
    :Xi                        U d dl mZmZmZmZmZmZ d dlmZ d dl	m
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Zd dlZd dlZd dlZd dlmZmZmZ d dlZd dlZd dlZd dlmZmZm Z   ej!        ej"                    ej#        e$          Z% ed	
          Z&e&'                    edgddgdg           ej(        )                    ej(        *                    e+                    Z,ej(        )                    e,          Z-ej(        .                    e-d          Z/ej(        .                    e/d          Z0ej(        .                    e/d          Z1ej(        .                    e/d          Z2ej(        .                    e/d          Z3d Z4d Z5d Z6 e4              e6e0          a7ee8d<    e6e1          a9ee8d<    e6e3          a:ee8d<   i a;ee8d<    G d d          Z< e6e2          Z=ee8d<   e=>                                D ]"\  Z?Z@e<A                    e@          tv          e?<   #d ZBejC        ZCejD        ZDd ZEddd eFd!eGfd"ZH G d# d$e          ZI G d% d&e          ZJ G d' d(e          ZK G d) d*e          ZL G d+ d,e          ZM G d- d.e          ZNd/eOd0eOfd1ZPd0eOfd2ZQg d3ZRd4d5gZSe&T                    d6          d7             ZUe&V                    d8           ed9          fd:eNd;eOfd<            ZWd;eOd0eeO         fd=ZXdmd;eOd0eOfd>ZYe&V                    d?          d@eIfdA            ZZe&V                    dB          d@eJfdC            Z[e&T                    dD          d;eOfdE            Z\e&V                    dF           ed9dGH          fd@eKd;eOfdI            Z]e&T                    dJ          dK             Z^e&V                    dL           ed9dGH          fdMeOd@eLd;eOfdN            Z_e&V                    dO           ed9dGH          fd;eOfdP            Z`e&T                    dQ          dR             Zae&T                    dS          dT             Zbe&V                    dU          d@eMfdV            Zce&V                    dW          d@eMfdX            Zde&e                    dY           ed9          fdZedMeOd;eOfd[            Zfd\ Zge&h                    d]          d^             Zie&h                    d_          d`             Zje&T                    da          db             Zkej(        .                    e-dc          Zle&m                    dd e
elde          dfg           e$dhk    r ejn        e&didjdkl           dS dS )n    )FastAPI	WebSocketWebSocketDisconnectHTTPExceptionDependsQuery)CORSMiddleware)StaticFiles)	BaseModelN)OptionalDictList)_dist_point_to_segmentcircle_aabb_overlapdistance)levelzBattle Royale Game API)title*T)allow_originsallow_credentialsallow_methodsallow_headersdatazusers_db.jsonzsessions.jsonz
rooms.jsonzuser_rooms.jsonc                      t           j                            t                    st          j        t                     d S d S N)ospathexistsDATA_DIRmakedirs     backend/server.pyensure_data_dirr$   1   s8    7>>(## 
H r"   c                     t          | dd          5 }t          j        ||dd           d d d            d S # 1 swxY w Y   d S )Nwutf-8encodingF   )ensure_asciiindent)openjsondump)r   r   fs      r#   	save_jsonr1   6   s    	dC'	*	*	* 9a	$a88889 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9s   9= =c                     t           j                            |           r>t          | dd          5 }t	          j        |          cd d d            S # 1 swxY w Y   i S )Nrr'   r(   )r   r   r   r-   r.   load)r   r0   s     r#   	load_jsonr5   ;   s    	w~~d  $g... 	 !9Q<<	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 Is   AAAusers_dbsessions
user_roomsroomsc                   n    e Zd Z	 	 ddededededef
dZd	ed
efdZd	efdZd Z	d Z
ed             ZdS )Room   Nroom_idnamecreatormax_playerspasswordc                     || _         || _        || _        || _        || _        i | _        g | _        i | _        d| _        t          j	                    | _
        g | _        i | _        g | _        g | _        g | _        d S NF)r=   r>   r?   r@   rA   playersbulletsconnectionsgame_runningtime
created_atwallsgraffitismokesturretscross_bombs)selfr=   r>   r?   r@   rA   s         r#   __init__zRoom.__init__L   s}     	& !)++
r"   username	websocketc                 <   t          | j                  | j        k    rdS t          j        dt
          dz
            t          j        dt          dz
            ddt          j        t          j	                    ddt                              |i                               di                               dg d          d d         t                              |i                               di                               dg           d	
| j        |<   || j        |<   d
S )NFd   r   loadoutweapon_slotssingleshotgun	crossbombwall   perks)
xydxdyhplast_hitkillsdeathsrV   r]   T)lenrD   r@   randomrandint	MAP_WIDTH
MAP_HEIGHTcfgPLAYER_MAX_HPrH   r6   getrF   )rO   rQ   rR   s      r#   
add_playerzRoom.add_playerc   s!   t| 0005 Y_55Z#%566#	$LL266::9bIIMMn  _I  _I  _I  J  J  KM  LM  KM  N\\(B//33IrBBFFwPRSS"
 "
X &/"tr"   c                     | j                             |d            | j                            |d            | j         s| j        rd| _        d S d S d S rC   )rD   poprF   rG   )rO   rQ   s     r#   remove_playerzRoom.remove_playery   si    4(((Xt,,,| 	& 1 	& %D	& 	& 	& 	&r"   c                    i }| j                                         D ]e\  }}|                                }|d         dk    rdnd|d<   t          dt	          |                    dd                              |d<   |||<   f|| j        | j        | j        | j	        | j
        | j        | j        t          | j                   | j        ddS )Nrb   r   deadalivestatus)r>   player_countr@   )rD   rE   rJ   rK   rL   rM   rN   	room_info)rD   itemscopymaxintrm   rE   rJ   rK   rL   rM   rN   r>   rf   r@   )rO   state_playersrQ   playerplayer_copys        r#   	get_statezRoom.get_state   s     $ 2 2 4 4 	2 	2Hf ++--K.9$.?1.D.DFF'K! #As;??4+C+C'D'D E EK&1M(##$|Zk|+	 #DL 1 1#/ 
 
 	
r"   c           
      t    | j         | j        | j        | j        | j        | j        | j        | j        | j        d	S )N	r=   r>   r?   r@   rA   rD   rE   rG   rI   r   )rO   s    r#   to_dictzRoom.to_dict   s@    |I|+|| -/

 

 
	
r"   c           	         t          | d         | d         | d         |                     dd          |                     d                    }|                     di           |_        |                     d	g           |_        |                     d
d          |_        |                     dt          j                              |_        |S )Nr=   r>   r?   r@   r<   rA   r=   r>   r?   r@   rA   rD   rE   rG   FrI   )r;   rm   rD   rE   rG   rH   rI   )drooms     r#   	from_dictzRoom.from_dict   s    iL6iLmQ//UU:&&
 
 
 uuY++uuY++EE.%88%%dikk::r"   )r<   N)__name__
