§
    õ¨½ji  ã                  ó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mZmZ  G d„ d¦  «        Zdd„Zdd„ZdS )a™  
FreeExile Server-Authoritative War-Fog Engine.
Implements:
1. Field of View (FOV) calculation with Bresenham Line-of-Sight & wall occlusion.
2. Three-state Fog of War: UNEXPLORED (0), EXPLORED_FOGGED (1), VISIBLE (2).
3. Zero-Trust Server Authority: Entity visibility filtering to defeat maphack/memory-reading bots.
4. Lossless Run-Length Encoding (RLE) Fog Delta Compression for 1M CCU network efficiency.
é    )ÚannotationsN)ÚListÚDictÚAnyÚTupleÚOptional)ÚFogStateÚMapGridDataÚPlayerVisibilityStatec                  ó\   — e Zd ZdZd'd(d„Z	 d)d*d„Z	 d)d+d„Zd,d„Zd-d„Zd.d!„Z	d/d%„Z
d/d&„ZdS )0ÚWarFogEnginezCServer-Authoritative Field of View and Fog of War computing engine.é   Údefault_view_radiusÚintc                ó   — || _         d S ©N)r   )Úselfr   s     ú4C:\Projects\FreeExile\server\world\war_fog_engine.pyÚ__init__zWarFogEngine.__init__   s   € Ø#6ˆÔ Ð Ð ó    NÚ	player_idÚstrÚwidthÚheightÚview_radiusúOptional[int]Úreturnr   c           
     óz   ‡— |p| j         }ˆfd„t          |¦  «        D ¦   «         }t          |‰|||ddd¬¦  «        S )Nc                óB   •— g | ]}d „ t          ‰¦  «        D ¦   «         ‘ŒS )c                ó0   — g | ]}t           j        j        ‘ŒS © )r	   Ú
