
    UHjg                       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Zddlm	Z	 ej                  j                  d e e	e      j                         j                               ddlmZmZmZmZmZ  ej,                  d      Z ej,                  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  Extract probable map scene records from Hwanse2.exe.

The executable embeds repeated scene blocks as CNS resource-load entries followed
by a map CNS filename pointer, a small scene id, and zero. Older tooling looked
after the map record for tilesets, which actually picked up the next scene's
loads in route-adjacent streams. This manifest keeps both sides for audit, but
uses the resources before the map record when they are present.
    )annotationsN)Path)classify_cnsfind_cns_stringsoffset_to_varead_sectionsva_to_offsetzmap\d+_\d+[a-z]\.cns$zmap_[a-z][123]\.cns$c                6    t        j                  d| |      d   S )N<Ir   )structunpack_from)dataoffsets     3/home/exedev/hwanse/tools/extract_scene_manifest.pydword_atr   "   s    dD&1!44    c                4    d| cxk  xr dk  nc xr | dz  dv S )Nr   i      >   r       )values    r   looks_like_scene_idr   &   s     uxBUT\l$BBr   c           
     R   g }d }t        |      D ]  }||dz  z   }|dz   t        |       kD  r ||fS t        | |      }	|j                  |	      }
|
sAt        j                  |
      rt        ||      } ||fS |j                  |
d d |
t        |
      t        ||      d        ||fS )N   namefilenamekindrefVa)	rangelenr   getMAP_RE	fullmatchr   appendr   )r   sectionsstringsstart
max_dwords	resourcesnext_map_vaindexoffr   r   s              r   collect_afterr/   *   s     I"Kz" 
eai7SY  k!! s#{{5!D!&x5K k!! 	Sb	 $T*%h4		

& k!!r   c                    |dk  s|dz   t        |       kD  ry|j                  t        | |            }|rt        j	                  |      syt        t        | |dz               xr t        | |dz         dk(  S )Nr      Fr      )r"   r#   r   r$   r%   r   )r   r(   r.   r   s       r   looks_like_scene_record_atr3   I   sp    
Qw#(SY&;;xc*+Dv''-xcAg67XHT3QR7<SWX<XXr   c           
        t        d||dz  z
        }d }|}t        |dz
  |dz
  d      D ]"  }t        | ||      st        ||      }|dz   } n g }	t        ||d      D ]c  }t	        | |      }
|j                  |
      }|rt        j                  |      r8|	j                  |d d |t        |      t        ||      d       e |	|fS )Nr   r      r   r1   r   )
maxr!   r3   r   r   r#   r$   r%   r&   r   )r   r'   r(   r)   r*   lowerprevious_map_va
scan_startr.   r+   r   r   s               r   collect_beforer:   R   s     5:>)*E"&OJUQY	2. %dGS9*8S9OrJ	 IZ* 
s#{{5!v''-Sb	 $T*%h4		

 o%%r   c                   t        |       }t        | |      }|j                         D ci c]  \  }}t        j	                  |      s||  }}}g }t               }|j                         D ]  \  }	}
