
    UHj                       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 dZ	ddZ
ddZddZdd	Zdd
ZddZddZddZ	 	 	 	 	 	 	 	 	 	 	 	 ddZ	 	 	 	 	 	 	 	 	 	 	 	 ddZ	 	 	 	 	 	 	 	 	 	 	 	 ddZddZedk(  r e        yy)a~  Dump probable CNS scene-load records embedded in Hwanse2.exe.

This is a diagnostic helper for the map renderer. The executable contains
arrays of small records that reference CNS filenames plus extra arguments.
Those extra arguments are likely needed to pick tilesets, source tables, map
logic, or scene scripts; treating map CNS values as direct tile IDs has proven
insufficient.
    )annotationsN)Path  @ c           	     (   | d d dk7  rt        d      t        j                  d| d      d   }| ||dz    dk7  rt        d	      t        j                  d
| |dz         d   }t        j                  d
| |dz         d   }|dz   |z   }g }t        |      D ]|  }||dz  z   }| ||dz    j	                  dd      d   j                  dd      }t        j                  d| |dz         \  }	}
}}|j                  |t        |
z   t        |	|      ||d       ~ |S )N   s   MZznot an MZ/PE executable<I<   r      s   PE  znot a PE executablez<H         (             asciireplacez<IIII)namevasizeraw_sizeraw)	
ValueErrorstructunpack_fromrangesplitdecodeappend
IMAGE_BASEmax)exepe_offsection_countoptional_sizesection_offsectionsindexoffr   virtual_sizevirtual_addressr   raw_pointers                3/home/exedev/hwanse/tools/probe_exe_scene_tables.pyread_sectionsr.      sL   
2Aw%233c403F
6FQJ9,.//&&tS&1*=a@M&&tS&2+>qAM2+-KH}% 
EBJ&3q!''q1!4;;GYO?E?Q?QS#'@
<ox 	 ?2L(3$"	

 O    c                b    | D ]*  }|d   }||d   z   }||cxk  r|k  sn |d   |z   |z
  c S  y )Nr   r   r    )r'   r   sectionstartends        r-   va_to_offsetr5   2   sO     /gj))B5>B&..	/
 r/   c                b    | D ]*  }|d   }||d   z   }||cxk  r|k  sn |d   |z   |z
  c S  y )Nr   r   r   r1   )r'   offsetr2   r3   r4   s        r-   offset_to_var8   ;   sO     2gj))F S 4=6)E11	2
 r/   c                p    | j                  d|      }|dk  rt        |       }| || j                  dd      S )Nr   r   r   r   )findlenr   )r"   r7   r4   s      r-   c_stringr<   D   s;    
((5&
!C
Qw#hvc?!!'955r/   c                    i }t        j                  d|       D ]<  }t        ||j                               }| t	        | |j                               ||<   > |S )Ns   [a-z0-9_]{2,12}\.cns\0)refinditerr8   r3   r<   )r"   r'   stringsmatchr   s        r-   find_cns_stringsrB   K   sV     G7= 7(EKKM2>"36GBK7 Nr/   c                V    | |v r| dd||     S d| cxk  rdk  rn | dS | ddS | dS )N08xz -> r     ` z -> ptr?r1   )valuer@   s     r-   format_dwordrG   T   sT    D 011U(j(C[ H%%C[r/   c                    t        j                  d|       ryt        j                  d|       ry| j                  d      s| j                  d      ryy)	Nzmap_[a-z][123]\.cnstilesetzmap\d+_\d+[a-z]\.cnsmapcara_face_spriteother)r>   	fullmatch
startswith)r   s    r-   classify_cnsrQ   \   sC    	||*D1	||+T2w4??7#;r/   c                6    t        j                  d| |      d   S )Nr   r   )r   r   )r"   r7   s     r-   dword_atrS   f   s    dC033r/   c           
        t        ||      }|y g }t        d||dz  z
        }||dz  z  }t        t        |       ||dz   dz  z         }t	        ||d      D ]{  }	|	dz   t        |       kD  r nht        ||	      }
