
    UHjI                    4   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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mZmZ  ee      j                         j2                  d   Zedz  Zd	Zd
ZdZdZdZ dZ!dZ"dZ#g dZ$g dZ%dddddddddgZ&d+dZ'd+dZ(d+dZ)d,dZ*d-dZ+d.dZ,d/dZ-d0d Z.d1d!Z/d2d3d"Z0d4d#Z1d5d$Z2d4d%Z3d6d&Z4d6d'Z5efd7d(Z6d8d)Z7e8d*k(  r e7        yy)9zOMap the current gate offsets through possible selection-buffer base candidates.    )annotationsN)Path)Any)
CHARACTERSITEM_FIELDSSAVE_BLOCKSSCENE_POSITION_X_OFFSETSCENE_POSITION_Y_OFFSETSCENE_SELECTOR_GROUP_OFFSETSCENE_SELECTOR_SLOT_OFFSET   outmap1_01amap2_02diY ivE iPwE       )z#save-runtime-gate-byte-route-samplezparty-slot-branch-state-indexzruntime-pointer-mode-proofzcontrol-path-gate-base-proof)zHcurrent selector 2:0 save/runtime sample proving save-runtime gate byteszTparty-slot byte mapping that yields a valid branch-state index instead of stat byteszBruntime pointer-mode proof selecting the correct context+0xa8 basezScontrol-path proof that the resolved gate base enables current frontier fallthroughz*out/save_selector_gate_offset_sources.jsonzEcurrent gate offsets and inherited/runtime gate-source classification)pathdescriptionz-out/save_selector_selection_buffer_bases.jsonzEcandidate context+0xa8 base modes and static address reference checksztools/parse_savedata.pyzLsave-block and field-offset schema used for loader-aware byte classificationc                    d| dS )N0x08x values    I/home/exedev/hwanse/tools/summarize_save_selector_gate_base_candidates.pyhex32r   ?       c{    c                    d| dS )Nr   04xr   r   s    r   hex16r!   C   r   r   c                    d| dS )Nr   02xr   r   s    r   hex8r$   G   r   r   c                p    | j                         s|S t        j                  | j                  d            S )Nutf-8encoding)existsjsonloads	read_text)r   fallbacks     r   	load_jsonr.   K   s*    ;;=::dnngn677r   c                    || cxk  r||z   k  sy  y d}|dk(  r
| |k(  rdnd}n|dk(  rd| |z
   }||t        |      ||dS )Nz
whole-byte   zlow-bytez	high-byte   zbyte-fieldfieldOffsetfieldOffsetHex	fieldSizebyteRole)r!   )offsetstartsizename	byte_roles        r   offset_labelr=   Q   sl    V*edl* +Iqy"(E/J{		FUN+,	, r   c                    t         ddft        ddft        ddft        ddfdg}|D ]  \  }}}t	        | |||      }|s|c S  t
        D ]!  \  }}}t	        | |dd| d	| d
      }|s|c S  t        D ]  }|d   }	d|d   fd|d   d   fd|d   d   fg}
d|d   fd|d   fd|d   fd|d   ffD ]-  \  }|
j                  fd|j                         D               / |
D ]   \  }}t	        | |d|	 d|       }|s|c c S  |d   j                         D ]4  \  }}|d   }t        |d         }t	        | |||	 d| d      }|s0|c c S   t        D ]5  }|d    }|| cxk  r||d!   z   k  sn d"|d    d#| t        |       dd$d%c S  y )&Nr   zscene selector groupzscene selector slotr0   ztile/camera X candidateztile/camera Y candidate)   r1   moneyzitem count:  ()r;   levelzexperience current
experiencecurrentzexperience maximummaximumHPhpMPmpz	base stat	baseStatszenhance statenhanceStatsc              3  6   K   | ]  \  }} d | |f  yw) Nr   ).0r;   field_offset
group_names      r   	<genexpr>z#known_save_field.<locals>.<genexpr>   s'      pL^DR^ZL$"8,!G ps   rN   skillsbase
valueBasesz skill packed bytes
saveOffsetr:   zunknown within z save blockzunmapped-byter2   )r   r   r	   r
   r=   r   r   extenditemslenr   r!   )r8   basicsr9   r:   r;   labelkeykorean	character	char_namescalar_fieldsgroup
