Skip to content

Commit bed2705

Browse files
committed
refract: daily info
1 parent cb64695 commit bed2705

3 files changed

Lines changed: 153 additions & 218 deletions

File tree

autopcr/db/database.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ class database():
6969
sun_ball: ItemType = (eInventoryType.Item, 25014)
7070
dark_ball: ItemType = (eInventoryType.Item, 25015)
7171
ex_rainbow_enhance_pt: ItemType = (eInventoryType.Item, 26202)
72+
ex_rainbow_enhance_ball: ItemType = (eInventoryType.Item, 26203)
7273

7374
def __init__(self):
7475
self.dbmgr: Optional[dbmgr] = None

autopcr/module/modules/daily.py

Lines changed: 108 additions & 218 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
from decimal import ROUND_HALF_UP, Decimal
2-
from typing import List, Literal, Optional, Tuple
1+
from typing import List
32

43
from ...model.common import InventoryInfo
54
from ..modulebase import *
@@ -10,6 +9,7 @@
109
from ...db.database import db
1110
from ...model.enums import *
1211
from ...util.questutils import *
12+
from ...util.format_number import format_number
1313

1414
@description('仅开启时生效,氪体数将取满足条件的最大值,禅模式指不执行体力相关的功能,仅在清日常生效,单项执行将忽略。庆典包括其倍数,加速期间的所有倍数判断均x2')
1515
@name("全局配置")
@@ -285,235 +285,125 @@ async def do_task(self, client: pcrclient):
285285
'香水', '扫荡券', '加速券', '大师币', '连结币',
286286
)
287287

288-
_CN_SCALE: Tuple[Tuple[str, int], ...] = (('亿', 10 ** 8), ('万', 10 ** 4))
289-
_EN_SCALE: Tuple[Tuple[str, int], ...] = (('b', 10 ** 9), ('m', 10 ** 6), ('k', 10 ** 3))
290-
291-
292-
def _resolve_scale_unit(val: int, scale: Literal['k', 'm', 'b', '万', '亿']) -> Tuple[int, str]:
293-
ladder = _CN_SCALE if scale in ('万', '亿') else _EN_SCALE
294-
start = next(i for i, (s, _) in enumerate(ladder) if s == scale)
295-
av = abs(val)
296-
for i in range(start, len(ladder)):
297-
suf, div = ladder[i]
298-
if av >= div:
299-
return div, suf
300-
return 1, ''
301-
302-
303-
def _round_scaled_quotient(quotient: Decimal, decimals: int) -> str:
304-
if decimals <= 0:
305-
n = quotient.quantize(Decimal('1'), rounding=ROUND_HALF_UP)
306-
return str(int(n))
307-
step = Decimal('1').scaleb(-decimals)
308-
n = quotient.quantize(step, rounding=ROUND_HALF_UP)
309-
s = format(n, 'f')
310-
if '.' in s:
311-
s = s.rstrip('0').rstrip('.')
312-
return s
313-
314-
315-
def _group_int_string(int_part: str, use_grouping: bool) -> str:
316-
if not use_grouping or not int_part:
317-
return int_part
318-
sign = ''
319-
if int_part[0] == '-':
320-
sign = '-'
321-
int_part = int_part[1:]
322-
elif int_part[0] == '+':
323-
sign = '+'
324-
int_part = int_part[1:]
325-
rev = int_part[::-1]
326-
pieces = [rev[i:i + 3][::-1] for i in range(0, len(rev), 3)]
327-
return sign + ','.join(reversed(pieces))
328-
329-
330-
def _apply_numeric_separator(num_str: str, mode: Literal['auto', 'no', 'yes'], original_val: int) -> str:
331-
if mode == 'no':
332-
use = False
333-
elif mode == 'yes':
334-
use = True
335-
else:
336-
use = abs(original_val) >= 100_000
337-
if '.' in num_str:
338-
a, b = num_str.split('.', 1)
339-
return _group_int_string(a, use) + '.' + b
340-
return _group_int_string(num_str, use)
341-
342-
343-
def format_number(
344-
val: int,
345-
scale: Optional[Literal['k', 'm', 'b', '万', '亿']] = None,
346-
decimals: Optional[int] = None,
347-
separator: Literal['auto', 'no', 'yes'] = 'auto',
348-
) -> str:
349-
if scale is None:
350-
s = str(int(val))
351-
return _apply_numeric_separator(s, separator, val)
352-
dec = 2 if decimals is None else decimals
353-
div, suffix = _resolve_scale_unit(val, scale)
354-
if not suffix:
355-
s = str(int(val))
356-
return _apply_numeric_separator(s, separator, val)
357-
q = Decimal(val) / Decimal(div)
358-
coeff = _round_scaled_quotient(q, dec)
359-
return _apply_numeric_separator(coeff, separator, val) + suffix
360-
361-
362288
@description('展示基本信息,固定显示玩家名、体力、等级、钻石、母猪石、全角色战力,可自定义显示其他信息')
363289
@name('基本信息')
364290
@default(True)
365-
@multichoice("user_info_display", "显示信息",
291+
@multichoice(
292+
"user_info_display", "显示信息",
366293
['心碎', '星幽碎片', '炼金点数', '香水'],
367-
['玛娜', '心碎', '星球杯', '星幽碎片', '属性球', '大师碎片', '炼金点数', '香水', '扫荡券', '加速券', '大师币', '连结币'])
294+
['玛娜', '心碎', '星球杯', '星幽碎片', '属性球', '大师碎片', '炼金点数', '香水', '扫荡券', '加速券', '大师币', '连结币']
295+
)
368296
class user_info(Module):
369-
async def do_task(self, client: pcrclient):
370-
now = db.format_time(apiclient.datetime)
371-
display_items = set(self.get_config('user_info_display'))
297+
def _collect_optional_info(self, client: pcrclient, display_items: set[str]) -> dict[str, str]:
298+
data = client.data
299+
inv = data.get_inventory
372300

