o
    	cj+2                  	   @  s  U d Z ddlmZ ddlZddlmZmZ ddlmZmZ ddl	m
Z
mZ ddlmZmZ ddlmZ dd	lmZ dd
lmZmZ edgdf Zi aded< dZddddZdGddZdHddZdIdd ZdId!d"ZdId#d$ZdId%d&Z d'dd(ed)d*d+dd(ed,d*d-dd(ed.d*d/d0d(e d1d*d2Z!ded3< dJd5d6Z"dKd7d8Z#dLd:d;Z$dMd=d>Z%dNd@dAZ&eG dBdC dCeZ'eG dDdE dEe
Z(eG dFd de
Z)dS )Oua  
积分商店：数据库 shop_stock 为唯一货架；内存 SHOP_ITEMS 由库表同步。

每周一 8:00 清空后：随机上架 4 个称号（库存各 2，售价按稀有度 common=3 / rare=6 / legendary=10），
并合并固定功能商品（FIXED_FUNCTION_ITEMS）。

功能向效果存于 shop_user_buffs 表，由打卡/抽卡插件消费。
    )annotationsN)datetime	timedelta)AnyCallable)PluginTimedHeartbeatPlugin)attext)logger)register_plugin)
TITLE_DEFSget_title_defRedeemShopPluginzdict[str, dict[str, Any]]
SHOP_ITEMS         
   commonrare	legendarytdefdict[str, Any] | Nonereturnintc                 C  s<   | pi  dpd}t|tr|  }tt |td S )Nrarityr   )get
isinstancestrstriplowerr   TITLE_PRICE_BY_RARITY)r   r r%   0/home/dore/onebot/Bot_Ero/plugins/redeem_shop.pytitle_price_from_def#   s   
r'   plugin'RedeemShopPlugin'title_idNonec                 C  sL   | j j}|d u rtd| j||rtd| jj||dds$tdd S )N   无法识别用户u   你已拥有该称号Fcommitu   称号发放失败)	bot_eventuser_idRuntimeError	dbmanager	has_titleunlock_title)r(   r*   uidr%   r%   r&   _grant_title*   s   r6   c                 C  sF   | j j}|d u rtdt tdd d}| jj||dd d S )Nr,   r   )days%Y-%m-%dFr-   )	r/   r0   r1   r   nowr   strftimer2   set_extra_draw_pack_until)r(   r5   untilr%   r%   r&   _grant_extra_draw_pack4   s
   r=   c                 C  .   | j j}|d u rtd| jj|ddd d S Nr,   r   Fr-   )r/   r0   r1   r2   add_shop_checkin_luckr(   r5   r%   r%   r&   _grant_checkin_boost=      rB   c                 C  r>   r?   )r/   r0   r1   r2   add_shop_lottery_waiverrA   r%   r%   r&   _grant_lottery_waiverD   rC   rE   c                 C  s<   | j j}|d u rtdt d}| jj||dd d S )Nr,   r8   Fr-   )r/   r0   r1   r   r9   r:   r2   !clear_lottery_draw_count_for_date)r(   r5   todayr%   r%   r&   _grant_lottery_refreshK   s
   rH   uB   额外抽卡补充包（7 天内每日 +2 次额外抽卡额度）uT   兑换成功，已获得额外抽卡补充（7 日有效）。剩余积分 {rest}。)descriptioncoststockapplysuccess_tipuF   打卡增强（接下来 10 次打卡，每次 10% 概率 +1 积分）uC   兑换成功，打卡增强次数已入账。剩余积分 {rest}。uK   抽奖增强（接下来 10 次付费抽奖，每次 30% 不消耗积分）uC   兑换成功，抽奖增强次数已入账。剩余积分 {rest}。u6   抽奖刷新（立刻清空今日已用抽卡次数）   uC   兑换成功，今日抽卡次数已重置。剩余积分 {rest}。)fn_extra_draw_packfn_checkin_boostfn_lottery_boostfn_lottery_refreshFIXED_FUNCTION_ITEMSdict[str, int]c                  C  s*   i } t  D ]\}}t|d | |< q| S )NrL   )rT   itemsr   )outpidmetar%   r%   r&   _fixed_shop_stock_mappings   s   rZ   c              
   C  s0  |   }t  |D ]\}}t|}|drtzt|ddd }W n ttfy.   Y q