block_nameblockrT   slotsrQ   s                   @r   known_save_fieldre   b   sa   	$a)?@	#Q(=>	 !%>?	 !%>?F $ tTVUD$7L * VUVUAfXRuA/NOL   	f%	i()!9\#:9#EF!9\#:9#EF
 9T?#9T?#)K01Y~67	"
 	qJ    pbgbmbmbo pp	q ) 	KD% i[$3HIE	 "+8!4!:!:!< 	J=Dl+,E u1ZLPc6deE	%0  	l#F2UU6]22*5=/E%"'-+ 	 r   c                    t         D ]H  }|d   }||d   z   }|| cxk  r|k  sn | |z
  }|d   |z   }|t        |      |d   t        |      dc S  y )N	runtimeVar:   rV   r;   )rV   saveOffsetHexruntimeSaveBlockruntimeBlockOffsetHex)r   r!   )runtime_addressrc   runtime_startruntime_endblock_offsetsave_offsets         r   runtime_to_save_offsetrp      sx     k*#eFm3O9k9*]:L-<K)!&{!3$)&M).|)<	  r   c                6   g }| j                  d      xs g D ]~  }|j                  d      }t        |t              s.|j                  d      }t        |t              sFt        |d      }|j	                  |j                  d      |t        |      d        |S )NgatesselectionBufferOffsetselectionBufferOffsetHex   	gateVaHex)rv   r8   	offsetHex)get
isinstanceintstrappendr$   )gate_sourcesrowsrowr8   
offset_hexs        r   gate_offsetsr      s    D(.B 01&#&!;<Jj#.R(F-f
 	 Kr   c                   i }| j                  d      xs g D ]  }|j                  d      }|j                  d      }t        |t              r(t        |t              r|j                  dd      |||f<   ]|j                  d      }|j                  d      }t        |t              s|dk7  st        |t              s|j                  dd      |t        |d	      t        |d	      f<    |S )
NgateOffsetAddressChecksaddressr8   directDwordRefCountr   
addressHexrw   -ru   )rx   ry   rz   r{   )selection_buffer_basesresultr   r   r8   address_hexr   s          r   address_ref_countsr      s    F%))*CDJ 	d'')$"gs#
63(?(+0Eq(IFGV$%ggl+WW[)
k3'K3,>:jZ]C^BE''J_abBcFCR(#j"*=>?	d Mr   c                \   ||d   z   }|rt        |      nd }|xs i j                  d      }|t        |      nd }| ||d   |d   |d   t        |      t        |      ||xs i j                  d      |xs i j                  d      ||xs i j                  d      |t         dt
         d	S )
Nr8   rV   rv   rw   ri   rj   rh   ..)baseKindslotrv   
gateOffsetgateOffsetHexruntimeBaseHexruntimeAddressHex
saveBackedri   rj   rV   rh   
knownFieldexpectedIndexRange)rp   rx   re   r   EXPECTED_INDEX_MINEXPECTED_INDEX_MAX)	kindruntime_basesave_backedgater   rk   mappedro   r3   s	            r   save_offset_rowr      s    "T(^3O8C#O4F<R$$\2K-8-D[)$E+&8nk*-"?3!#\r../AB"(,B!3!34K!L! ,B++O<!3 4B7I6JK r   c                    | d   dk(  r:| j                  d      xs i j                  d      xs d}d|v sd|v sd|v sd	|v ry
y| d   dk(  ry| d   dk(  ryy)Nr   party slot baser   r3    rI   statrC   rD   implausible-stat-byte-indexz#party-slot-byte-needs-runtime-proofsave/runtime block basezsave-backed-unmapped-byteglobal selection bufferzunresolved-global-bufferzunresolved-pointer-table-baserx   r   r3   s     r   classify_base_rowr      sw    
:++&,"11':@b5=FeOw%/?<SXCX04
:33*
:33)*r   c                   t        |       }t        |      }g }|D ]  }|j                  t        dt        d|             |j                  t        dt
        d|             t        d      D ]/  }|j                  t        dt        |t        z  z   d||             1 |j                  dd |d	   |d
   |d   dddd d d d t         dt         d        |D ]T  }|j                  dd      dk7  r*t        |d   d      }|j                  ||d   fd      |d<   nd|d<   t        |      |d<   V |D cg c]  }|d   dk(  r| }	}|D cg c]
  }|d   s	| }
}d}i dt        dt        d|D cg c]  }|d   	 c}dt        t        gdt!        t              dt#        |      dt#        |	      dt#        |
      d dd!dd"dd#t$        d$t&        d%t(        d&t#        t(              d'd(d)|d*|iS c c}w c c}w c c}w )+Nr   Fr   Tr1   r   )r   zruntime object pointer tablerv   r8   rw   z.dword[0x0059db30+i*4] or dword[0x0059dd70+i*4]r   r   )r   r   rv   r   r   r   r   r   saveBaseHexrV   rh   r   r   r   ru   r   r   r   classificationr   a  Mapping the gate offsets through known context+0xa8 base candidates weakens the party-slot-base path: for party slots, 0xe8/0xea land on later character MP/stat bytes such as Rinshan and Smashu MP fields, not on documented selector-index bytes. Since opcode 0x11 expects a branch-state slot index in the 0..11 range, those stat-byte mappings are not promotion evidence. Loader-aware save/runtime mapping also matters here: 0x004576d8+0xe8/0xea falls into the second loaded save block after the six-byte runtime gap, so those bytes map to save offsets 0x00e2/0x00e4 rather than linear offsets 0x00e8/0x00ea. The viable sources remain an unresolved global/save-runtime buffer or object pointer table mode, so control-flow proof is still blocked.sourcetargetgateOffsetsHexr   partySlotStrideHexcandidateCountpartySlotStatByteCandidateCountdirectRefCandidateCountruntimePointerModeStillRequired