|
%t        | |	      }|
||	|k(  d}||v r||   |d<   t        ||         |d<   nd|cxk  rdk  rn nd	|d
<   |j                  |       } |D cg c]  }|d   |kD  sd|v s| }}||||D cg c]  }|d   |d   d c}|D cg c]  }|j                  d      dk(  r|d   d d   c}dS c c}w c c}w c c}w )Nr   r
   r   )r   rF   isTargetcnskindr   rE   Tpointerr   )r   rW   rI   )
fileOffsetr   values	nearbyCnsnearbyTilesets)	r8   r!   minr;   r   rS   rQ   r   get)r"   r'   r@   hitcontexthit_var[   aligned_baser4   r)   r   rF   itemafters                 r-   collect_referencerf   j   s    (C(F~Fq#!+,LL1$$L
c#hw{a//
0C\3* 7SX(C(:c"5cSjAG!%.DK'7DL5.J."DOd %NdT
V(;TNENNSTdtE{DLAT 
xx9, K

 
 O
 U
s   D9'D9,D99D>
#Ec           	        |j                         D cg c](  \  }}|j                         |j                         v s'|* }}}|st        d|      g }|D ]  }	t        j                  d|	      }
g }d}	 | j                  |
|      }|dk  rn|j                  |       |dz   }/g }|D ]%  }t        | ||||      }||j                  |       ' |j                  ||	   |	|d        |S c c}}w )Nzno CNS string matching r   r   r   )r   r   
references)itemslowerr   r   packr:   r   rf   )r"   r'   r@   targetra   r   r   
target_vasrecords	target_vapatternstartssearchr`   refsrefs                   r-   collect_recordsru      s    &-]]_WT$**,8V"WJW26*=>>G 
	++dI.((7F+CQwMM#1WF   	!C#C7CICC 	! 		*"	
!
. N9 Xs
   (C-C-c                4   t        | ||||      }|D ]  }t        |d    d|d   ddt        |d          d       |d   D ]S  }t        d|d	   d
d|d   d       |d   D ]0  }|d   rdnd}	t        d|	 d|d   ddt        |d   |              2 U  y )Nr   z @ va=0xr   rD   z: rh   z pointer reference(s)z  ref file=0xrZ   06xz va=0xr[   rU   * z   0xrF   )ru   printr;   rG   )
r"   r'   r@   rl   ra   rn   recordrt   rd   marks
             r-   dump_recordsr~      s     c8WfgFG 	^f~hvd|C&86,'())>@	
 ,' 	^CM#l"3C!8s4yoNOH ^":.sCD6DJs#32l4=RY6Z5[\]^	^	^r/   c                 b   t        j                  t              } | j                  dt        t	        d             | j                  ddd       | j                  d	t
        d
d       | j                  ddd       | j                         }|j                  j                         }t        |      }t        ||      }|j                  rCt        t        j                  t        ||||j                  |j                         dd             y t#        ||||j                  |j                          y )N)descriptionz--exezHwanse2.exe)typedefaultz
--containsTzCNS filename substring)requiredhelpz	--contextr   z"dwords before/after each reference)r   r   r   z--json
store_truez write structured records as JSON)actionr   Fr   )ensure_asciiindent)argparseArgumentParser__doc__add_argumentr   int
parse_argsr"   
read_bytesr.   rB   jsonr{   dumpsru   containsra   r~   )parserargsr"   r'   r@   s        r-   mainr      s    $$9F
dD4GH
t:RS
#q?cd
<^_D
((


CS!HsH-GyyJJXwt||T"	
 	S(GT]]DLLIr/   __main__)r"   bytesreturn
list[dict])r'   r   r   r   r   
int | None)r'   r   r7   r   r   r   )r"   r   r7   r   r   str)r"   r   r'   r   r   dict[int, str])rF   r   r@   r   r   r   )r   r   r   r   )r"   r   r7   r   r   r   )r"   r   r'   r   r@   r   r`   r   ra   r   r   zdict | None)r"   r   r'   r   r@   r   rl   r   ra   r   r   r   )r"   r   r'   r   r@   r   rl   r   ra   r   r   None)r   r   )r   
__future__r   r   r   r>   r   pathlibr   r    r.   r5   r8   r<   rB   rG   rQ   rS   rf   ru   r~   r   __name__r1   r/   r-   <module>r      s'   #   	   
864)	)) ) 
	)
 ) )X#	## # 	#
 # #L^	^^ ^ 	^
 ^ 
^(J. zF r/   