__module____qualname__strr{   rP   r   rn   rq   r   r   staticmethodr   r!   r"   r#   r;   r;   K   s          !    	
     .3 9    ,&c & & & &
 
 
,
 
 
   \  r"   r;   	rooms_rawc                     t          t          t                     t          t          t                     t          t
          t                     d t                                          D             } t          t          |            d S )Nc                 >    i | ]\  }}||                                 S r!   )r   ).0r=   r   s      r#   
<dictcomp>z!save_all_data.<locals>.<dictcomp>   s&    MMMmgt'4<<>>MMMr"   )
r1   
USERS_FILEr6   SESSIONS_FILEr7   USER_ROOMS_FILEr8   r9   rx   
ROOMS_FILE)
rooms_dicts    r#   save_all_datar      sc    j(###mX&&&oz***MMu{{}}MMMJj*%%%%%r"   c                    |                      dd          }|                      dd          }|                      dd          }|                      dd          }||z  ||z  z   dz  pd}||z  }||z  }	||z
  }
||z
  }|
|z  ||	z  z   }|
 |	z  ||z  z   }t          j        }t          j        }t	          |          |k    rt	          |          |k    rdS t	          |          |k    rt	          |          |k    rdS d	S )
Nr^           r_   dirx      ?diry      ?TF)rm   rk   CROSS_BOMB_ARM_LENGTHCROSS_BOMB_ARM_HALF_WIDTHabs)bombr^   r_   bxbyr   r   normuxuyvxvyprojperplength
half_widths                   r#   point_in_cross_arear      s   	#s		B	#s		B88FC  D88FC  D4K$+%#-4D	B	B	
RB	
RB7R"WD38b2gD&F.J
4yyFs4yyJ66t
4yyFs4yyJ66t5r"   r   r   now_tsc           
         |                     d          }t          j        }| j                                        D ]\  }}|                     dd          dk    r!|r||k    r*t          ||                     dd          |                     dd                    rt          d|                     dd          |z
            |d<   ||d<   |d         dk    rdd|d<   |                     dd          dz   |d<   |rA||k    r;|| j        v r2| j        |                              d	d          dz   | j        |         d	<   | j        D ]}|                     dd          dk    rt          ||                     dd          |                     dd                    r*t          d|                     dd          |z
            |d<   g }t          | j	                  D ]~\  }	}
t          |
                     d
g                     D ]U\  }}t          ||                     dd          |                     dd                    r|
                    |	|f           V|rddlm}  |t                    }|D ] \  }	}||	         
                    |           !|                                D ]\  }	}d|	cxk    rt          | j	                  k     rpn '| j	        |	         }
t          |d          D ]N}d|cxk    r't          |
                     d
g                     k     rn 3|
d
                             |           Od | j	        D             | _	        d S d S )Nownerrb   r   r^   r_   rc   re      rd   blocksdefaultdictTreversec                 <    g | ]}|                     d           |S r   rm   r   r&   s     r#   
<listcomp>z+apply_cross_bomb_damage.<locals>.<listcomp>  s'    ???AquuX?a???r"   )rm   rk   CROSS_BOMB_DAMAGErD   rx   r   rz   rM   	enumeraterJ   appendcollectionsr   listrf   sortedrp   )r   r   r   r   damageunamer}   turret
remove_mapw_idxr[   b_idxblockr   groupedb_idxss                   r#   apply_cross_bomb_damager      s   HHWE"F++-- [ [v::dA!## 	Ue^^tVZZQ%7%7C9K9KLL 	[q&**T1"5"5">??F4L!'F:d|q   t#)::h#:#:Q#>x  [Ue^^0E0E37<3F3J3J7TU3V3VYZ3ZDL'0, @ @::dA!##tVZZQ%7%7C9K9KLL 	@q&**T1"5"5">??F4LJ ,, 2 2t%dhhx&<&<== 	2 	2LE5"43):):EIIc1<M<MNN 2!!5%.111	2  @+++++++d##& 	) 	)LE5EN!!%(((($]]__ 	2 	2ME6E++++C
OO+++++z%(#FD999 2 2EE????C2(>(>$?$??????X**5111?????


@ @r"   c                   .    e Zd ZU eed<   eed<   eed<   dS )RegisterRequestrQ   rA   emailNr   r   r   r   __annotations__r!   r"   r#   r   r     s+         MMMMMMJJJJJr"   r   c                   $    e Zd ZU eed<   eed<   dS )LoginRequestrQ   rA   Nr   r!   r"   r#   r   r     s"         MMMMMMMMr"   r   c                   B    e Zd ZU eed<   dZeed<   dZee         ed<   dS )CreateRoomRequest	room_namer<   r@   NrA   )	r   r   r   r   r   r@   r{   rA   r   r!   r"   r#   r   r     s?         NNNK"Hhsm"""""r"   r   c                   D    e Zd ZU dZee         ed<   dZee         ed<   dS )JoinRoomRequestNr=   rA   )r   r   r   r=   r   r   r   rA   r!   r"   r#   r   r     s:         !GXc]!!!"Hhsm"""""r"   r   c                       e Zd ZU eed<   dS )AdminRequestadmin_passwordNr   r!   r"   r#   r   r     s         r"   r   c                   <    e Zd ZU ee         ed<   ee         ed<   dS )UpdateLoadoutRequestrV   r]   N)r   r   r   r   r   r   r!   r"   r#   r   r     s2         s)9r"   r   rA   returnc                 r    t          j        |                                                                           S r   )hashlibsha256encode	hexdigest)rA   s    r#   hash_passwordr   $  s(    >(//++,,66888r"   c                  B    t          t          j                              S r   )r   uuiduuid4r!   r"   r#   generate_tokenr   (  s    tz||r"   )rX   rY   missiler[   smoker   iaidorZ   regen_boostregen_when_deadz/api/loadout/metac                  &   K   dt           t          dS )NT)successweaponsr]   )AVAILABLE_WEAPONSAVAILABLE_PERKSr!   r"   r#   get_loadout_metar   6  s      (9OTTTr"   z/api/loadout/update.reqsession_tokenc                    K   t          |           d {V }t          | j                  dk    rdddS d | j        D             d d         }t          |          dk     r(|                    d           t          |          dk     (d | j        D             }t
                              |i                               di            ||d	t
          |         d<   t                       d
t
          |         d         dS )Nr\   Fu   武器槽数量必须为4r   errorc                 $    g | ]}|t           v |S r!   )r   r   s     r#   r   z"update_loadout.<locals>.<listcomp>A  s#    JJJ!18I3I3IA3I3I3Ir"   rX   c                 $    g | ]}|t           v |S r!   )r   )r   ps     r#   r   z"update_loadout.<locals>.<listcomp>D  s"    ???!*>*>!*>*>*>r"   rU   rV   r]   T)r   rU   )verify_sessionrf   rV   r   r]   r6   
setdefaultr   )r   r   rQ   safe_weapons
safe_perkss        r#   update_loadoutr   ;  s     #M22222222H
3!! +FGGGJJs/JJJ2A2NL
l

a

H%%% l

a