UNEXPLOREDÚvalue©Ú.0Ú_s     r   ú
<listcomp>zDWarFogEngine.create_player_visibility.<locals>.<listcomp>.<listcomp>   s   € ÐGÐGÐG°Q•xÔ*Ô0ÐGÐGÐGr   ©Úrange©r%   r&   r   s     €r   r'   z9WarFogEngine.create_player_visibility.<locals>.<listcomp>   s.   ø€ Ð_Ð_Ð_ÈAÐGÐG½%À¹,¼,ÐGÑGÔGÐ_Ð_Ð_r   r   )r   r   )r   r   r   r   Ú
fog_matrixÚexplored_tiles_countÚvisible_tiles_countÚlast_pos)r   r)   r   )r   r   r   r   r   Úradiusr+   s     `    r   Úcreate_player_visibilityz%WarFogEngine.create_player_visibility   sd   ø€ ð Ð8 Ô 8ˆØ_Ð_Ð_Ð_ÕQVÐW]ÑQ^ÔQ^Ð_Ñ_Ô_ˆ
Ý$ØØØØØ!Ø!"Ø !Øð	
ñ 	
ô 	
ð 		
r   ÚvisÚmap_datar
   Úplayer_xÚplayer_yÚNonec           
     ó6  — |p|j         }|j        |j        }}|j        \  }	}
t	          d|	|z
  dz
  ¦  «        }t          |dz
  |	|z   dz   ¦  «        }t	          d|
|z
  dz
  ¦  «        }t          |dz
  |
|z   dz   ¦  «        }t          ||dz   ¦  «        D ]T}|j        |         }t          ||dz   ¦  «        D ]1}||         t          j	        j
        k    rt          j        j
        ||<   Œ2ŒUt	          d||z
  ¦  «        }t          |dz
  ||z   ¦  «        }t	          d||z
  ¦  «        }t          |dz
  ||z   ¦  «        }g }t          ||dz   ¦  «        D ]0}|                     ||f¦  «         |                     ||f¦  «         Œ1t          ||dz   ¦  «        D ]0}|                     ||f¦  «         |                     ||f¦  «         Œ1d|cxk    r|k     r2n n/d|cxk    r|k     r"n nt          j	        j
        |j        |         |<   |D ] \  }}|                      |||||||¦  «         Œ!||f|_        d}d}t          |¦  «        D ]H}|j        |         }|D ]6}|t          j	        j
        k    r|dz  }|t          j        j
        k    r|dz  }Œ7ŒI||_        ||_        d S )Nr   é   )r   r   r   r.   ÚmaxÚminr)   r+   r	   ÚVISIBLEr#   ÚEXPLORED_FOGGEDÚappendÚ	_cast_rayr"   r-   r,   )r   r1   r2   r3   r4   r   r/   ÚwÚhÚprev_xÚprev_yÚ
prev_min_xÚ
prev_max_xÚ
prev_min_yÚ
prev_max_yÚyÚrowÚxÚmin_xÚmax_xÚmin_yÚmax_yÚtargetsÚtxÚtyÚ	vis_countÚ	exp_countÚcells                               r   Úupdate_visibilityzWarFogEngine.update_visibility*   s)  € ð Ð/ ¤ˆØŒy˜#œ*ˆ1ˆð œ‰ˆ�Ý˜˜F V™O¨aÑ/Ñ0Ô0ˆ
Ý˜˜Q™ ¨¡°!Ñ 3Ñ4Ô4ˆ
Ý˜˜F V™O¨aÑ/Ñ0Ô0ˆ
Ý˜˜Q™ ¨¡°!Ñ 3Ñ4Ô4ˆ
å�z :°¡>Ñ2Ô2ð 	<ð 	<ˆAØ”. Ô#ˆCÝ˜: z°A¡~Ñ6Ô6ð <ð <�Ø�q”6�XÔ-Ô3Ò3Ð3Ý%Ô5Ô;�C˜‘Føð<õ
 �A�x &Ñ(Ñ)Ô)ˆÝ�A˜‘E˜8 fÑ,Ñ-Ô-ˆÝ�A�x &Ñ(Ñ)Ô)ˆÝ�A˜‘E˜8 fÑ,Ñ-Ô-ˆð *,ˆÝ�u˜e a™iÑ(Ô(ð 	'ð 	'ˆAØ�NŠN˜A˜u˜:Ñ&Ô&Ð&Ø�NŠN˜A˜u˜:Ñ&Ô&Ð&Ð&Ý�u˜e a™iÑ(Ô(ð 	'ð 	'ˆAØ�NŠN˜E 1˜:Ñ&Ô&Ð&Ø�NŠN˜E 1˜:Ñ&Ô&Ð&Ð&ð �ÐÐÒÐ˜1ÒÐÐÐÐ  hÐ!2Ð!2Ò!2Ð!2°Ò!2Ð!2Ð!2Ð!2Ð!2Ý19Ô1AÔ1GˆCŒN˜8Ô$ XÑ.ð ð 	Nð 	N‰FˆB�Ø�NŠN˜3 ¨(°H¸bÀ"ÀfÑMÔMÐMÐMð ! (Ð+ˆŒØˆ	Øˆ	Ý�q‘”ð 	#ð 	#ˆAØ”. Ô#ˆCØð #ð #�Ø�8Ô+Ô1Ò1Ð1Ø ‘N�IØ�8Ô.Ô4Ò4Ð4Ø ‘N�Iøð	#ð
 #,ˆÔØ#,ˆÔ Ð Ð r   Úx0Úy0Úx1Úy1Úmax_distc                ó  — t          ||z
  ¦  «        }t          ||z
  ¦  «        }	||k     rdnd}
||k     rdnd}||	z
  }||}}	 t          j        ||z
  ||z
  ¦  «        }||k    rdS d|cxk    r|j        k     r[n nXd|cxk    r|j        k     rFn nCt
          j        j        |j        |         |<   ||k    s||k    r| 	                    ||¦  «        rdS ||k    r||k    rdS d|z  }||	 k    r
||	z  }||
z  }||k     r
||z  }||z  }ŒÅ)z2Bresenham line algorithm with wall occlusion stop.r7   éÿÿÿÿTr   é   N)
ÚabsÚmathÚhypotr   r   r	   r:   r#   r+   Úblocks_vision)r   r1   r2   rT   rU   rV   rW   rX   ÚdxÚdyÚsxÚsyÚerrÚcurr_xÚcurr_yÚdistÚe2s                    r   r=   zWarFogEngine._cast_rayg   si  € õ ��b‘‰\Œ\ˆÝ��b‘‰\Œ\ˆØ�r’'�'ˆQˆQ˜rˆØ�r’'�'ˆQˆQ˜rˆØ�2‰gˆà˜R�ˆð	Ý”:˜f r™k¨6°B©;Ñ7Ô7ˆDØ�hŠˆØ�à�FÐ&Ð&Ò&Ð&˜SœYÒ&Ð&Ð&Ð&Ð&¨1°Ð+CÐ+CÒ+CÐ+C¸¼Ò+CÐ+CÐ+CÐ+CÐ+CÝ19Ô1AÔ1G�”˜vÔ& vÑ.ð ˜b’L�L F¨b¢L L°h×6LÒ6LÈVÐU[Ñ6\Ô6\ LØ�Eà˜Š|ˆ| ¨"¢ Ø�à�S‘ˆBØ�R�CŠxˆxØ�r‘	�Ø˜"‘�Ø�BŠwˆwØ�r‘	�Ø˜"‘�ð+	r   ÚentitiesúList[Dict[str, Any]]c                ór  — g }|j         |j        }}|D ]£}t          |                     dd¦  «        ¦  «        }t          |                     dd¦  «        ¦  «        }d|cxk    r|k     rNn ŒXd|cxk    r|k     r>n Œh|j        |         |         t
          j        j        k    r|                     |¦  «         Œ¤|S )zï
        Server-Authoritative Anti-Maphack Guard.
        Strictly excludes any entity not residing within a cell with FogState.VISIBLE.
        Prevents client memory inspection or packet sniffing from detecting hidden mobs/loot.
        rH   rZ   rF   r   )	r   r   r   Úgetr+   r	   r:   r#   r<   )	r   r1   ri   Úfilteredr>   r?   ÚentÚexÚeys	            r   Úfilter_visible_entitiesz$WarFogEngine.filter_visible_entities�   sÁ   € ð *,ˆØŒy˜#œ*ˆ1ˆàð 	)ð 	)ˆCÝ�S—W’W˜S "Ñ%Ô%Ñ&Ô&ˆBÝ�S—W’W˜S "Ñ%Ô%Ñ&Ô&ˆBØ�Bˆ{ˆ{Š{ˆ{˜Š{ˆ{ˆ{ˆ{ˆ{˜q B˜{˜{š{˜{¨š{˜{˜{˜{˜{Ø”> "Ô% bÔ)­XÔ-=Ô-CÒCÐCØ—O’O CÑ(Ô(Ð(øàˆr   Úfloatc                ó`   — |j         |j        z  }|dk    rdS t          |j        |z  d¦  «        S )z4Returns explored percentage (0.0 to 1.0) of the map.r   g        é   )r   r   Úroundr,   )r   r1   Útotals      r   Úget_explored_ratiozWarFogEngine.get_explored_ratio¤   s6   € à”	˜CœJÑ&ˆØ�AŠ:ˆ:Ø�3Ý�SÔ-°Ñ5°qÑ9Ô9Ð9r   rH   rF   Úboolc                ó¦   — d|cxk    r|j         k     r>n n;d|cxk    r|j        k     r)n n&|j        |         |         t          j        j        k    S dS )zDReturns True if coordinate is currently inside player line-of-sight.r   F)r   r   r+   r	   r:   r#   ©r   r1   rH   rF   s       r   Úis_cell_visiblezWarFogEngine.is_cell_visible«   sk   € à�ÐÐÒÐ�C”IÒÐÐÐÐ ! qÐ"5Ð"5Ò"5Ð"5¨3¬:Ò"5Ð"5Ð"5Ð"5Ð"5Ø”> !Ô$ QÔ'­8Ô+;Ô+AÒAÐAØˆur   c                ó¦   — d|cxk    r|j         k     r>n n;d|cxk    r|j        k     r)n n&|j        |         |         t          j        j        k    S dS )zJReturns True if coordinate has been explored (visible or previously seen).r   F)r   r   r+   r	   r"   r#   rz   s       r   Úis_cell_exploredzWarFogEngine.is_cell_explored±   sk   € à�ÐÐÒÐ�C”IÒÐÐÐÐ ! qÐ"5Ð"5Ò"5Ð"5¨3¬:Ò"5Ð"5Ð"5Ð"5Ð"5Ø”> !Ô$ QÔ'­8Ô+>Ô+DÒDÐDØˆur   )r   )r   r   r   )
