§
    j¿j€   ã                  óx   — d Z ddlmZ ddlZddlmZmZmZmZm	Z	 ddl
mZ ddlmZmZmZmZ  G d„ d¦  «        ZdS )	zÍ
FreeExile Social Service: High-Level Business Logic for Friendships & Presence.
Coordinates friendship lifecycles, mutual block verification, presence sync,
and Chat ChannelManager blacklist integration.
é    )ÚannotationsN)ÚAnyÚDictÚListÚOptionalÚSet)ÚSocialRepository)Ú	FriendDTOÚFriendshipStatusÚPresenceStatusÚSocialActionResponsec                  ó    — e Zd ZdZ	 	 d0d1d	„Zd2d
„Zd3d„Zd4d„Zd5d„Zd5d„Z	d3d„Z
d6d„Zd6d„Zd7d„Zd8d„Zd9d"„Z	 	 	 d:d;d*„Zd<d,„Zd<d-„Zd=d/„ZdS )>ÚSocialServicezQCore Social Engine managing friend relations, real-time presence, and blocklists.NÚ
repositoryúOptional[SocialRepository]Úchannel_managerúOptional[Any]ÚreturnÚNonec                ó‚   — |pt          ¦   «         | _        || _        i | _        i | _        |                      ¦   «          d S )N)r	   Ú_repositoryÚ_channel_managerÚfriend_requestsÚ_presence_cacheÚ_sync_friend_requests_from_db)Úselfr   r   s      ú5C:\Projects\FreeExile\server\social\social_service.pyÚ__init__zSocialService.__init__   sH   € ð
 &Ð;Õ)9Ñ);Ô);ˆÔØ /ˆÔØ46ˆÔØ57ˆÔØ×*Ò*Ñ,Ô,Ð,Ð,Ð,ó    c                ó   — dS )zJHydrates active pending friend requests from repository into memory cache.N© )r   s    r   r   z+SocialService._sync_friend_requests_from_db!   s   € àˆr   Ú	sender_idÚstrÚ	target_idÚboolc                ó8   — | j                              ||¦  «        S )zAReturns True if either user has blocked the other (mutual block).)r   Ú