??SY???J"%%00B???5AJ$W$WHXy!OOO(:9(EFFFr"   c                     t                               |           }|r(t          j                    |d         z
  dk     r|d         S d S )NrI   iQ rQ   )r7   rm   rH   )r   sessions     r#   get_user_by_sessionr  K  sE    ll=))G #49;;!66>>z""4r"   c                 t   K   | st          dd          t          |           }|st          dd          |S )Ni  zSession token requiredstatus_codedetailInvalid or expired session)r   r  )r   rQ   s     r#   r   r   R  s\       N4LMMMM"=11H 1/1 1 1 	1 Or"   z/api/registerrequestc                   K   | j         t          v rdddS t          | j                   dk    rdddS t          | j                  | j        ddddddg dg d	t          j                    d
t          | j         <   t                      }| j         t          j                    dt          |<   t          
                    d| j                     t                       d|| j         t          | j                  d         dS )NFu   用户名已存在r      u   用户名过长r   games_playedwinsrd   re   total_damagerW   r   )password_hashr   statsrU   rI   rQ   rI   zUser registered: Tr  )r   r   rQ   r  )rQ   r6   rf   r   rA   r   rH   r   r7   loggerinfor   )r	  r   s     r#   registerr  ]  s-     8## +?@@@
7r!! +<===&w'788
 
 GFF
 
 ikk" "HW  #$$M$ikk H] KK6G$466777OOO&$'*+G4	  r"   z
/api/loginc           
        K   t                               | j                  }|r|d         t          | j                  k    rdddS t                      }| j        t          j                    dt          |<   t          	                    d| j                    t                       d|| j        |d         |                    d	g d
g d          dS )Nr  Fu   用户名或密码错误r   r  zUser logged in: Tr  rU   rX   rY   r   r[   r   )r   r   rQ   r  rU   )r6   rm   rQ   r   rA   r   rH   r7   r  r  r   )r	  userr   s      r#   loginr    s      <<())D G4(M':J,K,KKK +EFFF"$$M$ikk H] KK57#355666OOO&$g88I8`8`8`km'n'noo  r"   z/api/user/{session_token}c                   K   	 t          |           }|sdddS t                              |          }|sdddS d||d         |d         |                    dg d	g d
          t                              |          |                    dt	          j                              |                    dt	          j                              dS # t
          $ r,}t                              d|            dddcY d }~S d }~ww xY w)NFr  r   zUser not foundTr   r  rU   r  r   rI   
last_login)r   rQ   r   r  rU   current_roomrI   r  zGet user info error: zServer error)r  r6   rm   r8   rH   	Exceptionr  r   )r   rQ   r  es       r#   get_user_info_by_pathr    s3     ;&}55 	M$/KLLL||H%% 	A$/?@@@ ']']xx	<a<a<aln+o+opp&NN844((<==((<==	
 	
 		
  ; ; ;0Q00111 >::::::::;s(   C  C BC 
D!C>8D>Dz/api/rooms/createu   用户会话令牌)descriptionc           
        K   t          |           d {V }|t          v rdddS t                      d d         }t          || j        || j        | j                  }|t          |<   |t          |<   |                    |d            t          
                    d| d|            t                       d|||j        |j        t          |j                  |j        t!          |j                  d	d
S )NFu   你已经在一个房间中r   r<   r   zRoom created: z by T)idr>   r?   rv   r@   has_password)r   r=   r   )r   r8   r   r;   r   r@   rA   r9   rn   r  r  r   r>   r?   rf   rD   bool)r	  r   rQ   r=   r   s        r#   create_roomr%    s      #M22222222H: +HIIIrr"G'!  D E'N"JxOOHd###
KK888h88999OOOI|--+ //
 
  r"   z
/api/roomsc                  .  K   g } t                                           D ]\}|                     |j        |j        |j        t          |j                  |j        t          |j
                  |j        d           ]|                     d d           d| iS )N)r"  r>   r?   rv   r@   r#  rI   c                     | d         S )NrI   r!   r^   s    r#   <lambda>zget_rooms.<locals>.<lambda>  s
    < r"   Tkeyr   r9   )r9   valuesr   r=   r>   r?   rf   rD   r@   r$  rA   rI   sort)	room_listr   s     r#   	get_roomsr/    s      I 	 	,I|--+ ///
 
 	 	 	 	 NN00$N???Yr"   z/api/rooms/{room_id}/joinr=   c                 j  K   t          |           d {V }t                              |           }|sdddS t          |j                  |j        k    rdddS |j        r|j        |j        k    rdddS | t          |<   t          	                    d| d|             t                       d| |d	S )
NFu   房间不存在r   u   房间已满u   房间密码错误User z joined room T)r   r=   rQ   )r   r9   rm   rf   rD   r@   rA   r8   r  r  r   )r=   r	  r   rQ   r   s        r#   join_room_by_pathr2    s      #M22222222H99WD > +<===
4<D,,, >:::} A'*::: +?@@@"Jx
KK888w88999OOO  r"   z/api/rooms/leavec                   K   t          |            d {V }t                              |          }|sdddS t                              |          }|rU|                    |           |j        s9t                              |d            t                              d| d           t                              |d            t                       t                              d| d|            dd	iS )
NFu   你不在任何房间中r   Room  deleted (empty)r1  z left room r   T)
r   r8   rm   r9   rq   rD   rp   r  r  r   )r   rQ   r=   r   s       r#   
leave_roomr6    s     #M22222222HnnX&&G G +EFFF99WD ;8$$$| 	;IIgt$$$KK9999:::NN8T"""OOO
KK666W66777tr"   z/api/leaderboardc                    K   g } t                                           D ]\  }}|d         }|                     ||d         |d         |d         |d         t          |d         t	          |d         d          z  d          t          |d         t	          |d         d          z  dz  d          d	           |                     d
 d           d| d d         dS )Nr  rd   re   r  r  r   r*   rT   )rQ   rd   re   r  r  kd_ratiowin_ratec                     | d         S )Nrd   r!   r(  s    r#   r)  z!get_leaderboard.<locals>.<lambda>  s
    1W: r"   Tr*  2   )r   leaderboard)r6   rx   r   roundrz   r-  )r<  rQ   	user_datar  s       r#   get_leaderboardr?    s      K'~~// 
 
)'" 7^Ho&M!.1eGns5?A/F/FFJJeFmc%2G.K.KKcQSTUU
 
 	 	 	 	 --t<<<K,<===r"   z/api/online-playersc                  l  K   g } t          j                     }t                                          D ]q\  }}||d         z
  dk     r]|d         }t                              |i           }|                     ||t          v |                    ddddddd          d           rd| t          |           d	S )