r   r   r   r   r   r   r   r   r   r   )r1   r   r2   r
   r3   r   r4   r   r   r   r   r5   )r1   r   r2   r
   rT   r   rU   r   rV   r   rW   r   rX   r   r   r5   )r1   r   ri   rj   r   rj   )r1   r   r   rr   )r1   r   rH   r   rF   r   r   rx   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r0   rS   r=   rq   rw   r{   r}   r!   r   r   r   r      s×   € € € € € ØMÐMð7ð 7ð 7ð 7ð 7ð UYð
ð 
ð 
ð 
ð 
ð, &*ð;-ð ;-ð ;-ð ;-ð ;-ðz'ð 'ð 'ð 'ðRð ð ð ð(:ð :ð :ð :ðð ð ð ðð ð ð ð ð r   r   ÚmatrixúList[List[int]]r   r   c                ó  — | r| d         sdS d„ | D ¦   «         }g }|d         }d}|dd…         D ],}||k    r|dz  }Œ|                      |› d|› �¦  «         |}d}Œ-|                      |› d|› �¦  «         d                     |¦  «        S )z.Lossless Run-Length Encoding of 2D Fog Matrix.r   Ú c                ó   — g | ]	}|D ]}|‘ŒŒ
S r!   r!   )r%   rG   rR   s      r   r'   z$compress_fog_rle.<locals>.<listcomp>¼   s%   € Ð3Ð3Ð3�S¨sÐ3Ð3 tˆDÐ3Ð3Ð3Ð3r   r7   NrH   ú,)r<   Újoin)r‚   ÚflatÚrunsÚcurrent_valÚcountÚvals         r   Úcompress_fog_rlerŽ   ¸   sÉ   € àð ˜ œð ØˆrØ3Ð3˜FÐ3Ñ3Ô3€DØ€DØ�q”'€KØ€Eà�A�B�BŒxð ð ˆØ�+ÒÐØ�Q‰JˆEˆEà�KŠK˜;Ð0Ð0¨Ð0Ð0Ñ1Ô1Ð1ØˆKØˆEˆEØ‡K‚K�;Ð(Ð( Ð(Ð(Ñ)Ô)Ð)Ø�8Š8�D‰>Œ>Ðr   Úrle_strr   r   r   c                ó*  ‡‡	— ˆfd„t          |¦  «        D ¦   «         }| r‰dk    s|dk    r|S g Š	|                      d¦  «        }	 |D ]~}|sŒ|                     d¦  «        }t          |¦  «        dk    r|c S t          |d         ¦  «        }t          |d         ¦  «        }|dk     r|c S ‰	                     |g|z  ¦  «         Œn# t
          t          f$ r |cY S w xY wt          ‰	¦  «        ‰|z  k    r|S ˆ	ˆfd„t          |¦  «        D ¦   «         S )zHDecompresses RLE string into a 2D integer matrix of size height x width.c                óB   •— g | ]}d „ t          ‰¦  «        D ¦   «         ‘ŒS )c                ó   — g | ]}d ‘ŒS )r   r!   r$   s     r   r'   z1decompress_fog_rle.<locals>.<listcomp>.<listcomp>Î   s   € Ð/Ð/Ð/˜Q�qÐ/Ð/Ð/r   r(   r*   s     €r   r'   z&decompress_fog_rle.<locals>.<listcomp>Î   s.   ø€ ÐGÐGÐG°AÐ/Ð/¥%¨¡,¤,Ð/Ñ/Ô/ÐGÐGÐGr   r   r‡   rH   r[   r7   c                ó6   •— g | ]}‰|‰z  |d z   ‰z  …         ‘ŒS )r7   r!   )r%   rF   r‰   r   s     €€r   r'   z&decompress_fog_rle.<locals>.<listcomp>æ   s/   ø€ ÐEÐEÐE°!ˆD��U‘˜a !™e u™_Ð,Ô-ÐEÐEÐEr   )r)   ÚsplitÚlenr   ÚextendÚ