373-
# 固定信息
374-
name = client.data.user_name
375-
level = client.data.team_level
376-
stamina = client.data.stamina
377-
max_stamina = db.team_info[client.data.team_level].max_stamina
378-
jewel = client.data.jewel.free_jewel + client.data.jewel.jewel
379-
pig = client.data.get_inventory((eInventoryType.Item, 90005))
380-
tot_power = sum([client.data.get_unit_power(unit) for unit in client.data.unit])
381-
382-
# 可选信息
383-
optional_info = {}
384-
385-
if '玛娜' in display_items:
386-
mana = client.data.gold.gold_id_free + client.data.gold.gold_id_pay
387-
optional_info['玛娜'] = format_number(mana, scale='亿', decimals=1, separator='no')
388-
389-
if '心碎' in display_items:
390-
heart = client.data.get_inventory(db.heart)
391-
xinsui = client.data.get_inventory(db.xinsui)
301+
def fmt(n: int, **kwargs) -> str:
302+
return format_number(n, **kwargs)
303+
304+
def fmt_heart() -> str:
305+
heart = inv(db.heart)
306+
xinsui = inv(db.xinsui)
392307
if heart > 0:
393-
optional_info['心碎'] = f"{format_number(xinsui)}(大心 {format_number(heart)})"
394-
else:
395-
optional_info['心碎'] = format_number(xinsui)
396-
397-
if '星球杯' in display_items:
398-
star_cup = client.data.get_inventory(db.xingqiubei)
399-
optional_info['星球杯'] = format_number(star_cup)
400-
401-
if '星幽碎片' in display_items:
402-
xinyou = client.data.get_inventory(db.xinyou)
403-
optional_info['星幽碎片'] = format_number(xinyou)
404-
405-
if '属性球' in display_items:
406-
fire = client.data.get_inventory(db.fire_ball)
407-
water = client.data.get_inventory(db.water_ball)
408-
wind = client.data.get_inventory(db.wind_ball)
409-
sun = client.data.get_inventory(db.sun_ball)
410-
dark = client.data.get_inventory(db.dark_ball)
411-
optional_info['属性球'] = f"{format_number(fire)}/{format_number(water)}/{format_number(wind)}/{format_number(sun)}/{format_number(dark)}"
412-
413-
if '大师碎片' in display_items:
414-
master = client.data.get_inventory(db.master_fragment)
415-
master_f = client.data.get_inventory(db.master_ffragment)
308+
return f"{fmt(xinsui)}(大心 {fmt(heart)})"
309+
return fmt(xinsui)
310+
311+
def fmt_balls() -> str:
312+
items = [
313+
db.fire_ball,
314+
db.water_ball,
315+
db.wind_ball,
316+
db.sun_ball,
317+
db.dark_ball,
318+
]
319+
return '/'.join(fmt(inv(item)) for item in items)
320+
321+
def fmt_master_fragment() -> str:
322+
master = inv(db.master_fragment)
323+
master_f = inv(db.master_ffragment)
416324
if master_f > 0:
417-
optional_info['大师碎片'] = f"{master}(残片 {master_f})"
418-
else:
419-
optional_info['大师碎片'] = str(master)
420-
421-
if '炼金点数' in display_items:
422-
alces_pt = client.data.get_inventory(db.ex_rainbow_enhance_pt)
423-
optional_info['炼金点数'] = format_number(alces_pt, scale='万', decimals=0, separator='no')
424-
425-
if '香水' in display_items:
426-
perfume = client.data.get_inventory((eInventoryType.Item, 26203))
427-
optional_info['香水'] = str(perfume)
428-
429-
if '扫荡券' in display_items:
430-
sweep_ticket = client.data.get_inventory((eInventoryType.Item, 23001))
431-
optional_info['扫荡券'] = format_number(sweep_ticket)
432-
433-
if '加速券' in display_items:
434-
speed_ticket = client.data.get_inventory(db.travel_speed_up_paper)
435-
optional_info['加速券'] = str(speed_ticket)
436-
437-
if '大师币' in display_items:
438-
master_coin = client.data.get_inventory((eInventoryType.Item, 90008))
439-
optional_info['大师币'] = format_number(master_coin, scale='万', decimals=1, separator='no')
440-
441-
if '连结币' in display_items:
442-
link_coin = client.data.get_inventory((eInventoryType.Item, 99007))
443-
optional_info['连结币'] = str(link_coin)
444-
445-
# 注释掉的琐碎物品(方便后续启用)
446-
# if 'EX装备币' in display_items:
447-
# ex_weapon = client.data.get_inventory((eInventoryType.Item, 90009))
448-
# ex_armor = client.data.get_inventory((eInventoryType.Item, 90010))
449-
# ex_accessory = client.data.get_inventory((eInventoryType.Item, 90011))
450-
# fmt_coin = lambda n: format_number(n, scale='万', decimals=2, separator='no')
451-
# optional_info['EX装备币'] = f"{fmt_coin(ex_weapon)}/{fmt_coin(ex_armor)}/{fmt_coin(ex_accessory)}"
452-
453-
# if '商店币' in display_items:
454-
# dungeon_coin = client.data.get_inventory((eInventoryType.Item, 90002))
455-
# arena_coin = client.data.get_inventory((eInventoryType.Item, 90003))
456-
# grand_arena_coin = client.data.get_inventory((eInventoryType.Item, 90004))
457-
# clan_coin = client.data.get_inventory((eInventoryType.Item, 90006))
458-
# fmt_coin = lambda n: format_number(n, scale='万', decimals=2, separator='no')
459-
# optional_info['商店币'] = f"{fmt_coin(dungeon_coin)}/{fmt_coin(arena_coin)}/{fmt_coin(grand_arena_coin)}/{fmt_coin(clan_coin)}"
460-
461-
# if '原矿' in display_items:
462-
# # 原矿 ID 范围通常是 35000-35999,按ID倒序
463-
# ores = [(item_id, client.data.get_inventory((eInventoryType.Item, item_id)))
464-
# for item_id in range(35999, 34999, -1)
465-
# if client.data.get_inventory((eInventoryType.Item, item_id)) > 0]
466-
# if ores:
467-
# optional_info['原矿'] = '/'.join(str(cnt) for _, cnt in ores)
468-
469-
# if '经验药剂' in display_items:
470-
# # 经验药剂 ID: 20001-20004,按ID倒序
471-
# exp_potions = [client.data.get_inventory((eInventoryType.Item, item_id))
472-
# for item_id in range(20004, 20000, -1)]
473-
# optional_info['经验药剂'] = '/'.join(
474-
# format_number(cnt, scale='万', decimals=2, separator='auto') for cnt in exp_potions)
475-
476-
# if '精炼石' in display_items:
477-
# # 精炼石 ID: 22001-22006,按ID倒序
478-
# refine_stones = [client.data.get_inventory((eInventoryType.Item, item_id))
479-
# for item_id in range(22006, 22000, -1)]
480-
# optional_info['精炼石'] = '/'.join(
481-
# format_number(cnt, scale='万', decimals=2, separator='auto') for cnt in refine_stones)
482-
483-
# if '好感礼物' in display_items:
484-
# # 蛋糕类 ID: 50001-50003,按ID倒序
485-
# cakes = [client.data.get_inventory((eInventoryType.Item, item_id))
486-
# for item_id in range(50003, 50000, -1)]
487-
# optional_info['好感礼物'] = '/'.join(
488-
# format_number(cnt, scale='万', decimals=2, separator='auto') for cnt in cakes)
489-
490-
# 输出格式
491-
if stamina >= max_stamina:
492-
self._warn(f"体力爆了!")
493-
494-
# 第一行:固定信息
495-
self._log(f"{name} 体力{stamina}({max_stamina}) 等级{level} 钻石{format_number(jewel)}")
496-
497-
# 第二行:可选信息(前两项)+ 母猪石(顺序与配置候选项一致,避免 set 迭代无序)
498-
line2_items = []
325+
return f"{master}(残片 {master_f})"
326+
return str(master)
327+
328+
handlers = {
329+
'玛娜': lambda: fmt(
330+
data.gold.gold_id_free + data.gold.gold_id_pay,
331+
scale='亿',
332+
decimals=1,
333+
separator='no',
334+
),
335+
'心碎': fmt_heart,
336+
'星球杯': lambda: fmt(inv(db.xingqiubei)),
337+
'星幽碎片': lambda: fmt(inv(db.xinyou)),
338+
'母猪石': lambda: fmt(inv((eInventoryType.Item, 90005))),
339+
'属性球': fmt_balls,
340+
'大师碎片': fmt_master_fragment,
341+
'炼金点数': lambda: fmt(
342+
inv(db.ex_rainbow_enhance_pt),
343+
scale='万',
344+
decimals=0,
345+
separator='no',
346+
),
347+
'香水': lambda: str(inv(db.ex_rainbow_enhance_ball)),
348+
'扫荡券': lambda: fmt(inv((eInventoryType.Item, 23001))),
349+
'加速券': lambda: str(inv(db.travel_speed_up_paper)),
350+
'大师币': lambda: fmt(
351+
inv((eInventoryType.Item, 90008)),
352+
scale='万',
353+
decimals=1,
354+
separator='no',
355+
),
356+
'连结币': lambda: str(inv((eInventoryType.Item, 99007))),
357+
}
358+
359+
return {
360+
key: handlers[key]()
361+
for key in _USER_INFO_DISPLAY_ORDER
362+
if key in display_items and key in handlers
363+
}
364+
365+
def _log_optional_info(self, optional_info: dict[str, str], pig: int) -> None:
499366
keys = [k for k in _USER_INFO_DISPLAY_ORDER if k in optional_info]
500-
for i in range(min(2, len(keys))):
501-
line2_items.append(f"{keys[i]}{optional_info[keys[i]]}")
367+
368+
line2_items = [
369+
f"{key}{optional_info[key]}"
370+
for key in keys[:2]
371+
]
502372
line2_items.append(f"母猪石{format_number(pig)}")
503373
self._log(' '.join(line2_items))
504374