w t	|p4i }|
dd}|
dpAd}t|trM|  }dd	d
d
|t|}t|}	d| d| d|	t||fdddt|< q
|tv rt| }
t|
d t|
d t||
d |

ddt|< q
dS )uY   根据 shop_stock 重建内存中的 SHOP_ITEMS（进程重启后与数据库一致）。title__rO   name?r   r   u   普通u   稀有u   传奇r   u   解锁称号「u   」（u   ）c                 S  s
   t | |S N)r6   )pttr%   r%   r&   <lambda>   s   
 z2refresh_shop_items_from_database.<locals>.<lambda>)rJ   rK   initial_stockrM   rJ   rK   rM   rN   )rJ   rK   rc   rM   rN   N)get_all_shop_stockr   clearr    
startswithr   split
ValueError
IndexErrorr   r   r   r!   r"   r'   rT   )dbrowsrX   _stocktidr   nmr   rcrK   rY   r%   r%   r&    refresh_shop_items_from_databasez   sB   






rp   	list[int]c                 C  sh   t t }tt }g }|r)tdt|}tj||d}|D ]	}t	|d| < q| 
| t|  |S )uK   清空商店：随机 4 个称号 + 固定功能商品，并同步内存。   )kr[   )listr   keysdictrZ   minlenrandomsampleWEEKLY_TITLE_STOCKreplace_entire_shop_shelfrp   )rj   all_idsmappingpickedrs   rm   r%   r%   r&   weekly_refresh_shop_shelf   s   

r   	list[str]c                 C  s   t |  g }tt D ]@}t| }|d }|d }| |}|du r&d}n|dkr-d}nt|}|d| d|  |d	| d
|  |d q|S )uB   返回本周货架每条商品的文案行（含空行分隔）。rK   rJ   Nu	   未上架rI   u   不限[z] u       售价 u    积分｜剩余  )rp   sortedr   ru   get_shop_stockr    append)rj   linesrX   rY   rK   descstock_nrL   r%   r%   r&   format_shop_shelf_lines   s    
r   r    c                 C  s8   t | }g d}|r|| n|d d| S )u-   每周刷新后发到群里的公告文案。)u   积分商店已刷新~ud   发送 /商店 查看完整列表，或 /商店 <商品id> 兑换。（方括号里的是商品id）r   u   —— 本周货架 ——u   本周暂无上架商品。
)r   extendr   joinrstrip)rj   shelfr   r%   r%   r&   format_shop_weekly_announcement   s   
r   c                   @  s.   e Zd ZdZdZdZdgZdd Zdd Zd	S )
ShopWeeklyRotationPluginshop_weekly_rotationuB   每周一 8:00 刷新积分商店并在群内公告本周货架。z08:00rO   c                 C  s
   |  |S r_   )should_run_on_heartbeatself
event_typer%   r%   r&   match   s   
zShopWeeklyRotationPlugin.matchc              
   C  sl   zt | j}tdt|| | jtt| j W d S  t	y5 } zt
d| W Y d }~d S d }~ww )Nu9   积分商店已刷新（本周随机称号 %s 个）：%su   积分商店周刷新失败: %s)r   r2   r   inforx   apisend_msgr
   r   	Exception	exception)r   r   er%   r%   r&   handle   s   
zShopWeeklyRotationPlugin.handleN)	__name__
__module____qualname__r]   rJ   RUN_ATRUN_WEEKDAYSr   r   r%   r%   r%   r&   r      s    r   c                   @  s$   e Zd ZdZdZdd Zdd ZdS )ShopManualRefreshPluginshop_manual_refreshu3   管理员指令：立刻刷新积分商店货架。c                 C  s   |dko|   o| dS )Nmessageu   /刷新商店)
admin_useron_full_matchr   r%   r%   r&   r      s
   zShopManualRefreshPlugin.matchc              
   C  s   | j jd u rd S | j j}z!t| j}td| | jt|t	dt