NrI   ,  rQ   r  r   r  )rQ   in_gamer  T)r   online_playerscount)rH   r7   rx   r6   rm   r   r8   rf   )rC  current_timer   r  rQ   r>  s         r#   get_online_playersrF    s      N9;;L"*.."2"2  w',//#55z*H Xr22I!!$#z1"w$%$%1 1  
# 
# 
 
 
 (^$$& & &r"   z/api/admin/clear-databasec           	      J  K   | j         dk    rt          dd          t          t                    t          t                    t          t
                    t          t                    t          d t
                                          D                       d}t
                                          D ]Y}t          |j
                                                  D ]0}	 |                    dd	           d {V  !# t          $ r Y -w xY wZt                                           t                                           t
                                           t                                           t                       t                              d
|            dd|dS )Nadmin123     管理员密码错误r  c              3   >   K   | ]}t          |j                  V  d S r   rf   rD   r   r   s     r#   	<genexpr>z!clear_database.<locals>.<genexpr>;  ,      JJ4S..JJJJJJr"   )usersr7   r9   r8   total_playersih  zDatabase clearing)codereasonz!Database cleared - Stats before: Tu   数据库已清空)r   messagecleared)r   r   rf   r6   r7   r9   r8   sumr,  r   rF   closeBaseExceptionclearr   r  r  )r	  stats_beforer   wss       r#   clear_databaser\  1  s     ++4KLLLL XMMU*ooJJ5<<>>JJJJJ L   t'..0011 	 	BhhD1DhEEEEEEEEEE    	
 NNNN	KKMMMOOO
KKBLBBCCC(  s   !C??
DDz/api/admin/statsc           
        K   | j         dk    rt          dd          dt          t                    t          t                    t          t
                    t          t                    t          d t
                                          D                       d t
                                          D             dS )	NrH  rI  rJ  r  Tc              3   >   K   | ]}t          |j                  V  d S r   rL  rM  s     r#   rN  z%get_database_stats.<locals>.<genexpr>Y  s,      'U'UdDL(9(9'U'U'U'U'U'Ur"   c                 ^    g | ]*}|j         |j        t          |j                  |j        d +S ))r"  r>   rD   r?   )r=   r>   rf   rD   r?   rM  s     r#   r   z&get_database_stats.<locals>.<listcomp>Z  sT     S S S <@ %)L&*i),T\):):)-7 7 S S Sr"   )r   users_countactive_sessionsactive_roomsusers_in_roomstotal_players_onlineroom_details)	r   r   rf   r6   r7   r9   r8   rV  r,  )r	  s    r#   get_database_statsrf  P  s      ++4KLLLLx=="8}}JJ!*oo$''U'Uellnn'U'U'U$U$US S DI<<>>S S S	T 	T 	Tr"   z/ws/{room_id}rR   c                 0&  >?K   	 t          |          ??s|                     d           d {V  d S t                              ?          |k    r|                     d           d {V  d S t                              |          }|s|                     d           d {V  d S |                                  d {V  |                    ?|           s|                     d           d {V  d S t                              d? d|            	 	 | 	                                 d {V }	 t          j        |          }n# t          $ r Y =w xY w|                    d	          d
k    rW|                    dd          |                    dd          }}?|j        v r ||j        ?         d<   ||j        ?         d<   n`|                    d	          dk    r^?|j        v rSt          |                    dd                    }t          |                    dd                    }	||	d|j        ?<   n|                    d	          dk    r?|j        v rt          |                    dd                    }t          |                    dd                    }	|j        ?         }
t          |                    dd                    }t!          |                    dd                    }|j                            ||	|?t'          j                    |d           t'          j                    |
d<   n|                    d	          dk    rr?|j        v rft          |                    dd                    }t          |                    dd                    }	|j        ?         }
|
d         |
d         }}||z
  }|	|z
  }t)          t+          j        ||                    }d}g }|t*          j        dz  k     s|dt*          j        z  dz  k    r2t1          dd          D ] }|                    ||	||z  z   d           !n1t1          dd          D ] }|                    |||z  z   |	d           !|j                            ||	?|t'          j                    d            t'          j                    |
d<   nX|                    d	          d!k    r?|j        v rt          |                    dd                    }t          |                    dd                    }	|j                            ||	t6          j        ?t'          j                    d"d#           t'          j                    |j        ?         d<   
n|                    d	          d$k    rg?|j        v r[|j        ?         }
|
d         |
d         }}t!          |                    d|                    }t!          |                    d|                    }||z
  }||z
  }t+          j        ||          }|dk    r.t6          j        }|dk    r||k    r||z  }|||z  z   }|||z  z   }nd%\  }}|d&z   }|}t?          d'tA          tB          d'z
  |                    }t?          d'tA          tD          d'z
  |                    }t+          j        ||z
  ||z
            }t+          j#        |          }t+          j$        |          }t'          j                    }tK          tM          j'                              d d         t          |          t          |          ?|||||t6          j(        z   d(d)
}?fd*|j)        D             }t6          j*        dk    r[tW          |          t6          j*        k    r>tA          |d+ ,          }	 |j)        ,                    |           n# tZ          $ r Y nw xY w|j)                            |           ||
d<   n|                    d	          d-k    rX?|j        v rL|j        ?         } t'          j                    }t!          |                    d.d                    }t!          |                    d/d                    }t!          |                    d0t6          j.                            }	 t          |                    d1t6          j/                            }!n# t`          $ r t6          j/        }!Y nw xY wt?          dtA          |!t6          j/                            }!||z  ||z  z   d2z  pd3}"||"z  }||"z  }| d         | d         }$}#|#|tA          t6          j.        t?          d"|                    z  z   }%|$|tA          t6          j.        t?          d"|                    z  z   }&t?          d'tA          tB          d'z
  t          |%                              }%t?          d'tA          tD          d'z
  t          |&                              }&|%|&}}g }'t6          j1        d4z  t6          j2        z   }(tg          |j                  D ]a\  })}*tg          |*d5                   D ]F\  }+},|,d         |,d         }.}-ti          |-|.|#|$||          }/|/|(k    r|'                    |)|+f           Gb|'rdd6l5m6}0  |0tn                    }1|'D ] \  }2}3|1|2                             |3           !|18                                D ]d\  }2}4|j        |2         }*ts          |4d7          D ]@}3d|3cxk    rtW          |*d5                   k     rn %|*d5         :                    |3           Aed8 |j        D             |_        t+          j        ||#z
  ||$z
            pd&}5|5t?          d3t6          j;                  z  }6|#|$||||6d9| d:<   || d;<   || d<   |j        8                                D ]\  }7}8|7?k    r|8d<         dk    rti          |8d         |8d         |#|$||          }9|9t6          j2        k    rF|8d<xx         |!z  cc<   ||8d<   |8d<         dk    r%d|8d<<   | d=xx         d&z  cc<   |8d>xx         d&z  cc<   ty                      >tg          |j                  D ]\  }}:|:                    d?          ?k    r|:                    d<d          dk    r:ti          |:d         |:d         |#|$||          }9|9t6          j2        k    rKt?          d|:                    d<d          |!z
            |:d<<   |:d<         dk    r>=                    |           >r%>fd@tg          |j                  D             |_        n|                    d	          dAk    r?|j        v r|j        ?         }