is_blocked)r   r"   r$   s      r   r'   zSocialService.is_blocked%   s   € àÔ×*Ò*¨9°iÑ@Ô@Ð@r   Ú	player_idc                ó8   — | j                              ||¦  «        S )z;Returns True if players are mutual friends and not blocked.)r   Ú	is_friend)r   r(   r$   s      r   r*   zSocialService.is_friend)   s   € àÔ×)Ò)¨)°YÑ?Ô?Ð?r   c                óŒ  — | j                              ||¦  «         | j                             |t	          ¦   «         ¦  «                             |¦  «         | j                             |t	          ¦   «         ¦  «                             |¦  «         | j        �­	 t          |¦  «        }t          |¦  «        }| j                             ||d¬¦  «         dS # t          t          f$ r[ t          | j        d¦  «        rB| j        j                             |t	          ¦   «         ¦  «                             |¦  «         Y dS Y dS w xY wdS )zDBlocks target player, cleans friend state, and syncs chat blacklist.NT©r'   Ú_player_blacklists)r   Úblock_playerr   ÚgetÚsetÚdiscardr   ÚintÚset_blacklist_entryÚ
ValueErrorÚ	TypeErrorÚhasattrr-   Ú
setdefaultÚadd©r   r(   r$   ÚpidÚtids        r   r.   zSocialService.block_player-   sJ  € àÔ×%Ò% i°Ñ;Ô;Ð;ØÔ× Ò  ­C©E¬EÑ2Ô2×:Ò:¸9ÑEÔEÐEØÔ× Ò  ­C©E¬EÑ2Ô2×:Ò:¸9ÑEÔEÐEàÔ Ð,ðiÝ˜)‘n”n�Ý˜)‘n”n�ØÔ%×9Ò9¸#¸sÈtÐ9ÑTÔTÐTÐTÐTøÝ¥	Ð*ð ið ið iÝ˜4Ô0Ð2FÑGÔGð iØÔ)Ô<×GÒGÈ	ÕSVÑSXÔSXÑYÔY×]Ò]Ð^gÑhÔhÐhÐhÐhÐhðið ið iðiøøøð -Ð,s   Â;C ÃA%EÅ Ec                ó¤  — | j                              ||¦  «         | j        �­	 t          |¦  «        }t          |¦  «        }| j                             ||d¬¦  «         dS # t
          t          f$ r[ t          | j        d¦  «        rB| j        j         	                    |t          ¦   «         ¦  «                             |¦  «         Y dS Y dS w xY wdS )z2Unblocks target player and updates chat blacklist.NFr,   r-   )r   Úunblock_playerr   r2   r3   r4   r5   r6   r-   r/   r0   r1   r9   s        r   r=   zSocialService.unblock_player<   sñ   € àÔ×'Ò'¨	°9Ñ=Ô=Ð=ØÔ Ð,ðfÝ˜)‘n”n�Ý˜)‘n”n�ØÔ%×9Ò9¸#¸sÈuÐ9ÑUÔUÐUÐUÐUøÝ¥	Ð*ð fð fð fÝ˜4Ô0Ð2FÑGÔGð fØÔ)Ô<×@Ò@ÀÍCÉEÌEÑRÔR×ZÒZÐ[dÑeÔeÐeÐeÐeÐeðfð fð fðføøøð -Ð,s   ¤;A! Á!A%CÃCc                ó   — ||k    rdS |                       ||¦  «        s|                      ||¦  «        rdS | j                             ||¦  «        }|r:| j                             |t          ¦   «         ¦  «                             |¦  «         |S )z.Sends an outgoing friend request to target_id.F)r'   r*   r   Úadd_friend_requestr   r7   r0   r8   )r   r"   r$   Úoks       r   Úsend_friend_requestz!SocialService.send_friend_requestH   s“   € à˜	Ò!Ð!Ø�5Ø�?Š?˜9 iÑ0Ô0ð 	°D·N²NÀ9ÈiÑ4XÔ4Xð 	Ø�5àÔ×0Ò0°¸IÑFÔFˆØð 	MØÔ ×+Ò+¨Iµs±u´uÑ=Ô=×AÒAÀ)ÑLÔLÐLØˆ	r   c                óä   — |                       ||¦  «        rdS | j                             ||¦  «        }|r:| j                             |t          ¦   «         ¦  «                             |¦  «         |S )z@Accepts a pending friend request sent by sender_id to target_id.F)r'   r   Úaccept_friend_requestr   r/   r0   r1   ©r   r$   r"   r@   s       r   rC   z#SocialService.accept_friend_requestT   sn   € à�?Š?˜9 iÑ0Ô0ð 	Ø�5àÔ×3Ò3°I¸yÑIÔIˆØð 	JØÔ ×$Ò$ Yµ±´Ñ6Ô6×>Ò>¸yÑIÔIÐIØˆ	r   c                ó´   — | j                              ||¦  «        }|r:| j                             |t	          ¦   «         ¦  «                             |¦  «         |S )z3Declines an incoming friend request from sender_id.)r   Údecline_friend_requestr   r/   r0   r1   rD   s       r   rF   z$SocialService.decline_friend_request^   sS   € àÔ×4Ò4°YÀ	ÑJÔJˆØð 	JØÔ ×$Ò$ Yµ±´Ñ6Ô6×>Ò>¸yÑIÔIÐIØˆ	r   Ú	friend_idc                ó8   — | j                              ||¦  «        S )zRemoves an existing friendship.)r   Úremove_friend)r   r(   rG   s      r   rI   zSocialService.remove_friende   s   € àÔ×-Ò-¨i¸ÑCÔCÐCr   Úowner_idÚnotec                ó:   — | j                              |||¦  «        S )z3Sets a custom personal note for an accepted friend.)r   Úset_friend_note)r   rJ   rG   rK   s       r   rM   zSocialService.set_friend_notei   s   € àÔ×/Ò/°¸)ÀTÑJÔJÐJr   ÚnameÚlevelr2   Ú	is_onlineÚzone_idÚ	zone_namec                óœ   — |rt           j        nt           j        }t          |||d|||dt	          j        ¦   «         ¬¦	  «	        | j        |<   dS )z6Updates live presence metadata in the in-memory cache.ÚOutcastÚ ©	r(   Úcharacter_namerO   Úcharacter_classÚpresence_statusrQ   Úcurrent_map_nameÚfriend_noteÚlast_seen_timestampN)r   ÚONLINEÚOFFLINEr
   Útimer   )r   r(   rN   rO   rP   rQ   rR   Ústatuss           r   Úupdate_presencezSocialService.update_presencem   s\   € ð +4ÐO•Ô&Ð&½Ô9OˆÝ*3ØØØØ%Ø"ØØ&ØÝ $¤	¡¤ð
+
ñ 
+
ô 
+
ˆÔ˜YÑ'Ð'Ð'r   rU   rT   rY   r   rW   rX   rZ   c                óê   — | j                              |¦  «        }|p
|r|j        n|}	|p
|r|j        nd}
|p
|r|j        n|}t          ||	||
|||dt          j        ¦   «         ¬¦	  «	        | j         |<   dS )z=Canonical presence update adhering to dispatch specification.rT   rU   rV   N)r   r/   rW   rX   rZ   r
   r_   )r   r(   rO   rQ   rY   rW   rX   rZ   ÚexistingrN   ÚclsÚmap_names               r   Úupdate_player_presencez$SocialService.update_player_presence„   s£   € ð Ô'×+Ò+¨IÑ6Ô6ˆØÐU¸XÐ"T (Ô"9Ð"9È9ˆØÐV¸hÐ"U (Ô":Ð":ÈIˆØ#Ð[ÀXÐ(Z¨Ô(AÐ(AÐSZˆå*3ØØØØØ+ØØ%ØÝ $¤	¡¤ð
+
ñ 
+
ô 
+
ˆÔ˜YÑ'Ð'Ð'r   úList[FriendDTO]c                óÐ  — | j                              |¦  «        }g }|D ]Æ}|d         }|                      ||¦  «        rŒ!|                     dd¦  «        }| j                             |¦  «        }|r<t          ||j        |j        |j        |j	        |j
        |j        ||j        ¬¦	  «	        }n"t          ||ddt          j        dd|d	¬¦	  «	        }|                     |¦  «         ŒÇ|S )