| d|  W d S  tyT } ztd| | jt|t	d|  W Y d }~d S d }~ww )Nu;   管理员手动刷新积分商店（随机称号 id）：%su1   商店已刷新。本周随机上架称号（共 u
    个）：u   管理员刷新商店失败: %su   刷新失败：)r/   r0   r   r2   r   r   r   r   r	   r
   rx   r   r   )r   r5   r   r   r%   r%   r&   r      s   

*zShopManualRefreshPlugin.handleN)r   r   r   r]   rJ   r   r   r%   r%   r%   r&   r      s
    r   c                   @  s.   e Zd ZdZdZdd ZdddZd	d
 ZdS )r   redeem_shopu*   使用积分兑换商店称号或权益。c                 C  s   |dko|  dS )Nr   u   /商店)
on_commandr   r%   r%   r&   r     s   zRedeemShopPlugin.matchr   r    c                 C  sd   g d}t | j}|s!|d |d |d d| S || |d d| S )N)u   —— 积分商店 ——u   用法：/商店 <商品id>r   u6   本周暂无上架商品（每周一 8:00 刷新）。r   u#   发送 /商店 <商品id> 兑换。r   )r   r2   r   r   r   r   )r   r   r   r%   r%   r&   _format_list  s   





zRedeemShopPlugin._format_listc              
     s  j jd u rd S j j}dd tdg pg D }tj t|dk r1jt	 g d S |d 
 }|tvrLjt|td| d d S t| }t|d }|d	   d u rkjt|td
 d S j|}||k rjt|td| d| d d S |}|drzt|ddd }W n ttfy   d }Y nw |d urj||rjt|td d S d fdd}	j||||	\}
}|
sjt|td|  d S j|}|d}t|tr|
 rz|j|d}W nP tttfy   |}Y nBw |drPz"t|ddd }t|p,i }|dd}d| d| d}W n ttfyO   d| d}Y nw d| d}jt|t| d S )Nc                 S  s   g | ]}|r|qS r%   r%   ).0r`   r%   r%   r&   
<listcomp>  s    z+RedeemShopPlugin.handle.<locals>.<listcomp>argsr   rO   u   未知商品 id：u!   ，发送 /商店 查看列表。rK   rM   u!   该商品未配置发放逻辑。u   积分不足：需要 u
   ，当前 u   。r[   r\   u-   你已拥有该称号，无需重复兑换。r   r+   c                     s     d S r_   r%   r%   apply_fnr   r%   r&   grantD  s   z&RedeemShopPlugin.handle.<locals>.grantu   兑换失败：rN   )restr]   r^   u   兑换成功，称号「u   」已解锁。剩余积分 u   兑换成功，剩余积分 r   r+   )r/   r0   getattrrp   r2   rx   r   send_forward_msgr
   r   r!   r   r   r	   r   get_user_pointrf   rg   rh   ri   r3   redeem_shop_itemr   r   r    formatKeyErrorr   )r   r0   r   
product_idrY   rK   pointsr5   rm   r   okerrr   tipmsgr   r]   r%   r   r&   r     sv   


zRedeemShopPlugin.handleNr   r    )r   r   r   r]   rJ   r   r   r   r%   r%   r%   r&   r     s    
)r   r   r   r   )r(   r)   r*   r   r   r+   )r(   r)   r   r+   )r   rU   r   )r   rq   )r   r   r   )*__doc__
__future__r   ry   r   r   typingr   r   	core.baser   r   core.cqr	   r
   core.loggerr   
core.utilsr   plugins.titler   r   	ShopApplyr   __annotations__r{   r#   r'   r6   r=   rB   rE   rH   rT   rZ   rp   r   r   r   r   r   r   r%   r%   r%   r&   <module>   sv    	




	



 

%