|                    d|
d         pdB          }|                    d|
d         pd          }|                    dCdD          }|                    d1dE          }!|j>                            |
d         |
d         ||?g |
d         |
d         ||!t'          j                    dFdG           t'          j                    |
d<   n|                    d	          dHk    r׉?|j        v r|j        ?         }
|                    dd          }|                    dd          }|                    dCdI          }|                    d1dJ          }!|j>                            |
d         |
d         ||?g |
d         |
d         ||!t'          j                    dKd dLdM           t'          j                    |
d<   n|                    d	          dNk    r?|j        v r|j        ?         d<         dk    rv|j        ?         ?                    t          jA        dOtB          dOz
            t          jA        dOtD          dOz
            t6          jB        t'          j                    dP           # t          $ r Y nw xY w	 ?|j        v r|j        ?         };?t          v rt          ?         dQ         }<|<dRxx         d&z  cc<   |<d=xx         |;d=         z  cc<   |<d>xx         |;d>         z  cc<   tW          |j                  d&k    s|;d=         dk    r|<dSxx         d&z  cc<   |E                    ?           t                              d? dT|            |j        s9t          :                    |d            t                              dU| dV           t          :                    ?d            t                       nE# ?|j        v r|j        ?         };?t          v rt          ?         dQ         }<|<dRxx         d&z  cc<   |<d=xx         |;d=         z  cc<   |<d>xx         |;d>         z  cc<   tW          |j                  d&k    s|;d=         dk    r|<dSxx         d&z  cc<   |E                    ?           t                              d? dT|            |j        s9t          :                    |d            t                              dU| dV           t          :                    ?d            t                       w xY wn4# t`          $ r'}=t          G                    dW|=            Y d }=~=nd }=~=ww xY w|                     dX           d {V  d S )YNi  )rR  i  i  i  zPlayer z connected to room Ttypemover`   r   ra   	target_dx	target_dyrK   r^   r_   )r^   r_   smoke_grenaderadiusx   durationr<   )r^   r_   rm  r   rI   ro  rc   
build_wall    r\      )r^   r_   r   r   rI   summon_turretr   )r^   r_   rb   r   rI   	last_fireplace_cross_bomb)r   r   r      armed)
r"  r^   r_   r   angler   r   
planted_at
explode_atstatec                 x    g | ]6}|                     d           k    |                     d          dk    4|7S )r   r|  
detonatingr   )r   brQ   s     r#   r   z&websocket_endpoint.<locals>.<listcomp>  sj      (F  (F  (FaquuW~~YaGaGafgfkfklsftft  yE  gE  gE  gE  gE  gEr"   c                 .    |                      dd          S )Nrz  r   r   )r  s    r#   r)  z$websocket_endpoint.<locals>.<lambda>  s    QUU<YZE[E[ r"   )r+  r   r   r   r   r   r   r   g       @r   r   r   c                 "    g | ]}|d          
|S r   r!   r   s     r#   r   z&websocket_endpoint.<locals>.<listcomp>(  s!    )O)O)O1X;)O!)O)O)Or"   )sxsyexeystartro  
iaido_dash
last_iaidorb   rd   re   r   c                 "    g | ]\  }}|v	|S r!   r!   )r   jtturret_indices_to_removes      r#   r   z&websocket_endpoint.<locals>.<listcomp>P  s)    +w+w+w$!QUV^vUvUvAUvUvUvr"   shoot
   max_disti   rA  normalr^   r_   r`   ra   r   hit_setstart_xstart_yr  r   rI   rh  shoot_missilei  iX  r   F)r^   r_   r`   ra   r   r  r  r  r  r   rI   rh  targetexplodedrespawnrT   )r^   r_   rb   rc   r  r  r  z disconnected from room r4  r5  zWebSocket error: i  )Hr  rW  r8   rm   r9   acceptrn   r  r  receive_textr.   loadsrX  rD   r{   rK   floatrL   r   rH   r   mathatan2pirangerJ   rM   rk   TURRET_INITIAL_HPhypotCROSS_BOMB_PLACE_DISTANCErz   minri   rj   cossinr   r   r   CROSS_BOMB_FUSE_SECrN    CROSS_BOMB_MAX_ACTIVE_PER_PLAYERrf   remove
ValueErrorIAIDO_DISTANCEIAIDO_DAMAGEr  WALL_BLOCK_SIZEIAIDO_WIDTHr   r   r   r   r   rx   r   rp   IAIDO_SPEEDsetaddrE   updaterg   rh   rl   r   r6   rq   r   r   )@rR   r=   r   r   r   msgr`   ra   r^   r_   r}   rm  ro  pxpyry  
block_sizewall_blocksitxtydistr  ratiofinal_xfinal_yr   r   r   r   active_bombsoldestr   r   r   r  r  r  r  	to_removethreshr   r[   r   r   r   r   dsegr   mwibibis	dash_distdash_durationr   otherr   r  player_data
user_statsr  r  rQ   s@                                                                 @@r#   websocket_endpointr  `  s      w.&}55 	//t/,,,,,,,,,F>>(##w..//t/,,,,,,,,,Fyy!! 	//t/,,,,,,,,,F         x33 	//t/,,,,,,,,,FDhDD7DDEEEd	O&3355555555*T**CC$   H 776??f,, WWT1--swwtQ/?/?B4<//>@X.{;>@X.{;WWV__
224<//Q00Q00892B2Bh/WWV__774<//Q00Q00!%h!7!$SWWXs%;%;!<!<#(Q)?)?#@#@**!"!"&,%-*.)++(0, ,    .2Y[[z*WWV__444<//Q00Q00!%h!7!'fSkBVV #DJr2$6$6 7 7%'
&( 47Q;..%!dg+/2I2I%*2q\\ G G + 2 2*+!a*n2D$E$E!G !G !G !GG
 &+2q\\ G G + 2 2*+a*n*<1$E$E!G !G !G !G 
))!"%-&1*.)++	+ +    .2Y[[z*WWV__774<//Q00Q00++!"!""%"7%-*.)++),- -    >BY[[X.z:WWV__(:::4<//!%h!7!'fSkB"3773#3#344"3773#3#344"W"W#z"b11!88'*'DH'!||x(04%'"u*_%'"u*_ &.FB!#aB!#B"%b#i"nb*A*A"B"B"%b#j2or*B*B"C"C $
7R<2 F F#x#x!%"%djll"3"3BQB"7!$W!$W%-%*$($(*0*033J*J%,    (F  (F  (F  (F43C  (F  (F  (F?!CCLHYHY]`  ^B  IB  IB%(;[;[%\%\%\F% $ 0 7 7 ? ? ? ?#- % % % $%(//555-3z*WWV__//4<// L2!%$SWWVQ%7%788$SWWVQ%7%788$SWWZ9K%L%LMM6%(3;K)L)L%M%MFF( 6 6 6%(%5FFF6!$QFC4D(E(E!F!F $tdTk 9cAHS!"33B$S-?S$)P)P"PP$S-?S$)P)P"PP SRR%A%ABB Sb#b''%B%BCC!#RB$&	"%"5";s!N+4TZ+@+@ E EKE409$x.0I0I E Eu).sU3ZB'=b"b"bRT'U'U#'6>>$-$4$4eU^$D$D$D	E
 % P?????? +D 1 1A*3 1 1B !"R 0 0 0 0+,7799 ? ?C'+z"~*0d*C*C*C !? !?B'(B'D'D'D'DT(^1D1D'D'D'D'D'D(,X(:(:2(>(>(>!? *P)OTZ)O)O)ODJ$(JrBwR$@$@$EA	(1CS_4M4M(M"$B"$B%+(5	+ +, +1,(.*,0L,>,>,@,@ 9 9LE5$00 ($T{a// ( 6uSz5:rSUWY[] ^ ^A CO33 %dv 54:j 1#(;!#3#323E$K$%gJJJ!OJJJ$)(OOOq$8OOO36550$-dl$;$; 	D 	DDAq uuW~~99 ( uuT1~~22 ( 6qvqvr2rSU V VA CO33*-atQ&1H*I*I$#$T7a<<$<$@$@$C$C$C3 x+w+w+w+w)DL:Q:Q+w+w+wDLWWV__//4<//!%h!7 WWT6$<+=2>> WWT6$<+<1==#&77:s#;#;!$3!7!7++!'6#;"$B%-')'-c{vc{(0&,*.)++$,
- 
- 
 
 
 .2Y[[z*WWV__774<//!%h!7 WWT1-- WWT1--#&77:s#;#;!$3!7!7++!'6#;"$B%-')'-c{vc{(0&,*.)++$-&*(-- -    .2Y[[z*WWV__	114<//DL4J44PTU4U4UX.55!'Y_!E!E!'Z#5E!F!F"%"3(,		7 7   UOb # 	 	 	D	4<''"l84x''!)(!3G!<J~...!3...w''';w+??'''x(((K,AA(((4<((A--W1E1I1I"6***a/***x(((KKM(MMGMMNNN< ?		'4(((=G===>>>NN8T***OOOO 4<''"l84x''!)(!3G!<J~...!3...w''';w+??'''x(((K,AA(((4<((A--W1E1I1I"6***a/***x(((KKM(MMGMMNNN< ?		'4(((=G===>>>NN8T***OOOOO . . .,,,--------.
//t/
$
$$$$$$$$$$s   -AK :AK 18AK +AAK 9 AK A@- 6E 
A@- 
EA@- EY6A@- _* )A@- *
_74A@- 6_77CA@- -d  A@- dA@- d\A@- @-
A@:@7AF  @9A@:@:AF  @>EAK F EAKKAK K
AK7KAK2K2AK7c                  %  QRSK   	 	 t          j                     Rt          t                                                    D ]3} | j        st          j                     RRfd| j        D             | _        g }| j        D ]}R|                    dR          z
  }||                    dd          k     r\t          j	        }t          ||z  d          }|                    dt          j                  }||z  |d<   |                    |           || _        g }g }g }	| j        D ]}