505-
# 第三行及以后:每行3个属性
506-
remaining_keys = keys[2:]
507-
for i in range(0, len(remaining_keys), 3):
508-
line_items = []
509-
for j in range(3):
510-
if i + j < len(remaining_keys):
511-
key = remaining_keys[i + j]
512-
line_items.append(f"{key}{optional_info[key]}")
375+
for i in range(2, len(keys), 3):
376+
line_items = [
377+
f"{key}{optional_info[key]}"
378+
for key in keys[i:i + 3]
379+
]
513380
self._log(' '.join(line_items))
514381

515-
# 最后一行:全角色战力
516-
self._log(f"全角色战力:{format_number(tot_power)}")
517-
self._log(f"已氪体数:{client.data.recover_stamina_exec_count}")
382+
async def do_task(self, client: pcrclient):
383+
data = client.data
384+
now = db.format_time(apiclient.datetime)
385+
display_items = set(self.get_config('user_info_display'))
386+
387+
name = data.user_name
388+
level = data.team_level
389+
stamina = data.stamina
390+
max_stamina = db.team_info[level].max_stamina
391+
jewel = data.jewel.free_jewel + data.jewel.jewel
392+
pig = data.get_inventory((eInventoryType.Item, 90005))
393+
total_power = sum(data.get_unit_power(unit) for unit in data.unit)
394+
395+
if stamina >= max_stamina:
396+
self._warn("体力爆了!")
397+
398+
optional_info = self._collect_optional_info(client, display_items)
399+
400+
self._log(
401+
f"{name} 体力{stamina}({max_stamina}) "
402+
f"等级{level} 钻石{format_number(jewel)}"
403+
)
404+
self._log_optional_info(optional_info, pig)
405+
406+
self._log(f"全角色战力:{format_number(total_power)}")
407+
self._log(f"已氪体数:{data.recover_stamina_exec_count}")
518408
self._log(f"清日常时间:{now}")
519409

0 commit comments

Comments
 (0)