From 504f26f8407b1ac2854c1bd5bb884b575b51e040 Mon Sep 17 00:00:00 2001 From: Lanly109 <1094916227@qq.com> Date: Sat, 25 May 2024 12:09:51 +0800 Subject: [PATCH 1/5] fea: more option in arena back --- autopcr/module/modules/tools.py | 36 ++++++++++++++++++++++++--------- server.py | 4 ++-- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/autopcr/module/modules/tools.py b/autopcr/module/modules/tools.py index b01b9458..6280e9ca 100644 --- a/autopcr/module/modules/tools.py +++ b/autopcr/module/modules/tools.py @@ -198,18 +198,34 @@ async def get_defend(self, client: pcrclient) -> Union[List[List[int]], List[int target_rank: int = self.target_rank() self_rank = await self.self_rank(client) - if target_rank: + if target_rank > 0: target = await self.get_rank_info(client, target_rank) target_info = (await client.get_profile(target.viewer_id)).user_info self._log(f"{target_info.user_name}({target.viewer_id})") self._log(f"{self_rank} -> {target_rank}({target_info.user_name})") defend = await self.get_defend_from_info(target) else: - history = await self.get_arena_history(client) - if not history: - raise SkipError("没有被刺记录") - history = history[0] - history_detail = await self.get_history_detail(history.log_id, client) + historys = await self.get_arena_history(client) + if not historys: + raise AbortError("没有被刺记录") + id = -target_rank + if id == 0: + for i, h in enumerate(historys): + h_detail = await self.get_history_detail(h.log_id, client) + if h_detail.is_challenge: + self._log(f"查找第{i + 1}条记录") + history = h + history_detail = h_detail + break + else: + raise AbortError("没有刺人记录") + else: + self._log(f"查找第{id}条记录") + if len(historys) < id: + raise AbortError(f"只有{len(historys)}条被刺记录") + history = historys[id - 1] + history_detail = await self.get_history_detail(history.log_id, client) + target = history.opponent_user target_info = (await client.get_profile(target.viewer_id)).user_info @@ -256,10 +272,10 @@ async def do_task(self, client: pcrclient): msg = [defend_str, "-------", attack_str] self._log('\n'.join(msg)) -@description('查询jjc回刺阵容,并自动设置进攻队伍,对手排名0则查找对战纪录第一条') +@description('查询jjc回刺阵容,并自动设置进攻队伍,对手排名=0则查找对战纪录第一条刺人的,<0则查找对战纪录,-1表示第一条,-2表示第二条,以此类推') @name('jjc回刺查询') @default(True) -@inttype("opponent_jjc_rank", "对手排名", 0, [i for i in range(0, 101)]) +@inttype("opponent_jjc_rank", "对手排名", -1, [i for i in range(-20, 101)]) class jjc_back(Arena): def target_rank(self) -> int: @@ -325,10 +341,10 @@ async def get_defend_from_histroy_detail(self, history_detail: VersusResultDetai async def get_attack_team(self, defen: List[int]) -> List[ArenaQueryResult]: return await ArenaQuery.get_attack(self.available_unit, defen) -@description('查询pjjc回刺阵容,并自动设置进攻队伍,对手排名0则查找对战纪录第一条') +@description('查询pjjc回刺阵容,并自动设置进攻队伍,对手排名=0则查找对战纪录第一条刺人的,<0则查找对战纪录,-1表示第一条,-2表示第二条,以此类推') @name('pjjc回刺查询') @default(True) -@inttype("opponent_pjjc_rank", "对手排名", 0, [i for i in range(0, 101)]) +@inttype("opponent_pjjc_rank", "对手排名", -1, [i for i in range(-20, 101)]) class pjjc_back(Arena): def target_rank(self) -> int: return self.get_config("opponent_pjjc_rank") diff --git a/server.py b/server.py index 5bdc00d8..b5f5a768 100644 --- a/server.py +++ b/server.py @@ -482,7 +482,7 @@ async def find_xinsui(botev: BotEvent): @register_tool("jjc回刺", "jjc_back") async def jjc_back(botev: BotEvent): msg = await botev.message() - opponent_jjc_rank = 0 + opponent_jjc_rank = -1 try: opponent_jjc_rank = int(msg[0]) del msg[0] @@ -496,7 +496,7 @@ async def jjc_back(botev: BotEvent): @register_tool("pjjc回刺", "pjjc_back") async def pjjc_back(botev: BotEvent): msg = await botev.message() - opponent_pjjc_rank = 0 + opponent_pjjc_rank = -1 try: opponent_pjjc_rank = int(msg[0]) del msg[0] From 81f0abf295656f68ebf5a0410c48d98c07bc92a4 Mon Sep 17 00:00:00 2001 From: Lanly109 <1094916227@qq.com> Date: Sat, 25 May 2024 12:10:30 +0800 Subject: [PATCH 2/5] fix: skill level up mana error --- autopcr/model/handlers.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/autopcr/model/handlers.py b/autopcr/model/handlers.py index 339caae3..c0da6f79 100644 --- a/autopcr/model/handlers.py +++ b/autopcr/model/handlers.py @@ -23,6 +23,11 @@ async def update(self, mgr: datamgr, request): class SkillLevelUpResponse(responses.SkillLevelUpResponse): async def update(self, mgr: datamgr, request): mgr.unit[self.unit_data.id] = self.unit_data + if self.user_gold: + mgr.gold = self.user_gold + if self.item_data: + for item in self.item_data: + mgr.update_inventory(item) @handles class UnitFreeLevelUpResponse(responses.UnitFreeLevelUpResponse): @@ -546,7 +551,8 @@ async def update(self, mgr: datamgr, request): class UnitCraftEquipResponse(responses.UnitCraftEquipResponse): async def update(self, mgr: datamgr, request): mgr.unit[self.unit_data.id] = self.unit_data - mgr.gold = self.user_gold + if self.user_gold: + mgr.gold = self.user_gold if self.item_data: for item in self.item_data: mgr.update_inventory(item) @@ -559,7 +565,8 @@ async def update(self, mgr: datamgr, request): class UnitMultiPromotionResponse(responses.UnitMultiPromotionResponse): async def update(self, mgr: datamgr, request): mgr.unit[self.unit_data.id] = self.unit_data - mgr.gold = self.user_gold + if self.user_gold: + mgr.gold = self.user_gold if self.item_data: for item in self.item_data: mgr.update_inventory(item) From 371a9b619ccaaf9ad4bca8cb3eaf7e8253ca34e3 Mon Sep 17 00:00:00 2001 From: Lanly109 <1094916227@qq.com> Date: Tue, 28 May 2024 20:23:41 +0800 Subject: [PATCH 3/5] fix: quest clear star < 3 show error --- autopcr/module/modules/autosweep.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/autopcr/module/modules/autosweep.py b/autopcr/module/modules/autosweep.py index bf70852d..01289cb4 100644 --- a/autopcr/module/modules/autosweep.py +++ b/autopcr/module/modules/autosweep.py @@ -101,10 +101,11 @@ async def do_task(self, client: pcrclient): if str(e).endswith("体力不足"): stop = True if not tmp and not self.log: self._log(str(e)) - elif str(e).endswith("未通关或不存在"): + elif str(e).endswith("未通关或不存在") or str(e).endswith("未三星"): self._log(f"{db.get_inventory_name_san(token)}: {str(e)}") else: - raise e + self._log(str(e)) + raise AbortError() break if stop: break @@ -119,7 +120,8 @@ async def do_task(self, client: pcrclient): if tmp: self._log(await client.serlize_reward(tmp)) if not self.log: - raise SkipError("需刷取的图均无次数") + self._log("需刷取的图均无次数") + raise SkipError() @conditional_execution("hard_sweep_run_time", ["h庆典"]) From 21fd78337373f6d615ba25e636a32cb39588a047 Mon Sep 17 00:00:00 2001 From: Lanly109 <1094916227@qq.com> Date: Wed, 29 May 2024 18:14:47 +0800 Subject: [PATCH 4/5] refactor: remove statsmodels --- autopcr/util/arena.py | 7 ++--- autopcr/util/statistics.py | 59 ++++++++++++++++++++++++++++++++++++++ requirements.txt | 2 -- 3 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 autopcr/util/statistics.py diff --git a/autopcr/util/arena.py b/autopcr/util/arena.py index 40ef82df..2d5b2503 100644 --- a/autopcr/util/arena.py +++ b/autopcr/util/arena.py @@ -151,7 +151,6 @@ async def get_approximate_attack(self, units: List[int], region: ArenaRegion) -> return result def attack_score(self, record: ArenaQueryResult) -> float: # the bigger, the better - confidence_level = 0.95 up_vote = record.up down_vote = record.down @@ -162,9 +161,9 @@ def attack_score(self, record: ArenaQueryResult) -> float: # the bigger, the bet def mean(x) -> float: return (x[0] + x[1]) / 2 - from statsmodels.stats.proportion import proportion_confint - positive_rate_ci = proportion_confint(up_vote, total_vote, alpha=1-confidence_level, method='wilson') - negative_rate_ci = proportion_confint(down_vote, total_vote, alpha=1-confidence_level, method='wilson') + from .statistics import wilson_score_interval as proportion_confint + positive_rate_ci = proportion_confint(up_vote, total_vote) + negative_rate_ci = proportion_confint(down_vote, total_vote) composite_score = mean(positive_rate_ci) - mean(negative_rate_ci) return composite_score diff --git a/autopcr/util/statistics.py b/autopcr/util/statistics.py new file mode 100644 index 00000000..bf19814d --- /dev/null +++ b/autopcr/util/statistics.py @@ -0,0 +1,59 @@ +import math + +def inverse_normal_cdf(p, tolerance=1e-5): + if p <= 0 or p >= 1: + raise ValueError("p must be between 0 and 1") + + if p < 0.5: + return -inverse_normal_cdf(1 - p, tolerance) + + low = 0.0 + high = 10.0 + mid = (low + high) / 2 + while high - low > tolerance: + mid = (low + high) / 2 + if norm_cdf(mid) < p: + low = mid + else: + high = mid + + return mid + +def norm_cdf(x): + return (1 + math.erf(x / math.sqrt(2))) / 2 + +def wilson_score_interval(successes, total, confidence_level=0.95): + """ + Calculate the Wilson score interval for a proportion. + + Parameters + ---------- + count : int + Number of successes. + nobs : int + Total number of trials or observations. + alpha : float, optional + Significance level (default is 0.05). The default alpha = 0.05 returns a 95% confidence interval. + + Returns + ------- + ci_low : float + Lower bound of the confidence interval. + ci_upp : float + Upper bound of the confidence interval. + """ + + if total == 0: + return (0, 0) + + z = inverse_normal_cdf(1 - (1 - confidence_level) / 2) + + phat = successes / total + denominator = 1 + (z**2 / total) + centre_adjusted_probability = phat + (z**2 / (2 * total)) + adjusted_standard_deviation = math.sqrt((phat * (1 - phat) + (z**2 / (4 * total))) / total) + + lower_bound = (centre_adjusted_probability - z * adjusted_standard_deviation) / denominator + upper_bound = (centre_adjusted_probability + z * adjusted_standard_deviation) / denominator + + return lower_bound, upper_bound diff --git a/requirements.txt b/requirements.txt index 10a510c7..aee2c3a2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,10 +10,8 @@ UnityPy~=1.10.1 SQLAlchemy~=2.0.17 Pillow~=9.5.0 Brotli~=1.0.9 -statsmodels~=0.14.0 quart_rate_limiter~=0.9.0 quart_auth~=0.9.1 quart-compress~=0.2.1 dataclasses_json~=0.6.4 -statsmodels~=0.14.0 PuLP~=2.8.0 From 6fda026b0d45e748e7cb09b0a588b9f580274d53 Mon Sep 17 00:00:00 2001 From: Lanly109 <1094916227@qq.com> Date: Thu, 30 May 2024 20:07:13 +0800 Subject: [PATCH 5/5] fix: daily task top error when lock --- autopcr/core/sessionmgr.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/autopcr/core/sessionmgr.py b/autopcr/core/sessionmgr.py index 407cf5f7..dba4c43a 100644 --- a/autopcr/core/sessionmgr.py +++ b/autopcr/core/sessionmgr.py @@ -117,12 +117,13 @@ async def _login(self, next: RequestHandler): req.gold_history = 0 req.is_first = 1 req.tips_id_list = [] - await next.request(req) + resp = await next.request(req) - req = DailyTaskTopRequest() - req.setting_alchemy_count = 1 - req.is_check_by_term_normal_gacha = 0 - await next.request(req) + if resp.quest_list and any(1 for quest in resp.quest_list if quest.quest_id == 11003005 and quest.result_type == eMissionStatusType.AlreadyReceive): # clear normal 3-5 and unlock daily task + req = DailyTaskTopRequest() + req.setting_alchemy_count = 1 + req.is_check_by_term_normal_gacha = 0 + await next.request(req) self._logged = True break