From 63c52d14b1ff10c22f64115c68371b27e0d4b7ce Mon Sep 17 00:00:00 2001 From: Colin Xu <127581131+ColinXHL@users.noreply.github.com> Date: Sun, 19 Oct 2025 20:27:19 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9EOCR=E8=AF=86=E5=88=AB?= =?UTF-8?q?=E6=A0=91=E8=84=82=E8=84=9A=E6=9C=AC=20(#2171)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 新增OCR识别树脂脚本 * update dev game metrics --- .../assets/icon/condensed_resin.png | Bin 0 -> 3020 bytes .../assets/icon/fragile_resin.png | Bin 0 -> 9342 bytes .../OCRCountResin/assets/icon/num0_white.png | Bin 0 -> 918 bytes repo/js/OCRCountResin/assets/icon/num1.png | Bin 0 -> 350 bytes .../OCRCountResin/assets/icon/num1_white.png | Bin 0 -> 1915 bytes repo/js/OCRCountResin/assets/icon/num2.png | Bin 0 -> 707 bytes .../OCRCountResin/assets/icon/num2_white.png | Bin 0 -> 2169 bytes repo/js/OCRCountResin/assets/icon/num3.png | Bin 0 -> 755 bytes .../OCRCountResin/assets/icon/num3_white.png | Bin 0 -> 2200 bytes repo/js/OCRCountResin/assets/icon/num4.png | Bin 0 -> 682 bytes .../OCRCountResin/assets/icon/num4_white.png | Bin 0 -> 2119 bytes .../OCRCountResin/assets/icon/num5_white.png | Bin 0 -> 2328 bytes .../assets/icon/original_resin.png | Bin 0 -> 2235 bytes .../assets/icon/replenish_resin_button.png | Bin 0 -> 1203 bytes .../assets/icon/transient_resin.png | Bin 0 -> 9563 bytes repo/js/OCRCountResin/main.js | 483 ++++++++++++++++++ repo/js/OCRCountResin/manifest.json | 14 + repo/js/OCRCountResin/settings.json | 7 + 18 files changed, 504 insertions(+) create mode 100644 repo/js/OCRCountResin/assets/icon/condensed_resin.png create mode 100644 repo/js/OCRCountResin/assets/icon/fragile_resin.png create mode 100644 repo/js/OCRCountResin/assets/icon/num0_white.png create mode 100644 repo/js/OCRCountResin/assets/icon/num1.png create mode 100644 repo/js/OCRCountResin/assets/icon/num1_white.png create mode 100644 repo/js/OCRCountResin/assets/icon/num2.png create mode 100644 repo/js/OCRCountResin/assets/icon/num2_white.png create mode 100644 repo/js/OCRCountResin/assets/icon/num3.png create mode 100644 repo/js/OCRCountResin/assets/icon/num3_white.png create mode 100644 repo/js/OCRCountResin/assets/icon/num4.png create mode 100644 repo/js/OCRCountResin/assets/icon/num4_white.png create mode 100644 repo/js/OCRCountResin/assets/icon/num5_white.png create mode 100644 repo/js/OCRCountResin/assets/icon/original_resin.png create mode 100644 repo/js/OCRCountResin/assets/icon/replenish_resin_button.png create mode 100644 repo/js/OCRCountResin/assets/icon/transient_resin.png create mode 100644 repo/js/OCRCountResin/main.js create mode 100644 repo/js/OCRCountResin/manifest.json create mode 100644 repo/js/OCRCountResin/settings.json diff --git a/repo/js/OCRCountResin/assets/icon/condensed_resin.png b/repo/js/OCRCountResin/assets/icon/condensed_resin.png new file mode 100644 index 0000000000000000000000000000000000000000..32aab864bb8fbf82d2fba9e47adb57b3557a4483 GIT binary patch literal 3020 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 snS>ca09eB}&I3vI0 zdnvCwP{{>P7sn8diODrTzwj~V9cVfB|M&O%%g^8c_rJX;@_|tOzdyAfejHuLoPK}b z|0$DY6i%FHp8D_a@AG@z&zH+uRDV6ze1HFck1p=N|Jkpe`}FPaa#87T@w=+tpP#?K z{{LU+?a>qFo9kUMwLRzV=O)vAdBzNh${jmPOhop?oY}B@&cun0Q>U^%60?y@R(bRO zpzhfdCr+F@*A+W!Zf|H%Aipt-TWxTvfM!?5B&gTDp6H=ujV9qZ8Z-k)2K+Y@@jE)&D<+-%IjWtJF3#U1UjIFM_^1*y~N_!1c58EmuPbZ z>7ed|aiyWxfUUiaA<)|a1evIM7~hc=5kV4K5}r;bR8vfQi43oZ#`ZKt;2DV3;U#Kp zgLpXDjQcbL;w}eI0*3S8Zo$Fu9PQ+{<1Ebx6z!oHCrL9R&5JHKp1lZU&5)yFi+^X< z7W(oMam&(0ib|zYj+E1(88M0x1jNBoEK4E;Y4)g=lqOZPBFEr|CNLD;QZyB}8KsEU zWqAptblHWZo~KpKY?x5MsI;V0jDxma$^nDH)uG8`9&K86-N;H-?@fu#P>&9&7HDc+ z27qja2zJ(-&WC7^NYl&EAgTjd zvZS?vHCc)FtOXhjiUHNMBo)Ab-%B7-4n>hg2GYETV?ZT`rmy z&?@c9=tBGb8tAgaXYXGwTUi5$BOf7=g*>2L9+u>x+ex|s#~?OD&bfFH;i2G((o&AC z$xzVAkrFFeZB;U2lsq(a$}Aw=9Ltk5&qYZo>gGs33L;Jy4Oze;9vO&H%}7e9PL!k+ zgOsku2>c&4J}sdcK}|+6cdncd_~vYEdgC8L%dX zQu3cwNZm@jDRr+deQg!;KT6Mr6~rYq22qEl2-_LT?nTQr0fmk&#{E*5T00-qg(E_Y-eE@&3a6iyvUz#i{e-r_Rp)co% zx*9$u3x~@6>rR}X{;q4`dR?VaHvQo|UR63RMn3*!r20ytoW4?h?r3uTCHGx}qt6fY z@n;^7xxzdCugaPV$p_tXB5l)2JxJnx?S?5U-zkJiVi zDRO=quln>c?8sPZ@tGdD?S=cwOVqE&7WbX(ukv3gas2tyW21)*M=Pzi$MD|3_G+`;h%52P-g!g19gr5H)`7t{0&KmhK&FK literal 0 HcmV?d00001 diff --git a/repo/js/OCRCountResin/assets/icon/num2.png b/repo/js/OCRCountResin/assets/icon/num2.png new file mode 100644 index 0000000000000000000000000000000000000000..665cb20a3b04306255c94be751257ea2b58994ef GIT binary patch literal 707 zcmV;!0zCbRP)eh4bY)!^&fNe202g#cSael$WpW@x zZ*6U5Zgc=sV{&C>ZgXgFboX@)M*si!jayF>Q51#uK69APbez^gX~C3> zO}N-9cmWiRL5*P4_~LK%#bAOLB64Z52w0|orA-lwLhUfqDd(IyJ~SF1Fn&)vS>Ij@ z_jYoKs3?>Wiin5^08;u=N+Gx}gak=dRYwE>1c2r#a~ux|8bK|fwjmOrQc9qN5Z{+S zj_cXALb+0Hcugc|=vr?gc6s<>yfcCbR7zR>e*9wg!=|;znCMN!7~>oH;`&yxR5^V7 zV7x2VP94`<%I23=x3qvdbMHoKu+M9<<<_Pw&zbr?H%~7~_fV=+xv$ z$TWoSBf|XRy4&zJtn0xE}p!JM)Vhw$nfa#<{gq-YM<_fCR~y zV4SB0`)J*E%lp+q&wb$yM^__ZslK+ p5!42f3H(;sJ~RFs@?Qf0egTBL5#IK6ykP(U002ovPDHLkV1mESK(PP- literal 0 HcmV?d00001 diff --git a/repo/js/OCRCountResin/assets/icon/num2_white.png b/repo/js/OCRCountResin/assets/icon/num2_white.png new file mode 100644 index 0000000000000000000000000000000000000000..00b861825b61199e56141c0334ad7853d68d1d15 GIT binary patch literal 2169 zcmcImeN5D596prc$3Qo6iXgEm=y2HU^}gGAcyNb6;=u)&Fx{r5eGe*k*R$<$oQtS) zaXQVWQ)h@q(D^X|aWgvc6P?b@sOZc9Weyg%1ml? zom_6dly93wF}zDjvwQ(imbyF;tx!y#QR<0w&z1#t{_^JQcIwffZnGPi@AOez_WqK zdj$rhmH@XDH)xDyf_pt)!P)OA%izEXTo5KgVMNfBr-+w$v50?$AHn6IHy+9&09xXO zT%LChCdxj@f~cX_NJ1XxW_h1DRaO+(0IakGOsHC=)?q3VBZyprq;y(JZAerZDV1sf zYJ+va(h~h*V4me1{uhDTY*dC@lxQ~tGOQ*Pic)eMOX>Amto(PjDRFrg47zd8W=5> zp&Y#6qG6qIF1irl9(N&%{G-OgJ9)vzvoPkGC+9OP7Q4VZI44{Xv(r+Lj8u!BAoY4o ztt8~KhcckM>6{32><=8I9I!Aja&kz2by74V9|{x7$khN?G%(FQCCo48&;YHk2td;3 zRLKBL?#Ov!&%A^t4!B3<%)=`U6x|D*IkSeYW)T?k-@#ZlQAT<%2!Nx}b} zul}_s`qm&EHbZ$B?85LP*vEkzQVXz4>&W<33dIm*hBY}i;Wfs7MPxmfcwuGs+%G?YDcqF^A%Jx8EwyU;fjVF)GDWUF`ZtyB?-}TG8{pV#(v4cTWg= zzo^FT6Vf@q_jK>D(aXlvFX?No^Uuwmlj$s=E~i&^nolk1dwg+=rtSLK@>5Oc#P-|A zU(qzxw*7u%LgkLy(FYnXwD`|A#hSh5g_X&B%Dcm_bx&^QuMfG~_qca%PTTe>FnspN zl=ZtVbaiz`p856c=b0;-K4~3~&kO0ElvFk?p>}EY(CrT!PHfuuo@H7`NBIwz-&}a> zsPE3QiIpolj*Y3KK*VzL-nibb&Y?FBR~>PLnR1HXH%!Xgr-(`OVT(0&SJtkqi`?B{ zUUSU!SK=A@mJhSe&IUEbr1% z?B|k{ny^RSYacg0RJNLX=kJU*vpaThl~u0r@U_*=wU%#hKGpMvN(c`A;B)G_suhV=hZLXYy>Oz z99%!9$`G}oF=FqZCcU#IY|UF=z5e)q)>a2gkIo*JHa{YK!JH{MyDx=InVeoX(I~|u z+UV5SsHw#h)Ydcc71ZKUTQ@AF$8O$mJ2GliYVxb*@y&)qS>;Kqx9!~9{@v20#LT3!yJMqT73b_16T9A_F!|>oBQ?`n Jn==1{zX9^x2>t*7 literal 0 HcmV?d00001 diff --git a/repo/js/OCRCountResin/assets/icon/num3.png b/repo/js/OCRCountResin/assets/icon/num3.png new file mode 100644 index 0000000000000000000000000000000000000000..f2112a529db95aefdfef82c34f8390a84e84cb99 GIT binary patch literal 755 zcmVeh4bY)!^&fNe202g#cSael$WpW@x zZ*6U5Zgc=sV{&C>ZgXgFboX@)M*si+kIPpQQ2>X3_c0HKH-q>9Gg1=E zM_R{Ct@_jLbkxkFi7yfzQ3f4A2YHHc?`@H%MVtE8-{Sko&2>?TkrYBfQ9>Exlrci6 zQc?;r5<{gF0pXM~LMXUW3d7;B)p-#h3fUAmEziTG#=!cd0wdEXRbT&KX z)$YBzU#`^ZjpqDph69Ml!mnqi(-U@jD#;iH5Db`xp#cy=NTmS60W2+KXEG@(V8)^$ z07|Kga<%H+OC={$c03w-{65zJ5D8zpQE+zw=vO&4=n-(*Kf9k5QeTN?MN=0dABq>lNmP+op^2ufDrP|Z+UgU+k2E!YMh5df$>x# l61Etn0G_>nLjOks@C$JOFOgD-UZDU0002ovPDHLkV1jkBRS5t9 literal 0 HcmV?d00001 diff --git a/repo/js/OCRCountResin/assets/icon/num3_white.png b/repo/js/OCRCountResin/assets/icon/num3_white.png new file mode 100644 index 0000000000000000000000000000000000000000..3895ed6137dce761162117493ed4dfe57fc35714 GIT binary patch literal 2200 zcmcImdrT8|953bJV}j9{%;}uxxnvr4y+_--_Ot@Fh)pO~K=CoA*Sl*upuKu`*aD)! zWU{#VhcTeg~y9i#q?=C3p9`-|zGL zd_UjE@0)wunU)eec+_BxMiXnFZc7L6q2L}dPz#HgUZ|y$}Ljq@kvy2YR z;kWWR!t^4E&nQaEWQ+1xGY2P3fhGrOK;Y#S1`2xfeKH-iz`eXQ7^~AL4D~{kJPVwp z8ieLJoRC$Nc*v+D5f(R?Aj+)6Ndu-QUxNq?H=~#d#q|h=(-=t`DJXQoz?#Il>2%w) zkS*|KfpZkaPoroc5YPqmI#KeVxY-Oi2$UcYfI#FzpTYzYpFF;w!N$w1B={9U^g${k z;}Q!L3k;O@x#0DOX?=1iOdw!rkny9q4pUv~2Ra;2hkCtXw5%jA23A6PA4@D}7W#QK zotMP|iRF_Q^FC#KzcG#t@AVf*`MsWUEXwEeUI3GUFg$F^pCc-woFhKLkMMHX8$WH8 zct#PWOi|45Pn5Ht1tNgg(1a|($B6-XqN*sgfwwUVZ-EJnFd~>4!SPJoOdE`}5sSx6 zG=}v-9iR?4Mq!=}EOLUo@L8Y^2W|Js3gcsWyUhXvQ9423XoKENVMdc4F|Z_s7$}1a zak*Fq!A(X3Zou^}k|29^f&Dg-El|U!?(ZvGPGkW`I6^dm8{DMPU`9wiMj|HM03L2V zg%EmPZ@@T;(^IZ~wi%KDP7ag*D66W91B`AXWn_7?8!_=bhG2}!L*YDPrg#c>v2HzS zVqu75X}2hO8BiyJm+|nZ-{*m$f7DpTd{J_U9EiF8(RsVo>XbyckPjB*^pvTPJ=sd) zW|Bk*9j=x=kOADCF32Fqg`tC#!7mDp@&%~3I%$Sg4}}G0)oS25I5aIhCd|*~P#7KK%3P_-BJ zB?bL=zIxXl>0AA9&bn3l1&WTXOB@M+KvwKeM|tb;r2e(#nX+F)bye@6!EW8X6ytynJEj zf|IlB7I)mP`0Ts^t2&%>eb24dGAU7d_>HxD-PTjphi{*6pS0{@PxN5ziEa98>zhs6 za$Y2sH@s3kxg^Gwn$j3mvkp4`byrM#LU5$(=-sM4rD@s?+4JTW-|8u;X==XnLhY4| z%V|-yC(gK+KIj}Y;qKkGtQum?jeVbxHI1cH6VdxoZ;ji2v&wL{W&gdzi8a-=9l2|A z3$ocU4?%p+jKXYd6t~0}QN#v07v&y^e*$1zFzo7GK`}|7Ob1HkG zaI3s-pXbQ0TN|q*tuez#t#Qu#N{NP}*3OEw-nerO{r2bXp6(S};%7%39k4PtV{{6& zvA%xS?+>nY9PApZeN$U|?dmDsZ?yLd_Yk+rk3E>Heh4bY)!^&fNe202g#cSael$WpW@x zZ*6U5Zgc=sV{&C>ZgXgFboX@)M*si<97#k$R5*=|lihC;K@`RB9cJ0(n?e-|EyZBJ zf^Ac6tT7sW@-Ozu7oSWM5<_hXt}a*#Qb3A8iwL_jdwp08w4(Mr%)`n3%{}*K2Af|$ z6M-#-l!AZ|(Z#rnb3{f&M79)`v?Ty=mx7Ej#yBEF1VqKfIT0WN03xDkiNWBfX_}g* z2K*kz(D4C)1AtRCIRF5_G_8VOIecHVEO9Tj^!&+oBpiU>;xJFO#>LxrM+Ln?L{i$1 zcGhMY_9xKo5Aw%G>9h_&jziZAZZei7K9y=8jcO?9*EDtF68(#*H!pH|-RITzw(q+Y z4gf?q+FYNfcR9$Pl)AmE7f*K`;6K@fkVd(FTs&P}j_qbM3g-w2^E747Tb*29cPsqh z;pRffKih=n&U1M+JSvpWTb=C2>Pqsi5K`Lqgt19TTL>woJ)K8NyHu&?@_Mg7C>quF z_dWo$JN@Bk?DT*A=Fso+B;$*Z_ckL70S*8^hNIK7Mx)u0wyhgg-ME&%*B|6hN&t}E zOmD5FCXAx+Ogj1M`0kcdYW&OMqsVGu!eE2>+WWxQUEF=PzGA%7ws4F{*2oc~50X{tLB zi|+5N2YlXHA6xa(T%gtNR%)$CIIz65=<%qxVu*+c7@PAH{+bPO`UP+37llIYxhA{c Q-v9sr07*qoM6N<$f^Wnwp8x;= literal 0 HcmV?d00001 diff --git a/repo/js/OCRCountResin/assets/icon/num4_white.png b/repo/js/OCRCountResin/assets/icon/num4_white.png new file mode 100644 index 0000000000000000000000000000000000000000..160fcaab4bc139449da91042ab9bd45c97a9fad6 GIT binary patch literal 2119 zcmcIleNfY894-SHqSeh0uIRCg(cQsZnxt)F8>xUTLX{#y1^n1ynxv4UZDJBAFcF8| z)SbF-b=CQ;6VIueAM?OXcGGhcb?S6DogZ_0PCeu{^^_A~Z=iJEP96U&cS+v7@AE#t z=lAjcvN$I@LmN9RR-@5q9hvrA@E!#2p)oIj=b^f!{ovJC%$z1`Gy@K)cf`k|2MpI} z`uxee3Y9`<7R3lYJ|$#zDyy6d>?%3Jq2GyndOgu)f%dSe1LvuM< zD3cg2y`1waBYTXoOn9$YCV9I&Wf_$7ay|f)fiOI5N-Pl+K`s%V;YWBm?2Sm-B#u@D z$t4KhopR^_FxtQ$M7y)V82~p%GB_w`@74Q6&Sz~ju2%aOco<)p%KnR;E07VnGiQ&G$FVL za}z9qlbDC?VVf-R;N;NWCs|chEMO!#5F^6iK}Zj4MhM!3A#M&=c^J3HX!4jzRTaxn z9zpWapiX!nUCg1PzZi!8QDYOlg5(rf5Od>`^A4LWM-n`|7c9uR8RH>Gx{bswB#9XG zxLWo=25>i%mqCszLkB63n;jZ?d8n&8DVk9ag%xJhYT$rl-P8P2!rVKDy7vc4I6(TG zD(QyFf=3C^5|>sCQu3cwh(1faOqV}jdhaUaf0P~yD^o)Ii#gC?QCM{bReMo)QqX_r zt849vzSRQ<%}^bNyD<0&_i@e-s3p*)Z!bT!UZaUP)HiWHRs&zNI zf>>%Iq3ioTn8m*k3-_>xn|Bs(B z)DgGoc$8z{M=uYHueo~dW@n~m>MA@k_-ZQ4dK$dfgRLoZ+aEm`Xd8ZJW^~r&$f?Oy z?NKEcj?eh2v*U5UQ~Ay3w(W@24&Cot)EE=9ELpnu@W|w~+e%mE@4Pr~i*|?Z2Qq=F z9(+4}((; zQZV2BRA0RZ3%vEa_G&VE@MPqR@3yzM?cUgMx$#U~;-U?o*S%qD9%3C;rbTX?DC)oD z*Osy6kD?aXR_|heIhs<_F{?RxcIg!UY|DkfTI-u@3JRkieD}fT7@yXe5Uk%Kw$Ag) z_xqn~XoYg_T&pu$t3NEg6)e3qecm4r7w3r?{__VCba?8wwHsnH3W}oFoy{vg7V-AO znyZaXD|Sl#nsnP+F79hNm%izh1>`!PgSQO+?AS_D)(@+nbN#jCO9K+dQPpvoyEcD) zwO7u6Q~fAEf7-&;s}_IRa_W}+XHIR>Ez@0j$F+CK$@hwKM!j@1e#ZR$!NeGicSN7~5eKGcslR$hdbWMX I_*u1o1MybwO#lD@ literal 0 HcmV?d00001 diff --git a/repo/js/OCRCountResin/assets/icon/num5_white.png b/repo/js/OCRCountResin/assets/icon/num5_white.png new file mode 100644 index 0000000000000000000000000000000000000000..fb48f36b90e8e3522b6f6089d6d1a527bf5a5a45 GIT binary patch literal 2328 zcmcIme^3-v96wMINz_qC5+-I_X3E69{c(GHcN@pgLtymq1XQdP_IBUF4tKZL?ZN>m zpp}FDV5%7#wK33iQjD5JYswT$OY=v9K8Jf^Ba}bIkO*mo1NgYOzEWxmP0}}Y5Fq>C!usN2w zfn4y(j20`3hsAN9&!_e2w34?7Cru`ZLE#jI!3a#Qa4TFn=9c4z5G+9Ey`o1EB{!lX za(1ayF{6;FzXX>j2)ax9SN8oYb1TKgz!&q{VpNCEJ z0#1>Zb9!W2&! zS%UC~TA>dFPT@uuED55cVl<&vE1Tt(70%6rEQ=Y1q_m4S?Zj!a-mRAnh1MK{UI`NMe+Z z1QZDvo@Ru>Dk0heuLxHT=NyizvJxPo-A?nAgV13HBX7q@f~GK|fu}K^&~XIAIP?a< zp~%C$X_8a&S|tIhs~g^*m6m4nN)FKpU&uKbsYq6O8bg{G2BWkjiU>UGki0Gq8clR@ zMF97>i&Wb~8jxV7D8o6f2rQ&r@N%H#6p=x9vK+523Ny;9ZUC?_f4BGunMYTUf4r|4 zK+q9f;t!K0hvMVBAf*US$$z>Ke;j$4D;t^m=p6DtQV+<=7jy0+0C!j%Rg1yZy~sZ) z_`m1tp)rQcl>%+A&ZZoYA(bl%3X=F}FFPnoPuq0{OlPF^n4YE$n9;^QAqNA&u5$o}#vD33hv{?>!bA~vOi$??dI~NN14j)TJy?yO6h1Qh!N_5I z@{km8qgR{369zs6&nV!AvU%YNl-m1tg+>!{E6b9SH|r#CJ4>UnWb&+6qUzV}JeO2) zZ(@Aq{a?jJ%bMR`H7>6-Z$;;Z=BR;dny$c(_|FLZ48D;*$i)N|gRDDu)RsX#` zTesBJ;E^Y87@U{G=(}wnJ)7JUzWsK0q}lU(xUKK?c}wh5Pfgffx8SFQ>W-rqE*4lnRL(1f(^*s!k z+m(wU^9{*~t!>HXBaQp+ADk4M7_qQ_;9y2!4ySoW+wh=fMd8@5D#pj{tg{|B`UX%- zU;p^YtCknlW@o;-HF0u8Y^EP5HKgFWw`ZpIwNCL@e7|HRj2U z$!+f(c`be3;%};YX2h;O&^zX>xUgF3_EX0Dce)Bb`Ml?s?~k>wVa(HFEYZ8mx^HxD yQhLsADrl)nncn}`oyqH`)SL}%3jN^;%S=s4K|9GbEIp%syJV$jTRu%KT>UphYBtUQ literal 0 HcmV?d00001 diff --git a/repo/js/OCRCountResin/assets/icon/original_resin.png b/repo/js/OCRCountResin/assets/icon/original_resin.png new file mode 100644 index 0000000000000000000000000000000000000000..7aea4d586f4c82233a8f7eec0fec617026ced687 GIT binary patch literal 2235 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 RaDe~-002ovPDHLkV1i|-KIZ@c literal 0 HcmV?d00001 diff --git a/repo/js/OCRCountResin/assets/icon/transient_resin.png b/repo/js/OCRCountResin/assets/icon/transient_resin.png new file mode 100644 index 0000000000000000000000000000000000000000..f9ed5fd05cd67ea92c00660bbcdc418b47212422 GIT binary patch literal 9563 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 FV1hoZVi5oU literal 0 HcmV?d00001 diff --git a/repo/js/OCRCountResin/main.js b/repo/js/OCRCountResin/main.js new file mode 100644 index 000000000..44c1252f4 --- /dev/null +++ b/repo/js/OCRCountResin/main.js @@ -0,0 +1,483 @@ +/** + * OCR树脂数量统计脚本 + * 功能:自动识别并统计原神中各种树脂的数量 + * 支持:原粹树脂、浓缩树脂、须臾树脂、脆弱树脂 + */ + +// ==================== 常量定义 ==================== + +// 树脂图标识别对象 +const RESIN_ICONS = { + ORIGINAL: RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/icon/original_resin.png")), + CONDENSED: RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/icon/condensed_resin.png")), + FRAGILE: RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/icon/fragile_resin.png")), + TRANSIENT: RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/icon/transient_resin.png")), + REPLENISH_BUTTON: RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/icon/replenish_resin_button.png")) +}; + +// 普通数字识别对象(1-4) +const NUMBER_ICONS = [ + { ro: RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/icon/num1.png")), value: 1 }, + { ro: RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/icon/num2.png")), value: 2 }, + { ro: RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/icon/num3.png")), value: 3 }, + { ro: RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/icon/num4.png")), value: 4 } +]; + +// 白色数字识别对象(0-5,用于浓缩树脂) +const WHITE_NUMBER_ICONS = [ + { ro: RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/icon/num0_white.png")), value: 0 }, + { ro: RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/icon/num1_white.png")), value: 1 }, + { ro: RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/icon/num2_white.png")), value: 2 }, + { ro: RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/icon/num3_white.png")), value: 3 }, + { ro: RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/icon/num4_white.png")), value: 4 }, + { ro: RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/icon/num5_white.png")), value: 5 } +]; + +// 配置常量 +const CONFIG = { + RECOGNITION_TIMEOUT: 2000, // 图像识别超时时间(毫秒) + SLEEP_INTERVAL: 500, // 循环间隔时间(毫秒) + UI_DELAY: 1500, // UI操作延迟时间(毫秒) + MAP_ZOOM_LEVEL: 6, // 地图缩放级别 + + // 点击坐标 + COORDINATES: { + MAP_SWITCH: { x: 1840, y: 1020 }, // 地图右下角切换按钮 + MONDSTADT: { x: 1420, y: 180 }, // 蒙德选择按钮 + AVOID_SELECTION: { x: 1090, y: 450 } // 避免选中效果的点击位置 + }, + + // OCR识别区域配置 + OCR_REGIONS: { + ORIGINAL_RESIN: { width: 200, height: 40 }, + CONDENSED_RESIN: { width: 90, height: 40 }, + OTHER_RESIN: { width: 0, height: 60 } // width会根据图标宽度动态设置 + } +}; + +// 树脂数量存储 +let resinCounts = { + original: 0, // 原粹树脂数量 + condensed: 0, // 浓缩树脂数量 + transient: 0, // 须臾树脂数量 + fragile: 0 // 脆弱树脂数量 +}; + +// ==================== 工具函数 ==================== + +/** + * 通用图像识别函数 + * @param {Object} recognitionObject - 识别对象 + * @param {number} timeout - 超时时间(毫秒) + * @returns {Object|null} 识别结果或null + */ +async function recognizeImage(recognitionObject, timeout = CONFIG.RECOGNITION_TIMEOUT) { + const startTime = Date.now(); + + while (Date.now() - startTime < timeout) { + try { + // 直接链式调用,不保存gameRegion变量,避免内存管理问题 + const imageResult = captureGameRegion().find(recognitionObject); + if (imageResult.isExist()) { + return imageResult; + } + } catch (error) { + log.error(`识别图像时发生异常: ${error.message}`); + } + await sleep(CONFIG.SLEEP_INTERVAL); + } + + log.warn(`经过多次尝试,仍然无法识别图像`); + return null; +} + +/** + * 在指定区域内识别数字图片 + * @param {Object} ocrRegion - OCR识别区域 + * @param {Array} numberIcons - 数字图标数组 + * @param {string} logPrefix - 日志前缀 + * @returns {number|null} 识别到的数字或null + */ +async function recognizeNumberInRegion(ocrRegion, numberIcons, logPrefix = "") { + try { + for (const numObj of numberIcons) { + try { + // 直接链式调用,避免内存管理问题 + const numResult = captureGameRegion().find(numObj.ro); + if (numResult && isPointInRegion(numResult, ocrRegion)) { + log.info(`${logPrefix}通过图片识别到数字: ${numObj.value}`); + return numObj.value; + } + } catch (error) { + log.error(`${logPrefix}识别数字图片时发生异常: ${error.message}`); + } + } + } catch (error) { + log.error(`${logPrefix}识别数字区域时发生异常: ${error.message}`); + } + return null; +} + +/** + * 普通数字图片识别函数 + * @param {Object} ocrRegion - OCR识别区域 + * @returns {number|null} 识别到的数字或null + */ +async function recognizeNumberByImage(ocrRegion) { + return await recognizeNumberInRegion(ocrRegion, NUMBER_ICONS, "普通数字 - "); +} + +/** + * 白色数字图片识别函数(用于浓缩树脂) + * @param {Object} ocrRegion - OCR识别区域 + * @returns {number|null} 识别到的数字或null + */ +async function recognizeWhiteNumberByImage(ocrRegion) { + return await recognizeNumberInRegion(ocrRegion, WHITE_NUMBER_ICONS, "白色数字 - "); +} + +/** + * 检查点是否在指定区域内 + * @param {Object} point - 点坐标 {x, y} + * @param {Object} region - 区域 {x, y, width, height} + * @returns {boolean} 是否在区域内 + */ +function isPointInRegion(point, region) { + return point.x >= region.x && + point.x <= region.x + region.width && + point.y >= region.y && + point.y <= region.y + region.height; +} + +/** + * 通过OCR识别数字 + * @param {Object} ocrRegion - OCR识别区域 + * @param {RegExp} pattern - 匹配模式 + * @returns {number|null} 识别到的数字或null + */ +async function recognizeNumberByOCR(ocrRegion, pattern) { + try { + // 直接链式调用,避免内存管理问题 + const ocrRo = RecognitionObject.ocr(ocrRegion.x, ocrRegion.y, ocrRegion.width, ocrRegion.height); + const resList = captureGameRegion().findMulti(ocrRo); + + if (!resList || resList.length === 0) { + log.warn("OCR未识别到任何文本"); + return null; + } + + for (const res of resList) { + if (!res || !res.text) { + continue; + } + + const numberMatch = res.text.match(pattern); + if (numberMatch) { + const number = parseInt(numberMatch[1] || numberMatch[0]); + if (!isNaN(number)) { + return number; + } + } + } + } catch (error) { + log.error(`OCR识别时发生异常: ${error.message}`); + } + return null; +} + +// ==================== 树脂计数函数 ==================== + +/** + * 统计原粹树脂数量 + * @returns {number} 原粹树脂数量 + */ +async function countOriginalResin() { + const originalResin = await recognizeImage(RESIN_ICONS.ORIGINAL); + if (!originalResin) { + log.warn(`未找到原粹树脂图标`); + return 0; + } + + const ocrRegion = { + x: originalResin.x, + y: originalResin.y, + width: CONFIG.OCR_REGIONS.ORIGINAL_RESIN.width, + height: CONFIG.OCR_REGIONS.ORIGINAL_RESIN.height + }; + + // 匹配 xxx/200 格式中的第一个数字(1-3位) + const count = await recognizeNumberByOCR(ocrRegion, /(\d{1,3})\/\d+/); + if (count !== null) { + log.info(`原粹树脂数量: ${count}`); + return count; + } + + log.warn(`未能识别原粹树脂数量`); + return 0; +} + +/** + * 统计浓缩树脂数量 + * @returns {number} 浓缩树脂数量 + */ +async function countCondensedResin() { + const condensedResin = await recognizeImage(RESIN_ICONS.CONDENSED); + if (!condensedResin) { + log.warn(`未找到浓缩树脂图标`); + return 0; + } + + const ocrRegion = { + x: condensedResin.x, + y: condensedResin.y, + width: CONFIG.OCR_REGIONS.CONDENSED_RESIN.width, + height: CONFIG.OCR_REGIONS.CONDENSED_RESIN.height + }; + + // 首先尝试OCR识别 + const ocrCount = await recognizeNumberByOCR(ocrRegion, /\d+/); + if (ocrCount !== null) { + log.info(`浓缩树脂数量: ${ocrCount}`); + return ocrCount; + } + + // OCR识别失败,尝试白色数字图片识别 + log.info(`OCR识别浓缩树脂失败,尝试白色数字图片识别`); + const imageCount = await recognizeWhiteNumberByImage(ocrRegion); + if (imageCount !== null) { + log.info(`浓缩树脂数量(白色数字图片识别): ${imageCount}`); + return imageCount; + } + + log.info(`白色数字图片识别识别浓缩树脂失败,尝试在说明界面获取`); + // 点击浓缩树脂打开说明界面统计 + condensedResin.click(); + await sleep(CONFIG.UI_DELAY); + let captureRegion = captureGameRegion(); + // OCR识别整个界面的文本 + let ocrRo = RecognitionObject.Ocr(0, 0, captureRegion.width, captureRegion.height); + let textList = captureRegion.findMulti(ocrRo); + captureRegion.dispose(); + for (const res of textList) { + if (res.text.includes("当前拥有")) { + const match = res.text.match(/当前拥有\s*([0-5ss])/); + if (match && match[1]) { + const count = parseInt(match[1]); + log.info(`浓缩树脂数量(说明界面): ${count}`); + keyPress("ESCAPE"); + await sleep(CONFIG.UI_DELAY); + return count; + } + } + } + + log.warn(`未能识别浓缩树脂数量`); + return 0; +} + +/** + * 统计须臾树脂数量 + * @returns {number} 须臾树脂数量 + */ +async function countTransientResin() { + const transientResin = await recognizeImage(RESIN_ICONS.TRANSIENT); + if (!transientResin) { + log.warn(`未找到须臾树脂图标`); + return 0; + } + + const ocrRegion = { + x: transientResin.x, + y: transientResin.y + transientResin.height, + width: transientResin.width, + height: CONFIG.OCR_REGIONS.OTHER_RESIN.height + }; + + return await countResinWithFallback(ocrRegion, "须臾树脂", recognizeNumberByImage); +} + +/** + * 统计脆弱树脂数量 + * @returns {number} 脆弱树脂数量 + */ +async function countFragileResin() { + const fragileResin = await recognizeImage(RESIN_ICONS.FRAGILE); + if (!fragileResin) { + log.warn(`未找到脆弱树脂图标`); + return 0; + } + + const ocrRegion = { + x: fragileResin.x, + y: fragileResin.y + fragileResin.height, + width: fragileResin.width, + height: CONFIG.OCR_REGIONS.OTHER_RESIN.height + }; + + return await countResinWithFallback(ocrRegion, "脆弱树脂", recognizeNumberByImage); +} + +/** + * 通用树脂计数函数(带图片识别回退) + * @param {Object} ocrRegion - OCR识别区域 + * @param {string} resinType - 树脂类型名称 + * @param {Function} fallbackFunction - 回退识别函数 + * @returns {number} 树脂数量 + */ +async function countResinWithFallback(ocrRegion, resinType, fallbackFunction) { + // 首先尝试OCR识别 + const ocrCount = await recognizeNumberByOCR(ocrRegion, /\d+/); + if (ocrCount !== null) { + log.info(`${resinType}数量: ${ocrCount}`); + return ocrCount; + } + + // OCR识别失败,尝试图片识别 + log.info(`OCR识别${resinType}失败,尝试图片识别`); + const imageCount = await fallbackFunction(ocrRegion); + if (imageCount !== null) { + log.info(`${resinType}数量(图片识别): ${imageCount}`); + return imageCount; + } + + log.warn(`未能识别${resinType}数量`); + return 0; +} + +// ==================== UI操作函数 ==================== + +/** + * 打开并设置地图界面 + */ +async function openMap() { + log.info("打开地图界面"); + keyPress("M"); + await sleep(CONFIG.UI_DELAY); + + // 切换到国家选择界面 + click(CONFIG.COORDINATES.MAP_SWITCH.x, CONFIG.COORDINATES.MAP_SWITCH.y); + await sleep(CONFIG.UI_DELAY); + + // 选择蒙德 + click(CONFIG.COORDINATES.MONDSTADT.x, CONFIG.COORDINATES.MONDSTADT.y); + await sleep(CONFIG.UI_DELAY); + + // 设置地图缩放级别,排除识别干扰 + await genshin.setBigMapZoomLevel(CONFIG.MAP_ZOOM_LEVEL); + log.info("地图界面设置完成"); +} + +/** + * 打开补充树脂界面 + */ +async function openReplenishResinUi() { + log.info("尝试打开补充树脂界面"); + const replenishResinButton = await recognizeImage(RESIN_ICONS.REPLENISH_BUTTON); + if (replenishResinButton) { + replenishResinButton.Click(); + log.info("成功打开补充树脂界面"); + } else { + log.warn("未找到补充树脂按钮"); + } +} + +/** + * 显示统计结果并发送通知 + * @param {Object} results - 统计结果对象 + */ +function displayResults(results) { + const resultText = `原粹:${results.original} 浓缩:${results.condensed} 须臾:${results.transient} 脆弱:${results.fragile}`; + + log.info(`============ 树脂统计结果 ============`); + log.info(`原粹树脂数量: ${results.original}`); + log.info(`浓缩树脂数量: ${results.condensed}`); + log.info(`须臾树脂数量: ${results.transient}`); + log.info(`脆弱树脂数量: ${results.fragile}`); + log.info(`====================================`); + + // 读取设置 + const notify = settings.notify || false; + + // 发送通知 + if (notify) { + notification.Send(`树脂统计: ${resultText}`); + log.info("已发送通知"); + } +} + +// ==================== 主要功能函数 ==================== + +/** + * 统计所有树脂数量的主函数 + * @returns {Object} 包含所有树脂数量的对象 + */ +async function countAllResin() { + try { + setGameMetrics(1920, 1080, 1); + log.info("开始统计树脂数量"); + + // 返回主界面 + await genshin.returnMainUi(); + await sleep(CONFIG.UI_DELAY); + + // 打开地图界面统计原粹/浓缩树脂 + await openMap(); + await sleep(CONFIG.UI_DELAY); + + log.info("开始统计地图界面中的树脂"); + resinCounts.original = await countOriginalResin(); + resinCounts.condensed = await countCondensedResin(); + + // 打开补充树脂界面统计须臾/脆弱树脂 + await openReplenishResinUi(); + await sleep(CONFIG.UI_DELAY); + + // 点击避免选中效果影响统计 + click(CONFIG.COORDINATES.AVOID_SELECTION.x, CONFIG.COORDINATES.AVOID_SELECTION.y); + await sleep(500); + + log.info("开始统计补充树脂界面中的树脂"); + resinCounts.transient = await countTransientResin(); + resinCounts.fragile = await countFragileResin(); + + // 显示结果 + displayResults(resinCounts); + + // 返回主界面 + await genshin.returnMainUi(); + await sleep(CONFIG.UI_DELAY); + + log.info("树脂统计完成"); + return { + originalResinCount: resinCounts.original, + condensedResinCount: resinCounts.condensed, + transientResinCount: resinCounts.transient, + fragileResinCount: resinCounts.fragile + }; + + } catch (error) { + log.error(`统计树脂数量时发生异常: ${error.message}`); + throw error; + } +} + +// ==================== 脚本入口 ==================== + +/** + * 脚本主入口函数 + */ +(async function main() { + try { + await countAllResin(); + } catch (error) { + log.error(`脚本执行失败: ${error.message}`); + log.error(`错误堆栈: ${error.stack}`); + } finally { + // 确保最终返回主界面 + try { + await genshin.returnMainUi(); + } catch (finalError) { + log.error(`返回主界面时发生异常: ${finalError.message}`); + } + } +})(); \ No newline at end of file diff --git a/repo/js/OCRCountResin/manifest.json b/repo/js/OCRCountResin/manifest.json new file mode 100644 index 000000000..f2401f736 --- /dev/null +++ b/repo/js/OCRCountResin/manifest.json @@ -0,0 +1,14 @@ +{ + "manifest_version": 1, + "name": "读取当前树脂", + "version": "1.0", + "description": "至少0.44.3版本。OCR识别原粹/浓缩/须臾/脆弱树脂数量,支持通知", + "authors": [ + { + "name": "羊汪汪", + "links": "https://github.com/ColinXHL" + } + ], + "settings_ui": "settings.json", + "main": "main.js" +} \ No newline at end of file diff --git a/repo/js/OCRCountResin/settings.json b/repo/js/OCRCountResin/settings.json new file mode 100644 index 000000000..ab0cc751e --- /dev/null +++ b/repo/js/OCRCountResin/settings.json @@ -0,0 +1,7 @@ +[ + { + "name": "notify", + "type": "checkbox", + "label": "发送通知" + } +]