proofFoundgateBaseCandidateProofFoundfailedGateBaseCandidateGateIdsmissingEvidenceevidenceRefsevidenceRefCountpromotionStatusblockedbaseCandidates
conclusion)r   r   r|   r   GLOBAL_SELECTION_BUFFERSAVE_RUNTIME_BLOCK_BASErangePARTY_SLOT_RUNTIME_BASEPARTY_SLOT_STRIDEr   r   rx   rz   r   SOURCETARGETr!   rY   #FAILED_GATE_BASE_CANDIDATE_GATE_IDS$GATE_BASE_CANDIDATE_MISSING_EVIDENCE!GATE_BASE_CANDIDATE_EVIDENCE_REFS)r}   r   rr   refsr~   r   r   r   rk   party_stat_rowsdirect_ref_rowsr   s               r   build_summaryr      s   &E45DD O$=?VX]_cdeO$=?VX\^bcd!H 		DKK%+d5F.FF		 	6k*x.!+.N!$!%7$8;M:N"O
 	8  777&,3!#&9":B?O)-?CDU2VXY)ZC%&)*C%& 1# 67  $AA 	O  '+Isc2G.HsIOI	 && 	?4,? 	13EF	
 	e$56 	#d) 	*3+? 	"3#7 	*4 	e 	&u 	)*M 	? 	9 	C AB  	9!" 	$#$ 	j%  J @s   1G8