t        j                  d|	      }d}	 | j                  ||      }|dk  r8|dz   }|dz   t        |       kD  r0t        | |dz         }t        | |dz         }|dk7  st        |      s_t        | |||dz   |      \  }}t        | ||||      \  }}|D cg c]  }t        j	                  |d         r|d   ! }}|D cg c]  }t        j	                  |d         r|d   ! }}t        |      d	k\  r|}|}d
}n|}|}d}t        |      d	k  rt        ||      }||	|f|v r|j!                  |	|f       |j#                  i d|
d d d|
d|	dd|	dd|dd|dd|dd|dd|dd|dd|dz	  d|dz  d|d|d|D cg c]  }|d    d!k(  s|d    c}d"|d#||||d|dnd ||d|dnd d$        |j%                  d% &       |S c c}}w c c}w c c}w c c}w )'Nr   r   r5   r1   r   r2   r   r      	preceding	followingmapr   mapStringVamapStringVaHex0x08xrecordVarecordVaHexrecordFileOffsetrecordFileOffsetHex06xsceneId
sceneIdHex04x
sceneGroup	sceneSlotr   resourceSourcetilesetsspritesr   spriter+   precedingResources)followingResourcespreviousMapRefVapreviousMapRefVaHexnextMapRefVanextMapRefVaHexc                    | d   | d   fS )NrD   r?   r   )items    r   <lambda>z"extract_manifest.<locals>.<lambda>   s    4
#3T%["A r   )key)r   r   itemsr$   r%   setr   packfindr"   r   r   r/   r:   
TILESET_REr   addr&   sort)r   r*   r'   r(   var   map_string_vasrecordsseenmap_vamap_nameneedlesearchhitscene_idzerofollowing_resourcesnext_map_ref_vapreceding_resourcesprevious_map_ref_varY   preceding_tilesetsfollowing_tilesetsr+   rO   resource_sourceref_vas                              r   extract_manifestrv   s   s   T"HtX.G!(RF4D4DT4JDN  G!$D*002 OT6*))FF+CQw1WFRx#d)#cAg.HD#'*Dqy 3H =3@b40 8F84!4 0"''Z(89 V" " 0"''Z(89 V" "
 %&!+/	-"-/	-"-8}q !(C0F~&&!1T!9HHff%&NN8CR= "6 %6#,&7	
  "Rs|#4 ' *RCy> x !Bxn"5 !(a-  D %o  1: )-d6lh>VV $  %& )*='( +>(;M`MlR0CC/H+Irv$3ETE`OC+@'Afj1c O` LLALBNoD"
"F s#   I!	I!$I' $I,I1I1c                    t        j                  t              } | j                  dt        t	        d             | j                  dt        t	        d             | j                  dt
        d       | j                  d	d
d       | j                         }t        |j                  j                         |j                        }|j                  j                  j                  dd       |j                  j                  t        j                   |dd      dz   d       |D cg c]#  }|j"                  r|d   |j"                  k(  s"|% }}t%        dt'        |       d|j                          |d d D ]4  }t%        |d    d|d    d|d   dddj)                  |d                  6 t'        |      dkD  rt%        d!t'        |      dz
   d"       y y c c}w )#N)descriptionz--exezHwanse2.exe)typedefaultz--outzout/scene_manifest.jsonz--max-dwordsP   z--map
map_filterz#only print records for one map stem)desthelpT)parentsexist_okF),:)ensure_ascii
separators
zutf-8)encodingr?   zwrote z scene records -> d   rJ    z
 record=0xrD   rC   z
 tilesets=r   rO   z... z more)argparseArgumentParser__doc__add_argumentr   int
parse_argsrv   exe
read_bytesr*   outparentmkdir
write_textjsondumpsr|   printr"   join)parserargsmanifestrY   showns        r   mainr      s   $$9F
dD4GH
dD9R4ST
S"=
l9^_D 3 3 5tGHHHOO$6HH

8%JWZ^^ipq&`ddooePTP_P_A_T`E`	F3x=/!3DHH:
>?ds 
L!"!DK= 1Z(-ZjAQ8R7SU	


 5zCSZ#%&e,-  as   (#GG__main__)r   bytesr   r   returnr   )r   r   r   bool)r   r   r'   
list[dict]r(   dict[int, str]r)   r   r*   r   r   ztuple[list[dict], int | None])r   r   r(   r   r.   r   r   r   )r   r   r*   r   r   r   )r   None)!r   
__future__r   r   r   rer   syspathlibr   pathinsertstr__file__resolver   probe_exe_scene_tablesr   r   r   r   r	   compiler$   r`   r   r   r/   r3   r:   rv   r   __name__r   r   r   <module>r      s%   #   	  
  3tH~--/667 8  
,	-RZZ/0
5C"
"" " 	"
 " #">Y&
&& & 	&
 & #&BZz.. zF r   