ValueErrorÚOverflowError)
r�   r   r   Údefault_matrixÚtokensÚtokenÚpartsr�   rŒ   r‰   s
    `       @r   Údecompress_fog_rler�   Ì   sc  øø€ àGÐGÐGÐG½¸v¹¼ÐGÑGÔG€NØð �e˜q’j�j F¨a¢K KØÐà€DØ�]Š]˜3ÑÔ€FðØð 
	'ð 
	'ˆEØð ØØ—K’K Ñ$Ô$ˆEÝ�5‰zŒz˜QŠˆØ%Ð%Ð%Ð%Ý�e˜A”h‘-”-ˆCÝ˜˜aœ‘M”MˆEØ�qŠyˆyØ%Ð%Ð%Ð%Ø�KŠK˜˜ ™Ñ&Ô&Ð&Ð&ð
	'øõ �Ð&ð ð ð ØÐÐÐðøøøõ ˆ4�y„y�E˜F‘NÒ"Ð"ØÐàEÐEÐEÐEÐEµu¸V±}´}ÐEÑEÔEÐEs   Á2C Á93C Â-C ÃCÃC)r‚   rƒ   r   r   )r�   r   r   r   r   r   r   rƒ   )r�   Ú
__future__r   r]   Útypingr   r   r   r   r   Úserver.world.map_data_typesr	   r
   r   r   rŽ   r�   r!   r   r   ú<module>r¡      sñ   ððð ð #Ð "Ð "Ð "Ð "Ð "Ø €€€Ø 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3ðð ð ð ð ð ð ð ð ð ðað að að að añ aô að aðHð ð ð ð(Fð Fð Fð Fð Fð Fr   