G=G=/Hc                F    | j                  d      }|sy|d    d|d    dS )Nr   r   r3   rA   r7   rB   r   r   s     r   
field_textr   7  s4    GGL!EGnRj 12!44r   c                   ddd| d    d| d    ddj                  d	 | d
   D               d| d   d    d| d   d    d| d    d| d    d| d    d| d    dd| d    dd| d    dd| d   dddg}|j                  d | d    D               |j                  g d!       |j                  d" | d#   D               |j                  g d$       |j                  d% | d&   D               |j                  g d'       | d(   D ]  }|j                  d)      d*nt        |d)         }|j	                  d+|d,    d-| d.|d/    d0|d1    d2|j                  d3      xs d* d-|j                  d4      rd|d4   z   dz   nd* d-t        |       d-|d5    d-|d6    d7        |j	                  d       d8j                  |      S )9Nz$# Save Selector Gate Base Candidatesr   z	- route: r   z -> r   z- gate offsets: , c              3  (   K   | ]
  }d | d   yw)`Nr   rO   items     r   rR   zmarkdown.<locals>.<genexpr>C  s     $WTqa[$W   r   z"- expected selection index range: r   r   r   r   z#- party-slot stat-byte candidates: r   z- direct ref candidates: r   z'- runtime pointer mode still required: r   z- proofFound: `r   r   z - gateBaseCandidateProofFound: `r   z- promotion status: `r   r   z## Failed Gatesc              3  (   K   | ]
  }d | d  yw)- `r   Nr   r   s     r   rR   zmarkdown.<locals>.<genexpr>Q  s     U43tfAUr   r   )r   z## Missing Evidencer   c              3  &   K   | ]	  }d |   yw)z- Nr   r   s     r   rR   zmarkdown.<locals>.<genexpr>W  s     D2dVDs   r   )r   z## Evidence Refsr   c              3  8   K   | ]  }d |d    d|d      yw)r   r   z`: r   Nr   rO   r   s     r   rR   zmarkdown.<locals>.<genexpr>]  s/       c&k]#c-012s   r   )r   zu| base | slot | gate | runtime address | save block | save offset | known save field | direct refs | classification |z9| --- | ---: | --- | --- | --- | --- | --- | ---: | --- |r   r   r   z| r   z | z | `r   z` | `r   z` | ri   rh   r   r   z |
)joinrW   rx   r{   r|   r   )summarylinesr   r   s       r   markdownr   >  sw   .

GH%&d78+<*=>
499$WWEU=V$WWXY
,W5I-J1-M,NbQXYmQnopQqPrs
-g6W.X-YZ
#G,E$F#GH
1':[2\1]^
',/02
*73P+Q*RRST
(9 :;1=


!E$ 
LLU73S+TUU	LL  
 
LLD1B)CDD	LL  
 
LL >*  
LL  
 '( 
ggfo-s3s6{3CZ!TF$s?/C.D E'()ww)*1c2#3677?3KsS))C/QTUUX#s3'<#=">c#FVBWAXXZ	\	

 
LL99Ur   c                   dj                  d | d   D              }dj                  d | d   D              }dj                  d | d   D              }g }| d   D ]  }|j                  d	      d
nt        |d	         }|j                  d      rdt        j                  |d          dnd
}|j                  dt        j                  |d          d| dt        j                  |d          dt        j                  |d          dt        j                  |j                  d      xs d
       d| dt        j                  t        |             d|d    dt        j                  |d          d         dj                  g dddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.| d/    d0| d1    d2t        j                  d3j                  | d4                d5| d6   d7    d8| d6   d9    d:| d;    d<| d=    d>d?t        j                  | d@          dAdBdC| dDdEdC| dDdFdC| dDdG|dHdIdJd      S )KNr   c              3  N   K   | ]  }d t        j                  |       d  yw)
