o
    /Ioj                     @  s   U d Z ddlmZ ddlZddlZddlZddlZddlmZ eej	
ddZi Zded< d5ddZd6ddZd7ddZd8ddZd8ddZd9ddZd:ddZd;d d!Zd<d#d$Zd=d&d'Zd>d)d*Zd>d+d,Zd?d-d.Zd@d/d0ZdAd1d2ZdAd3d4ZdS )Bu  角色卡 JSON 文件存储层（bot 与 web 双进程共用）。

存储布局：
    server_data/trpg_chars/<user_id>/meta.json        # {"current_id": 3, "order": [1,2,3]}
    server_data/trpg_chars/<user_id>/<char_id>.json   # 单个角色完整数据（任意嵌套 dict）

所有写入均为原子写（tmp + os.replace），防止出现写了一半的文件；
同一进程内对同一用户加锁（threading.Lock），防止并发读改写丢失更新；
跨进程并发未加锁——写频率可忽略，属可接受风险。
    )annotationsN)PathBOTERO_TRPG_CHARS_ROOTzserver_data/trpg_charszdict[str, threading.Lock]_LOCKSreturnthreading.Lockc                 C  s   t t| t S N)r   
setdefaultstr	threadingLockuser_id r   1/home/dore/onebot/Bot_Ero/core/character_store.py	_lock_for   s   r   r
   c                 C  s&   t |  }| std| |S )Nu   非法用户 ID: )r
   stripisdigit
ValueError)r   uidr   r   r   _validate_user_id   s   r   intc              	   C  sJ   zt | }W n ttfy   td| d w |dkr#td| |S )Nu   非法角色 ID: r   )r   	TypeErrorr   )char_idcidr   r   r   _validate_char_id%   s   r   r   c                 C  s   t t|  S r   )
CHARS_ROOTr   r   r   r   r   	_user_dir/   s   r   c                 C  s   t | tt| S r   )r   r
   r   )r   r   r   r   r   
_char_path3   s   r   pathdictc              	   C  s>   |   si S z
t| jddW S  ttjfy   i  Y S w )Nutf-8encoding)is_filejsonloads	read_textOSErrorJSONDecodeError)r   r   r   r   
_read_json7   s   r*   dataNonec                 C  sZ   | j jddd | j d| j dt j d }|jtj|ddddd	 t	
||  d S )
NT)parentsexist_ok.z.tmpF   )ensure_asciiindentr!   r"   )parentmkdirnameuuiduuid4hex
write_textr%   dumpsosreplace)r   r+   tmpr   r   r   _write_json@   s    r>   c                 C  s,   t t| d }|dd  |dg  |S )N	meta.json
current_idorder)r*   r   r	   r   metar   r   r   
_load_metaG   s   rD   rC   c                 C  s   t t| d | d S )Nr?   )r>   r   rB   r   r   r   
_save_metaN   s   rE   
list[dict]c                 C  s6   t | }g }|d D ]}t| |}|r|| q
|S )NrA   )rD   get_charappend)r   rC   outr   r+   r   r   r   
list_charsR   s   

rJ   dict | Nonec                 C  sB   t | |}| sd S t|}|sd S t||d< t| |d< |S )Nidr   )r   r$   r*   r   r   )r   r   r   r+   r   r   r   rG   \   s   
rG   c                 C  s"   t | d }|d urt| |S d S )Nr@   )rD   rG   )r   r   r   r   r   get_currenth   s   rM   c                 C  s   t | }t|H t|}t|d ddd }t|| r)|d7 }t|| s|d | |d d u r:||d< tt||| t|| |W  d    S 1 sSw   Y  d S )NrA   r   )default   r@   )	r   r   rD   maxr   r$   rH   r>   rE   )r   r+   r   rC   next_idr   r   r   create_charm   s   

$rR   c                 C  s(   t | |}| stdt|| d S )N   角色不存在)r   r$   r   r>   )r   r   r+   r   r   r   r   update_char}   s   
rT   c                 C  s   t | }t|}t|L t||}| r|  t|}||d v r+|d | |d |krK|d r;|d d nd |d< |d d u rK|dd  t	|| W d    d S 1 s[w   Y  d S )NrA   r@   r   )
r   r   r   r   r$   unlinkrD   removepoprE   )r   r   r   r   r   rC   r   r   r   delete_char   s   

"rX   c                 C  sn   t | }t|}t|| stdt| t|}||d< t|| W d    d S 1 s0w   Y  d S )NrS   r@   )r   r   r   r$   r   r   rD   rE   )r   r   r   r   rC   r   r   r   set_current   s   
"rY   )r   r   )r   r
   )r   r   )r   r   )r   r   r   r    )r   r   r+   r    r   r,   )r   r    )rC   r    r   r,   )r   rF   )r   rK   )r+   r    r   r   )r+   r    r   r,   )r   r,   )__doc__
__future__r   r%   r;   r   r6   pathlibr   environgetr   r   __annotations__r   r   r   r   r   r*   r>   rD   rE   rJ   rG   rM   rR   rT   rX   rY   r   r   r   r   <module>   s2    







	