|
                    d	d
          }|d
k    rFR|
                    dR          k    r|	                    |
           N|                    |
           d|dk    r>|
                    dR          }R|z
  t          j        k    r|                    |
           t                      }|	r|	                    d          }
|
                    d          }||v r2|                    |           d|
d	<   R|
d<   t%          | |
R           |
                    d          }g }|D ]}|                    d          |k    rYt'          |
|                    dd          |                    dd                    r d|d	<   R|d<   |	                    |           t|                    |           |}|                    |
           |	||z   | _        | j                                        D ]}|                    d          }|rډR|                    dR          z
  t)          d|                    dd                    z  }|dk    rU|                    d|d                   |d<   |                    d|d                   |d<   |                    dd            nA|d         |d         |d         z
  |z  z   |d<   |d         |d         |d         z
  |z  z   |d<   d}|                    dd          }|                    dd          }|                    dd          |z  |d|z
  z  z   |d<   |                    d d          |z  |d|z
  z  z   |d <   t+          |d                   d!k     rd|d<   t+          |d                    d!k     rd|d <   t)          d"t          t,          d"z
  |d         |d         z                       }t)          d"t          t.          d"z
  |d         |d          z                       }d#}| j        D ]D}|d$         D ]5}|d         |d         }}d%}t1          ||d         d%|||d&z            rd} n6|r nEd#} | j        D ]D}|d$         D ]5}|d         |d         }}d%}t1          |d         |d%|||d&z            rd}  n6| r nE|s||d<   | s||d<   g }!t                      Qg }"t3          | j                  D ]\  }#}$t3          | j                  D ]~\  }%}t3          |d$                   D ]c\  }&}|d         |d         }}t7          |$d         |$d         ||          d"k     r,|"                    |%|&f           Q                    |#           d|$                    d'          d(k    r|$                    d)d#          smd }'d }(| j                                        D ]c\  })}*|)|$d         k    rR|*d*         dk    rFt7          |*d         |*d         |$d         |$d                   }+|+t          j        k    r|'|+|'k     r|+}'|)}(d|(|$d+<   |(r| j        |(         d         },| j        |(         d         }-|,|$d         z
  }.|-|$d         z
  }/t=          j        |.|/          }0|0dk    rt=          j        |$d         |$d                    pd,}1|$d         |1z  }2|$d          |1z  }3|.|0z  }4|/|0z  }5d-}6d|6z
  |2z  |6|4z  z   }7d|6z
  |3z  |6|5z  z   }8t=          j        |7|8          pd}9|7|9z  |1z  |$d<   |8|9z  |1z  |$d <   |$dxx         |$d         z  cc<   |$dxx         |$d          z  cc<   t7          |$d         |$d         |$d.         |$d/                   }:d|$d         cxk     rt,          k     rpn d|$d         cxk     rt.          k     rTn |:|$d0         k     rDR|$d         z
  t          j         k     r+|$                    d)d#          s|!                    |$           |!| _        g };| j!        D ]}|                    d1|                    dR                    }<t)          d2R|<z
            }|dk    r<t)          d|                    d*d          t          j"        |z  z
            |d*<   R|d1<   |                    d*d          dk    r|d         |d         }-},d }=d }>| j                                        D ]u\  })}*|)|                    d          k    s|*d*         dk    r+|*d         |,z
  d&z  |*d         |-z
  d&z  z   d3z  }+|+t          j#        k    r|=|+|=k     r|+}=|*d         |*d         f}>v| j!        D ]}||u r|                    d          |                    d          k    r4|                    d*d          dk    rO|d         |,z
  d&z  |d         |-z
  d&z  z   d3z  }+|+t          j#        k    r|=|+|=k     r|+}=|d         |d         f}>|>rΉR|                    d4d          z
  t          j$        k    r|>\  }?}@|?|,z
  }.|@|-z
  }/|.d&z  |/d&z  z   d3z  pd}0|.|0z  t          j%        z  }A|/|0z  t          j%        z  }B| j                            |,|-|A|B|                    d          g |,|-t          j&        t          j'        t          j                     d5d6           R|d4<   |;                    |           |;| _!        t                      }C| j                                        D ]\  }D}t3          | j                  D ]\  }#}$|d*         dk    s|D|Cv r|$d         |Dk    r|D|$                    d7g           vrpt7          |d         |d         |$d         |$d                   }:|$                    d'          d(k    rt          j(        nt          j)        }E|:|Ek     r|$                    d8t          j*                  }F|d*xx         |Fz  cc<   R|d9<   |$+                    d7g                               |D           |$d         tX          v r'tX          |$d                  d:         d;xx         |Fz  cc<   |d*         dk    rY|D|CvrU|C                    |D           |d<xx         dz  cc<   |$d         | j        v r!| j        |$d                  d=xx         dz  cc<   Q                    |#           t                      St3          | j!                  D ]n\  }G}|                    d*d          dk    rS                    |G           6|d         |d         }-},t3          | j                  D ]\  }#}$|$                    d          |                    d          k    r2t7          |,|-|$d         |$d                   }:|$                    d'          d(k    rt          j(        nt          j)        }E|:|Ek     r]t)          d|                    d*d          |$                    d8t          j*                  z
            |d*<   Q                    |#           |                    d*d          dk    rS                    |G           pSr%Sfd>t3          | j!                  D             | _!        Qr%Qfd?t3          | j                  D             | _        |"rdd@l-m.}H  |Ht                    }I|"D ] \  }%}&|I|%                             |&           !|I                                D ]d\  }%}J| j        |%         }t_          |JdA          D ]@}&d|&cxk    rta          |d$                   k     rn %|d$                             |&           AedB | j        D             | _        | j                                        D ]}dC|                    dDg           v otc          t          dEd          }KR|d9         z
  t          j2        k    o#|d*         t          j3        k     o|d*         dk    p|K}L|Lr9t          j4        }MdF|                    dDg           v r|MdGz  }M|d*xx         |Mz  cc<   |d*         t          j3        k    rt          j3        |d*<   |d*         dk    rd|d*<   |CD ]`}D| j5                            |D          }N|NrB	 |N6                    to          j8        dHdIdJ                     d {V  P# tr          $ r Y \w xY wa| j5        r}| :                                }to          j8        |          }Ot          | j5                                                  D ].}N	 |N6                    |O           d {V  # tr          $ r Y +w xY w5tw          j<        dK           d {V  nN# tz          $ rA}Pt|          ?                    dL|P            tw          j<        d           d {V  Y d }P~Pnd }P~Pww xY w)MNTc                 b    g | ]+}|                     d           z
  t          j        k     )|,S )rI   )rm   rk   WALL_LIFETIME_SEC)r   r&   nows     r#   r   zgame_loop.<locals>.<listcomp>  sV     6 6 6SEE$ .  #4.5 .5A .5 .5 .5r"   rI   ro  r<   r   rm  current_radiusr|  rx  r{  r~  detonate_timer   r"  r   r^   r_   r  r  gư>gMbP?r   r  r  r  r  g333333?rj  rk  r`   ra   g?rw  Fr   rq  r*   rh  r   r  rb   r     g{Gz?r  r  r  