<li><code>z</code></li>Nhtmlescaper   s     r   rR   zhtml_page.<locals>.<genexpr>t  s+       T[[&'|4   #%r   c              3  N   K   | ]  }d t        j                  |       d  yw)z<li></li>Nr   r   s     r   rR   zhtml_page.<locals>.<genexpr>x  s+       t{{4 !'r   r   c              3     K   | ]9  }d t        j                  |d          dt        j                  |d          d ; yw)r   r   z	</code>: r   r   Nr   r   s     r   rR   zhtml_page.<locals>.<genexpr>|  sE       T[[V-.iCDV8W7XX]^s   ?Ar   r   r   r   rh   z<code>z</code>z<tr><td>r   z	</td><td>z</td><td><code>r   z</code></td><td><code>r   z</code></td><td>ri   r   r   z
</td></tr>r   z<!doctype html>z<html lang="en">z<head>z  <meta charset="utf-8">zF  <meta name="viewport" content="width=device-width, initial-scale=1">z3  <title>Save Selector Gate Base Candidates</title>z	  <style>zg    :root { color-scheme: dark; font-family: system-ui, sans-serif; background: #101010; color: #eee; }z&    body { margin: 0; padding: 24px; }z,    h1 { margin: 0 0 8px; font-size: 24px; }z<    p { max-width: 1120px; color: #bbb; line-height: 1.45; }z[    table { width: 100%; border-collapse: collapse; margin: 12px 0 20px; font-size: 13px; }zi    th, td { border-bottom: 1px solid #303030; padding: 7px 8px; text-align: left; vertical-align: top; }zF    th { position: sticky; top: 0; background: #181818; color: #ddd; }z    code { color: #d7f0ff; }z
  </style>z</head>z<body>z-  <h1>Save Selector Gate Base Candidates</h1>z  <p>route <code>r   z -&gt; r   z</code>; gate offsets r   r   z!; expected selection index range r   r   r   r   z; proofFound <code>r   z </code>; promotion status <code>r   z</code></p>z  <p>r   z</p>z  <h2>Failed Gates</h2>z  <ul>z</ul>z  <h2>Missing Evidence</h2>z  <h2>Evidence Refs</h2>z  <table><thead><tr><th>base</th><th>slot</th><th>gate</th><th>runtime address</th><th>save block</th><th>save offset</th><th>known save field</th><th>direct refs</th><th>classification</th></tr></thead><tbody>z  </tbody></table>z</body>z</html>)r   rx   r{   r   r   r|   r   )r   failed_gatesmissing_evidenceevidence_refsr~   r   r   ro   s           r   	html_pager   s  s   77 <= L ww -.  GG >* M D'( 
ggfo-s3s6{3CMPWWUdMet{{3+?@AIkn;;s:/0 1& S%9:; <S)<%=>? @;;sww'9:AcBC D-  ;;z#/0 1,-. /;;s#3456 7
	

  99 %%% 	% 	#	%
 	Q% 	>% 	% 	r% 	1% 	7% 	G% 	f% 	t% 	Q% 	'%  	!%" 	#%$ 	%%& 	8'%( GH-.ggh6G5H IDIIg6F.G$HIJ K**12F*G*J)K2gVjNklmNnMo p#L122RSZ[lSmRnny	{)%0 GL123481%2 	"3%4 e$5%6 	&7%8 !"%(9%: 	#;%< u%=%> 	]?%@ 
A%B 	C%D 	E%F 	G%H 	I% % %r   c                    |j                  dd       |dz  j                  t        j                  | dd      dz   d	       |d
z  j                  t	        |       d	       y )NT)parentsexist_okz'save_selector_gate_base_candidates.jsonFr0   )ensure_asciiindentr   r&   r'   'save_selector_gate_base_candidates.html)mkdir
write_textr*   dumpsr   )r   out_dirs     r   write_outputsr     se    MM$M.88DD

7q9D@ E  88DDYwEWbiDjr   c                    t        j                  t              } | j                  dt        t
        dz         | j                  dt        t
        dz         | j                  dt        t
               | j                         }t        t        |j                  i       t        |j                  i             }t        ||j                         t        d|j                  d	z          y )
N)r   z--gate-offset-sourcesz&save_selector_gate_offset_sources.json)typedefaultz--selection-buffer-basesz)save_selector_selection_buffer_bases.jsonz	--out-dirz,wrote save selector gate base candidates -> r   )argparseArgumentParser__doc__add_argumentr   OUT
parse_argsr   r.   gate_offset_sourcesr   r   r   print)parserargsr   s      r   mainr    s    $$9F
/dCJrDrs
2sMxGxy
$<D$**B/$--r2G '4<<(	8Hq9q8r
str   __main__)r   rz   returnr{   )r   r   r-   r   r  r   )
r8   rz   r9   rz   r:   rz   r;   r{   r  dict | None)r8   rz   r  r  )rk   rz   r  r  )r}   dictr  z
list[dict])r   r	  r  zdict[tuple[int, int], int])N)r   r{   r   rz   r   boolr   r	  r   z
int | Noner  r	  )r   r	  r  r{   )r}   r	  r   r	  r  r	  )r   r	  r  r{   )r   r	  r   r   r  None)r  r  )9r   
__future__r   r   r   r*   syspathlibr   typingr   r   insertr{   __file__resolveparentparse_savedatar   r   r   r	   r
   r   r   r   ROOTr   r   r   r   r   r   r   r   r   r   r   r   r   r!   r$   r.   r=   re   rp   r   r   r   r   r   r   r   r   r   r  __name__r   r   r   <module>r     sb   U "    
   3tH~--/667 8   H~''*
Ul		$ $ $    ' #( $ =^
 @^
 *e% ! 8"2j ".
+IX52jCL 25 ku zF r   