zCRetrieves list of mutual friends with live presence info and notes.rG   r[   rU   rV   é   rT   ÚofflineÚOfflineg        )r   Úget_friendsr'   r/   r   r
   rW   rO   rX   rY   rQ   rZ   r\   r   r^   Úappend)	r   r(   Ú
db_friendsÚresultÚfÚfidrK   ÚcachedÚdtos	            r   Úget_friend_presencez!SocialService.get_friend_presence    s  € àÔ%×1Ò1°)Ñ<Ô<ˆ
Ø"$ˆàð 	ð 	ˆAØ�K”.ˆCØ�Š˜y¨#Ñ.Ô.ð Øà—5’5˜¨Ñ+Ô+ˆDØÔ)×-Ò-¨cÑ2Ô2ˆFØð ÝØ!Ø#)Ô#8Ø œ,Ø$*Ô$:Ø$*Ô$:Ø"œNØ%+Ô%<Ø $Ø(.Ô(Bð
ñ 
ô 
��õ  Ø!Ø#&ØØ$-Ý$2Ô$:Ø%Ø%.Ø $Ø(+ð
ñ 
ô 
�ð �MŠM˜#ÑÔÐÐØˆr   c                ó,   — |                       |¦  «        S )z*Convenience alias for get_friend_presence.)rt   ©r   r(   s     r   rl   zSocialService.get_friendsÇ   s   € à×'Ò'¨	Ñ2Ô2Ð2r   ú	List[str]c                ó6   — | j                              |¦  «        S )z2Retrieves list of player IDs blocked by player_id.)r   Úget_blocked_listrv   s     r   ry   zSocialService.get_blocked_listË   s   € àÔ×0Ò0°Ñ;Ô;Ð;r   )NN)r   r   r   r   r   r   )r   r   )r"   r#   r$   r#   r   r%   )r(   r#   r$   r#   r   r%   )r(   r#   r$   r#   r   r   )r$   r#   r"   r#   r   r%   )r(   r#   rG   r#   r   r%   )rJ   r#   rG   r#   rK   r#   r   r%   )r(   r#   rN   r#   rO   r2   rP   r%   rQ   r#   rR   r#   r   r   )rU   rT   rU   )r(   r#   rO   r2   rQ   r#   rY   r   rW   r#   rX   r#   rZ   r#   r   r   )r(   r#   r   rg   )r(   r#   r   rw   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r'   r*   r.   r=   rA   rC   rF   rI   rM   ra   rf   rt   rl   ry   r!   r   r   r   r      s�  € € € € € Ø[Ð[ð 26Ø)-ð	-ð 	-ð 	-ð 	-ð 	-ðð ð ð ðAð Að Að Að@ð @ð @ð @ðið ið ið ið
fð 
fð 
fð 
fð
ð 
ð 
ð 
ðð ð ð ðð ð ð ðDð Dð Dð DðKð Kð Kð Kð
ð 
ð 
ð 
ð: !Ø(Ø "ð
ð 
ð 
ð 
ð 
ð8%ð %ð %ð %ðN3ð 3ð 3ð 3ð<ð <ð <ð <ð <ð <r   r   )r}   Ú
__future__r   r_   Útypingr   r   r   r   r   Úserver.social.social_repositoryr	   Úserver.social.social_typesr
   r   r   r   r   r!   r   r   ú<module>r‚      sà   ððð ð #Ð "Ð "Ð "Ð "Ð "Ø €€€Ø 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1Ø <Ð <Ð <Ð <Ð <Ð <ðð ð ð ð ð ð ð ð ð ð ð ðz<ð z<ð z<ð z<ð z<ñ z<ô z<ð z<ð z<ð z<r   