last_decayr   r   ru  r   r  r  r   rc   r  r  re   rd   c                 "    g | ]\  }}|v	|S r!   r!   )r   r  r  r  s      r#   r   zgame_loop.<locals>.<listcomp>  s6     $P $P $P"a-.6N-N-N -N-N-Nr"   c                 "    g | ]\  }}|v	|S r!   r!   )r   r  r  bullets_to_removes      r#   r   zgame_loop.<locals>.<listcomp>  s6     $I $I $I"a-.6G-G-G -G-G-Gr"   r   r   c                 "    g | ]}|d          
|S r   r!   r   s     r#   r   zgame_loop.<locals>.<listcomp>  s!    !G!G!G1X;!G!!G!G!Gr"   r   r]   ALLOW_REGEN_WHEN_DEADr   r  deathu   你已死亡! 按R重生)rh  rT  g{Gz?zGame loop error: )@rH   r   r9   r,  rD   rJ   rL   rm   rk   SMOKE_APPEAR_ANIM_SECr  SMOKE_DEFAULT_RADIUSr   rN   CROSS_BOMB_EXPLOSION_DURATIONr  rp   r  r   r   rz   r   ri   rj   r   r   rE   r   rx   MISSILE_TRACK_RANGEr  r  BULLET_MAX_LIFETIME_SECrM   TURRET_SELF_DECAY_PER_SECTURRET_RANGE	TURRET_CDTURRET_BULLET_SPEEDTURRET_MAX_DISTTURRET_BULLET_DAMAGEMISSTLE_HIT_RADIUSBULLET_HIT_RADIUSBULLET_DEFAULT_DAMAGEr   r6   r   r   r   rf   getattrREGEN_INTERVAL_SECrl   REGEN_AMOUNT_PER_TICKrF   	send_textr.   dumpsrX  r   asynciosleepr  r  r   )Tr   updated_smokesselapsedappear_durationprogress
max_radiusarmed_bombsdetonating_bombstrigger_queuer   r|  det_timeprocessed_idsbomb_idr   	remainingr  r}   dashr  inertiarj  rk  next_xnext_y	blocked_xr[   r   r   r   r  	blocked_ynew_bulletswall_blocks_to_removeidxbulletr   r   min_disttarget_namer   r   r   r  r  r`   ra   dist_to_targetspeed	cur_dir_x	cur_dir_y	tgt_dir_x	tgt_dir_yalpha	new_dir_x	new_dir_yr   r  updated_turretsr  min_d
target_posr  r  r   r   dead_playersrQ   
hit_radiusr   t_idxr   wall_remove_mapr   can_regen_when_dead	can_regenamountr[  rT  r  r  r  r  sT                                                                                    @@@r#   	game_loopr    s     j#i	#)++CU\\^^,, c! c!| ikk6 6 6 6#z6 6 6
 "$ 1 1A!AEE,$<$<<Gz1!5!555*-*C#&w'@##F#F%&UU8S5M%N%N
.88.C*+&--a000, !#%  " , 
: 
:D HHWg66E''$((<"="===)006666'..t4444,..#'88OS#A#A>S-NNN,33D999 ## 2(,,Q//D"hhtnnG-// !%%g...$0DM,/D)+D$<<< HHW--E "I!, 4 4 99W--66;NtUZU^U^_bdeUfUfhmhqhqruwxhyhy;z;z6-9E'N58E/2)007777%,,U3333"+K$++D111) $ 2* $/1A#A "l1133 <- <-F!::l33D 
% 488GS#9#99StxxPZ\aGbGb=c=cc66*.((4*E*EF3K*.((4*E*EF3K"JJ|T::::*.t*T
T$Z8OST7T*TF3K*.t*T
T$Z8OST7T*TF3K$"G &

; : :I &

; : :I#)::a$! $!#*$+-6!g+-F$GF4L#)::a$! $!#*$+-6!g+-F$GF4L 6$<((3..'(t6$<((3..'(t C%NF3K&,,FH HI IF !C&OVC[6$<-GI IJ JF !&I $
 	" 	"%)(^ & &E%*3ZsB)+J266#;BPRT^abTbcc &,0	 %& % "!E" !&I $
 " "%)(^ & &E%*3ZsB)+J26#;BPRT^abTbcc &,0	 %& % "!E" % -&,s$ -&,s $'EE!(*%#,T\#:#: 83 83KC'0'<'< ; ;t,5d8n,E,E ; ;LE5%*3ZsB'sVC["bIIBNN 5 < <eU^ L L L 1 5 5c : : :	; zz&))Y66vzz&@/ @/6 $(&*(,(:(:(<(< < <HE1$w77AdGaKK$,QsVQsVVC[&QT+$V$V#$(?#?#?'/'71x<<346;+6x(& H!%k!:3!?B!%k!:3!?B!#fSk!1B!#fSk!1B-1ZB-?-?N-11(,
6$<(N(N(TRT,24L5,@	,24L5,@	,.,?	,.,?	(,$%I-;=BY=N-O	 %&I-;=BY=N-O	'+z)Y'G'G'L1/84/?%/Gt/84/?%/Gt3KKK6$</KKK3KKK6$</KKK#F3KfY>OQWXaQbccDF3K3333)33333F3K8T8T8T8T*8T8T8T8T8TY]`fgq`rYrYrwz|,x-/2/JxK xKSYS]S]&!T# T#xK $**6222* #% 6. 6.A!"|QUU<5M5M!N!NJ!#sZ'788G{{"%atQ#:WZa:a)a"b"b$*-,uuT1~~** sVQsVB E!%J$(L$6$6$8$8 : :q AEE'NN22agll$frka/1S6B;12DDL 000emq5yy$%E*+C&!C&)9J!% B B A::$ 99W--w??$ 99T1--22$#Cj2o!3#Cj2o!348;< 000emq5yy$%E*/*eCj)AJ! -cAEE+q,A,A&AS]&R&R!+B"W"W*,'B!G*;)C)Hq.033JJ.033JJ++!#""$B%&UU7^^')')b(+(;&)&>*.)++$,
- 
- 
 
 
 *-+#**1----.  #uu(,(:(:(<(< ; ;$Hf'0'>'> ; ;V!$<1,,L0H0H$"7Ox77 (

9b0I0I I I#+F3KfSkSYZ]S^#_#_DCI:: &D( D(+4D5 D5)?)?:=:O '#j00)/$,c.G*I *I &t 658z 2 & 1 1$-r!3 !3396(3C3C3C#)'?h#>#>$,VG_ %//6%88F%H %H %HKQ%R %H %H %H $*$<1#4#49U9U$0$4$4X$>$>$>$*8$4$4$4$9$4$4$4'-g$,'F'F(,VG_ )77>)@ )@ )@CD)E )@ )@ )@ 1 5 5c : : :3;8 ,/55( )$, 7 7 < <HE1uuT1~~**044U;;; sVQsVB'0'>'> 7 7V!::g..!%%..@@$'BsVC[II?Ezz"@$ @$'0@1 @1S%;%;696K #*,,&) ! !$($%!' !' !'

$,$'$=!? !?!?'@ '@AdG .11#666uuT1~~**044U;;;+ P$P $P $P $P&/ L'* '*$P $P $PDL
 % I$I $I $I $I&/ L'* '*$I $I $IDL ) H777777&1k$&7&7O(= = =u'.55e<<<<)8)>)>)@)@ : :v#z%0%+FD%A%A%A : :E E????CX,?,?????? $X 2 25 9 9 9: "H!GTZ!G!G!GDJ #l1133 ) )F+<

7TV@W@W+W  +I]deh  kB  DH  ^I  ^I' #fZ&8 83;Q Q  !eV\]aVbehevVv  !e  }C  DH  }I  LM  }M  }d  QdI  /!$!:(FJJw,C,CCC%+b[Ft.d|c&777'*'8td|q(('(t !- ! !H)--h77B !!"$,,tz7Wq:r:r/s/s"t"ttttttttt, ! ! ! D!!
 # ! NN,,E"j//G"4#3#:#:#<#<== ! !!"$,,w"7"777777777, ! ! ! D!-%%%%%%%%%% 	# 	# 	#LL0Q00111-""""""""""""""	#Qj#s   AF%AJ F.0AGGAJ G
AG,G)AJ G+AG,G,AAJ IAI$I#AJ I$
AI1I.AJ I0AI1I1AJ J
AKJ7AKKAKstartupc                  ~   K   t                               d           t          j        t	                                 d S )NzStarting game server...)r  r  r  create_taskr  r!   r"   r#   startup_eventr!    s4      
KK)***	$$$$$r"   shutdownc                  Z   K   t                               d           t                       d S )Nz"Saving all data before shutdown...)r  r  r   r!   r"   r#   shutdown_eventr$    s&      
KK4555OOOOOr"   z/healthc            
        K   dt          j                     t          t                    t          t                    t          t                    t          d t                                          D                       dS )Nhealthyc              3   >   K   | ]}t          |j                  V  d S r   rL  rM  s     r#   rN  zhealth_check.<locals>.<genexpr>  rO  r"   )ru   	timestampr`  ra  rb  rQ  )rH   rf   r6   r7   r9   rV  r,  r!   r"   r#   health_checkr)    s`       Y[[8}}x==E

JJ5<<>>JJJJJ  r"   frontend/)	directoryhtmlstatic)r>   __main__z0.0.0.0i  r  )hostport	log_levelr   )ofastapir   r   r   r   r   r   fastapi.middleware.corsr	   fastapi.staticfilesr
   pydanticr   uvicornr  rg   r.   rH   r   r   r  typingr   r   r   loggingr   server_configrk   utilsr   r   r   basicConfigINFO	getLoggerr   r  appadd_middlewarer   dirnameabspath__file__BASE_DIRPROJECT_ROOTjoinr   r   r   r   r   r$   r1   r5   r6   r   r7   r8   r9   r;   r   rx   r=   	room_datar   r   ri   rj   r   dictr  r   r   r   r   r   r   r   r   r   r   r   r   rm   r   postr   r  r   r  r  r  r%  r/  r2  r6  r?  rF  r\  rf  rR   r  r  on_eventr!  r$  r)  
STATIC_DIRmountrunr!   r"   r#   <module>rN     s	   Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z 2 2 2 2 2 2 + + + + + +               ' ' ' ' ' ' ' ' ' '  				     G G G G G G G G G G  ', ' ' ' '		8	$	$g,---   %%%     7??27??84455wx((7<<f--W\\(O44
X77W\\(L11
',,x):;;  
9 9 9
      :&&$ & & &=))$ ) ) )9_--
D - - -t   
d d d d d d d dP )J''	4 ' ' '#//++ / /GY^^I..E'NN& & & M	^
  *(@& (@ (@e (@ (@ (@ (@Z    i       9   
# # # # #	 # # ## # # # #i # # #
    9       9   
9C 9C 9 9 9 9    
   
 $ 	U U U 
  INs G G2 G3 G G G ! Gs x}      s     /!O ! ! ! !H ,    ( 	$%%;s ; ; ; &%;. 
GLuS^rGsGsGs  0     >        
%&&Y^Y^_b  qE  ZF  ZF  ZF  S ? SV    '&& 
*/%AU*V*V*V  C    " 	> > >" 	& &  &0 
%&&,    '&< 
Tl T T T T V[V[\_V`V` y% y%	 y%C y%PS y% y% y%  y%x	k# k# k#\ i% % %
 j  
    W\\,
33
 		#{{Zd;;;(	 K K KzGK)$&AAAAAA r"   