From 632b06780f087c13d2b5a9cc200214c903d879bb Mon Sep 17 00:00:00 2001 From: sui-feng-cb <2518179942@qq.com> Date: Sun, 10 May 2026 04:32:59 +0800 Subject: [PATCH 1/8] Add: buy dorm food when oil overflow during commission receive --- assets/cn/commission/OIL_MAXED.png | Bin 0 -> 7000 bytes assets/cn/dorm/DORM_BUY_FOOD_CHECK.png | Bin 0 -> 6421 bytes assets/cn/dorm/DORM_BUY_FOOD_CONFIRM.png | Bin 0 -> 4238 bytes assets/cn/dorm/DORM_BUY_FOOD_ENTER.png | Bin 0 -> 3540 bytes assets/cn/dorm/FOOD_MINUS.png | Bin 0 -> 3686 bytes assets/cn/dorm/FOOD_PLUS.png | Bin 0 -> 3575 bytes assets/cn/dorm/OCR_DORM_BUY_FOOD_AMOUNT.png | Bin 0 -> 4194 bytes module/commission/assets.py | 1 + module/commission/commission.py | 10 ++ module/dorm/assets.py | 6 + module/dorm/dorm.py | 127 +++++++++++--------- 11 files changed, 88 insertions(+), 56 deletions(-) create mode 100644 assets/cn/commission/OIL_MAXED.png create mode 100644 assets/cn/dorm/DORM_BUY_FOOD_CHECK.png create mode 100644 assets/cn/dorm/DORM_BUY_FOOD_CONFIRM.png create mode 100644 assets/cn/dorm/DORM_BUY_FOOD_ENTER.png create mode 100644 assets/cn/dorm/FOOD_MINUS.png create mode 100644 assets/cn/dorm/FOOD_PLUS.png create mode 100644 assets/cn/dorm/OCR_DORM_BUY_FOOD_AMOUNT.png diff --git a/assets/cn/commission/OIL_MAXED.png b/assets/cn/commission/OIL_MAXED.png new file mode 100644 index 0000000000000000000000000000000000000000..9baa15826acd4d88fef6911d04deffe962d826c1 GIT binary patch literal 7000 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 literal 0 HcmV?d00001 diff --git a/assets/cn/dorm/DORM_BUY_FOOD_CHECK.png b/assets/cn/dorm/DORM_BUY_FOOD_CHECK.png new file mode 100644 index 0000000000000000000000000000000000000000..f01963a7d9b599cf4ae2b65f698b1f994de260f1 GIT binary patch literal 6421 zcmeH~`9G9<|Hm&WiqNrCvQ_6U9oddD%G#k2vL`W(7E5;7W*AydGD$-?($H`_ju;vf z8jNim!jZ-#jb+A`8OsbaW1qnc_tpKl|A6n$-$&Ok*Y(rqy57(C`}KOguQXR@J2{yn zG5`R`UADjI4gh<=$6cTI?gDQYv>YS=;PB|>i@$jy=-e^i=g{d}ZA&C-AB;>&FaWl?6nV4NIH&&L#as6Fpy)?U~2seN8G4fA#dVL$PbQ-P*ULR;d2aJh9)SL@aqN zE)hW@%|@X!xSXUlS=x%N)IDN2KRFlx}BQx{HphXkZ;DF$r8( z1K>a#V5qi)@QhSnfD&AsoIF2HXXR+4RyJlK;hRllaY0{S-_=Sl{Ea5a{{3=EV{t>_ z!3XuAyoXjqX9aMqYAA+OlukN2t^`=erFEi`GqF?uVBiTQTdhe{Hka^Y~ks%hd|cg)<}f)6S1ia^9$#0;`I^0<{b5qr@nfqTVdT#R#xH+ZF0hoKO+tR*HFU|)&=K;JdJv#ZNl zi#lr+%?P)!uvnR)gi3{wpz`;SG&=DbEMdBm(6ZTQ#!uOlGvJOjnPl1PUa$Gf2d{sl zF*YjdowsgkcmK}nUX~9YB9^kH1kZjrpQF@{?!DErHd8>gSQ+@n+z5Pa0(&+TO2iXH zn?XCG5|5vM=Ka1K7$C`<1$*OOnSn-IE|REtSWBa)PJj{S{K|~3PxC3PJ%6lLK)ZH- zO!IwuW$txg{j59}?(SA2HT=kJ$x^N-XTQl9z1V zUL#E0>()4y7PNcut+Qpt)ynGN+Io2M=0NW?g7XKa8$RE;D?6VH3mknYF)7J0!G`yU2NWI%OAV54Z7fgQ*w~O>LTlsf z?Cc6q7A`krPKz`(HCwrLj0`O+nC`(@YLQl96|5z3Yn_{ZQ14@4?U^IOFGtR_4HOQB z*q{`&&Kr8;opk-G!@gyAvYj@aiVd%lDb&{vWo23`Ni&}?f6_XMKEa#Fm@Gce*n)<`)*i4n``cPo*JBefGK7@L<)6)A;&vAG{ZwOIJxX zCL~_Pd77G|JL9wy1w{K5HTV2o#3!(e-cpBtiKqsV}C$EZRr3G5$gMH+G zyhQC%8Gk0SbiDsdIa_X&PHzm`Se{ucxBi^kia)FSiaZJ0;>KgE=C##fb~vL>!yIAw zA*wbS&Kp(rYUVZ0xBGzdK+YATy1KgBb@Gts=Vav{!CIF;%4v!3GDtC*9fRxqv1^6r zL1#-kin<`#c8O!+A6QpfT2?P8q~2c_e*T=Mqz%TCMMc>Fo4LWX%hU`n96>I#db%}{ zVdBlTn3+$co$W2zC)S5u_491ZGoL?CnmJRHu+(`7Y_pX(wXIfm@>EWbzgpx^*1}C+ z2vqP*fzJ@HW2}ouzWl81Obel@&SUs{0EzuTo=O|qPY>f1gxuc zsR-Tt*NPeW{Y{{sXcr=GkJJPp1-!B5gcU|4Sxkw%UrQkHD=MpWaveZhBnvwYBFN%( zQp_yG0Bh{nl71+8x`$kKw(6z|Ei`9IJ+sV%z4&j{Hd;t2tcA6wYSj>U-F@scu-Iy( zr*{pSFzt7LnjrI}U9_>nL@Ubmf|E>M!SY9As1|-=&NT%sOOa@WN?z(x+Y;~}EdDK> zsbLnsxyn{K?UiCKAKD^X?$vfFR9920q=n=yb-8&~wwA#Neul~F$D1MPSj3H8l5J-L zLGg$s&tVG(XmMQQA=b(U7=5^X!;6!|AsBMwOMv?17fz zYiBS{Pg#ZyV8yty!p*_@R$70<+f`kK6wBzj&u_HEbF6>tSJ>DhA*&5M>D;L>j(f7& zckgn#BXtTiSz55}Ac>MODmP6~xW5Ty0!NyW4SjaC~yF7foCx8;j3`p#w+KtrrEfOxS=tWyha5rz5*Y5NFuABV?RKFga=>GoxBulM!#Lb&WQ|24v<_nXSd$O{!97>IPRVSSwIj;`Z zuhCiIkJR!?EDQeb@zlxf`9L*TH@uy=c+wqbD=GQ?#ri63IkzzO{xu_2RT*2nCM(a` zQBur2dTT!Qg5JS&Vq!SAkvJcDed5a(#oIzqxH5OFH+gj8>HTvYjtm8=lbeb{DS!#6 zpBHpqa&&~Iq6p^%FMYxspngj(d�lhhwq0*u;u*?UN_Fx*hx9*WPECnR?*%uT*@Q6fu3im`Zi`QiH zIaNwN@~n}$`u+Ug4%GFU+npb`AH9V3;mn)KYx?bO&81pDjUaG?cXG*V>wE^MR*>@JRRCK|jG(jh_%ieGo=}zk?m4IT-IRa9Tnn zQE2nLO{UfLcTu;F|D+Hq&l?l06p2^cT9b*KkzaA1o2hd1HdgT1_>;_PsBhE%7MRv7z!1eSRbsLyG zEJ@TGkE(8o|2k}~3t?uoxp^uSnPHy?#DK!M?a>qm+)VB9mFX-qYH<5^TEa@B3syZi zG*Y3HVL?Wovr><|$VLR4=U!Hk?JS6FP2kdr#ldj?xP_(V_NOz{lvOT|7ZDtc5s#4b z?ksywccn6C9fV=~Q7&qooZ9BOv;SREG*lwhsiO_}2y@dzRc`ha@3$o-%1z#h8;|HgR2J7uNoR!5zYwXaO|t z6Svm}>*W1TeXj&T2K0*@dtS7n({Iw|)BKH;7g<-*Y;C2ar4=+xS62sIuIc2)%@2;% z+_DK}u#N_u*2`>Yur0P3bpJ z=rfh4gd^wYz47_^&3j*he`!Ci9|V37_({JI$9DS~0l-%wKFIH|DPqO=Ojcp&F4I4x;To5; zC$sws?hbZ|gQ5#?VR^otXb_`e?N(!4U^RB_I_RbK%YO@^R4Ey-n7Jz@UYC)3PlICY zg{WSf-*-I~BXXU92cIY;5P0kpsGfq%%wqF@I?o^F5newc3znX1+3Q!L8-_u^AYc$M z2p9wm0)J6}uD5ax27s}CFrny?MDh0fjp;{AA@DY)xWg__O=3dhD!Vv!297+=F$>pVTL~Ts0R>Z7&so(S#`NGpikZWyTI| zIMSmwKWYJcFy<`y7+?ZCtg-t!N{)Kxt3Z!_z)a;%OUvy@b=FrBcy_nbCobK(A|)mnF54D33`$kDPpC z%OrWIH}WOF-9O$3;yzgO)BNIa-ww*by>IwNE~5R4>^W|nzR&B>zR2tp$w%Y$?Et`b zraHHpn2UE?>9v7o_&tzfPIm_lE z)kt;ZFt|iu0irRxR4q$^(Kck|c%-Ar7nZ4ig}XMJmq*3HJBKQRX2;coQ%$@JjR|;i z#HoF3C6kS3kR2@XxgdlD{3F$|GX0iUcf>biL!~pPlcd|Uj=W8K0AnC2{FS8PbyKv$ z6H6$2^bJ`_7Ac4sF6a&|<)dVmFyq|4u0=oGt_Xb2cz}2G64~fmPGu2_W-(dqe>(** z+5z0*kr6j7&ii(lzJ0#C@+Me~?CHc2Y9^Xtu zvsI@;(&Z7pEzjiPVCJpsENsrH3<5#jVSUMRQkOAe5KCW#M( zv#-s+5Q<0tcLVu3(AyL!5rAkZmUQmg(HOgTviqWm$;>0ti-hiM^qh!tbJn#vIL*G8#o2J z!h*R^3{U+7Qz*0IM4Q!Bk8QjvK55W0Y8iHl?HY_{PPUC&Z2S^$414+K;L%!}?Lro_ z9XylBvOiwJ%{yxq3$=JJF1~bI+tiSHAgIKm%=-)pZp?krIl0{?l0JG&vK0Utb0uk| zpWUH4nF=GxtJ`0gL!%yX)HMw9J}BN#$djYgQX(zHn)xPx5L<4A3G)jzfiUXJMw~i; zF%K-=h(3ye&&uvQ{3nr%Bnotq9>NJufV-0l`O(@>`O2~D-Q2J`ZvfOBOPc|$a3$E( zZZG45>-)5>py3+KkQ3Z&Rm^$zcpg!TsyUi zVsnw|sv7Zsy%^)Rtwzrpo=f5HuY+uXRc@ibf{AA1kn!i>Uu(MlAh@JgD!gOSo2AbG zZ7L@sTljMN$FjV}eo_CqgVZeJaj}uLIg0IPtO`MZSuPaork`c4iUD zc&L21nW_;Ev#LYSyiwoOQa>odtur&cgR|~UPblz`l#_N9vhT-}k)byVgR##c#bEoD rmq(KFWV`?3A8*)h5cvNTAobFWg4p?pnrhtPFBSM4_ea)wp1$-aSokZp literal 0 HcmV?d00001 diff --git a/assets/cn/dorm/DORM_BUY_FOOD_ENTER.png b/assets/cn/dorm/DORM_BUY_FOOD_ENTER.png new file mode 100644 index 0000000000000000000000000000000000000000..6864988038039a501ee9de32c380f3cd03e420c3 GIT binary patch literal 3540 zcmeAS@N?(olHy`uVBq!ia0y~yUu%Ihd{{@Ik^ zKg^v&SE^B@W}$&ktXS4vww9N1HQe(!{0z2=ysH#aArV1NACpMPD9Z}_^UFMn^^5xw7T#=89* zKF>5_@=jgA!oYCm_2u_>QmXIX;dsBV?#({qt1CF)*W3L1a(daB``5xRCNWM62?5q0 z&z2T$ezA4_tiS4V=lJuE3eW!d<>ZGqlQ+(Kv;5DR@^ae#qgO%hXI?F-)67rFX7yAlJ^*h)S3td!dN{q>aO6~S|+ zbZXuB!vj_~&m#Blx9fM@ALK3K-xYh@e90>QeUS$nM1SmNV_^8aZ0C0V{gFplSrQl+ z`YL$#eNFZFucXVYV;;SLks(53YkTz5tl$5t^7Vap^+Z1}+4RCjh32iU<4clX}$so5ef(7?!G@yhPM zRc&eJl>cSFLOHtQx9_fwh0|X@85klSyxIBOdsFYidscJRC!4WPH`o)m zz4FJKjsKVT=^1;q@43f?>s~oVZV5a7`ntPixV5$T6u}5BzJp8*2@?fw z1us}#^YwX&L3nuTocg_y@@INx{W+|k8L}*xE7r!&PGaejngd3gSfv;mj;6&k)MQ*w z`0?Dg<&yq}EhRulMkpN7JMm1btoMQ4mt*T{jWizH^zPi)dpI$`H)vi-d9xU|0w^}4 zisn~4^ZniZ?ULL5vf?i~>g6Xbwv^|sZ}T%xQyM}Oz@fH8X7#)7J}1Awl^5Qo%$l-e_wL!nQr~_r$p3S%=lE~K zD@6ui+h*N5BfWY~a_7OyTYq!~cbtj)x9{h(TR*OxEYp7|K7CfmrcLc$4h(Dz38C`B z?XP_|-|zc%{_nlAPgni-KMlYC@9{n1T!w$&j-Naf-+$5lEq$`ws4b%*Fd71*AwY2m c{FwijRr?M9RJX^6^gxDry85}Sb4q9e09e?_LjV8( literal 0 HcmV?d00001 diff --git a/assets/cn/dorm/FOOD_MINUS.png b/assets/cn/dorm/FOOD_MINUS.png new file mode 100644 index 0000000000000000000000000000000000000000..a0b72706947e9cd96c071fad20e4cb824c65c390 GIT binary patch literal 3686 zcmeAS@N?(olHy`uVBq!ia0y~yUXJXx@*9j~_?z0!0*kCTi>pVK^$Nv5F(4@xwJX8N8iylc61_uV_fUUpIexC7s^38LTCG?VNK7V`5@4ug4QIo%i zfBH%3WsGxrUT@#=V}~IN1B(HJsDTXM^ZAVLzE-KXuSUhk+gn-v%B}x@X?4F_zVog+ z`5#3r;_tX2M$A}K8!GlLY58O`Df_o?e3m);@A|G(c>MRns4rr!CT(DYyclEN@v}EC zUApw{-MfnyFIGAxEmiTY%vu?>7@9J$&eYEb*{{35a z{5XBiZ~y)IapjiH>DuwE-3j32mBrzC^MK(orPEIH%(J()hP{s49qWDhe0W%0-N#2? zSBGD|x*;#?!Hnl^0^r2HxZyM#pJJz?2P8TzdR0XZS-mSCx=#6(JX7aXL(mSrdj$P9hDw6k~2^2Z6zPztt zo?l+Tv6!dtX}{azGY^*V+?6mlGpoCM*Ve*fMr=h<(WN4G2^y3RqehN~z-S1Jh5)TX c;6eOP=~|{Ed;P_`y+C$&y85}Sb4q9e0K2^gYXATM literal 0 HcmV?d00001 diff --git a/assets/cn/dorm/FOOD_PLUS.png b/assets/cn/dorm/FOOD_PLUS.png new file mode 100644 index 0000000000000000000000000000000000000000..df703a5143822ee50b9b62f178caac44f89eddc0 GIT binary patch literal 3575 zcmeAS@N?(olHy`uVBq!ia0y~yUGn7h!g^eQWm~$He8N)B3%%J{zieh5oy%yJ z-uP~HvHc+9qFmtO{giy2#X?u@MW zpQPe@x%%IRn>nlG8W?yOHW+=fncsi@{CR&rzpA})GRHla&Y5;}BLmNe^;}*I3>%)P z+<95DZTt5AzCI_8(sz5c|1xcG_;;0wK}Yj@ow-Jj+v3xwPuJ~_?@^!ZDcD>e!?%{1 zXM={-0R{&CW!GPe{`_`%x&P4}9*4ri!|mHr7{pxJB^VMUH{G^6@OkBp_4{Rc>guK~ z%goNzZQ0~%7%%eo@+>|Bu)CTVcbq#=%EMPU!~M~H`#PW5Ys+@u%`kbz6Z5*%dKJ3@ z12e-KKZbLke*RhAv;S(gY)SX@s+zJgGn;?O$;rwg&z-^}Ev3H9Um{{W$6C%eKiXMgSSCE)8DsWwD%`ReS7{g zQ?T*%zYh;G{l7AZIe{F$@>Bl2{k7}2F#e0eE60S;l&9P7|DG2q zSk~@RFp7U^yi7W zAOGs3%lT~$qmJ7ukPD3Z4}8?U|M*kEi(l>^&$=G05@ldAU^t+)>)lH?^M~7b_NBhs ztNZ*~W`&KMwlp}XvOa07zmzAMx41s%17Cl?J%9TtwhbEFrZ6z*c;Ec8H(9;lW9>he zz-g(~)xS6ERR8<4a}%RZ7a!12=AFts{l_2k%iDeV{rA(4)i=x%7#JlO9$cJxHtq1k z52q{cyenCDIdk(>p$0~l1cnCp7k6)O|9f!3?YGM^XQ_BDzRA^jQwr>cqJ7byV#>=` zw_bSsv7(}6%hs);q1*p$yZ!c6$%_X{DqvGTR{a0>_xk3|2RElH`bMt}6YOy2h@93c zu$xOFp>YlqFT)0&!V>QpbI+z#|Nbq#_ulF7^^XLkdfk>^_Po61hum@3KWB3p*&-BV zfi7t;EGjChsMxW2^JEpzdCy(VMglyp!LraQ)HQ5{<* z+9vK9;xcI`^y`vn$1-uPBH0v?ic+F+i9rxH{U`Q$_IdLD<(%Kn`MjRb=lpQ;QNjK? zTEJTnP~{JpB7W8REd-wMK{tdVI$n0Ha9mH zRmIh#%YXhk{X;%G#vXsazY^m`p_G^F<{~VOE8%#%1EARrx;^sy9E3vQRl-`CL+r4& z_MYvD`4lAWo3td}GYEoQ@kVCMG(q=w8X*OJM-vkhJJMFP-WO-Kgh46mbM;InlTKf2 zZ+}}?CAlT9=$=0}teKm~xJkhAuzkx^=P1qQlHJWkdMj!S^Xuji{47!nMB! z9%o60TT-DZ2A0duTxruI8{KIRgQ}ed6w;!Un@>j+US{i97`+-wk{EITWIz5Fm8yc8$LaKo1CF8h>JRW2B2#$ z)sJ(z-kzSO{fqec5%M&a(|-N0 zMASOp6JH^aQi4~Hz_-$lnw>x(?7d}(DwzyMEu9XlnSJ^4B~Ldrlyp-fk>z-%Zi$OC z)O~z42ap0m2z6-&jCt>+2G%Nwz`HUv;{Q>upnJd}Q=lK`zqMne1}9UnK% zbZq^JUfMlK8X4@dCvC{qgEj(cAR2RYh)%SdpVB1-^;)T{o}nvi%e&cXf=;LZQ$x>> z?es7JpT>GUKJIen%(2L;llW9rQ#+ohHZr*f3%X_4A<4p)QKHj(DX?gk1hia8khhpCsiMXpA9`AE4_cXDl zsqg!_xw$;^{kY_0JG}gjieNFZYqNfOSy-;R3aYXZsQCD4!G3FPZH6G}%eol*heI6s z#X3*1Ivr|wM{R-&3kyq~1N+7nH|~Aredi;C;{S~%ZgR6Eik?2(!i(3vc0{sVu zUnS6Jw9N6XA0QUeGV*Vq17$m4M^Roq_)$J5iYNpW0t$iuJAqZ4)P2c1a<{%f`soV+ Noc9YxH2Yq=`(Fx3CiMUS literal 0 HcmV?d00001 diff --git a/module/commission/assets.py b/module/commission/assets.py index d775a0927..32f9d3ba4 100644 --- a/module/commission/assets.py +++ b/module/commission/assets.py @@ -11,5 +11,6 @@ COMMISSION_SCROLL_AREA = Button(area={'cn': (1254, 77, 1261, 676), 'en': (1254, COMMISSION_START = Button(area={'cn': (1028, 322, 1156, 383), 'en': (1053, 333, 1134, 361), 'jp': (1033, 340, 1153, 376), 'tw': (1027, 326, 1157, 389)}, color={'cn': (229, 175, 113), 'en': (237, 199, 149), 'jp': (231, 184, 121), 'tw': (231, 180, 120)}, button={'cn': (1028, 322, 1156, 383), 'en': (1053, 333, 1134, 361), 'jp': (1033, 340, 1153, 376), 'tw': (1027, 326, 1157, 389)}, file={'cn': './assets/cn/commission/COMMISSION_START.png', 'en': './assets/en/commission/COMMISSION_START.png', 'jp': './assets/jp/commission/COMMISSION_START.png', 'tw': './assets/tw/commission/COMMISSION_START.png'}) COMMISSION_URGENT = Button(area={'cn': (35, 231, 68, 281), 'en': (28, 221, 76, 283), 'jp': (34, 266, 68, 279), 'tw': (35, 229, 69, 280)}, color={'cn': (215, 188, 124), 'en': (169, 138, 95), 'jp': (216, 190, 111), 'tw': (213, 186, 123)}, button={'cn': (35, 231, 68, 281), 'en': (28, 221, 76, 283), 'jp': (34, 266, 68, 279), 'tw': (35, 229, 69, 280)}, file={'cn': './assets/cn/commission/COMMISSION_URGENT.png', 'en': './assets/en/commission/COMMISSION_URGENT.png', 'jp': './assets/jp/commission/COMMISSION_URGENT.png', 'tw': './assets/tw/commission/COMMISSION_URGENT.png'}) EXP_INFO_S_REWARD = Button(area={'cn': (498, 140, 557, 154), 'en': (1138, 40, 1266, 145), 'jp': (498, 140, 557, 154), 'tw': (498, 140, 557, 154)}, color={'cn': (233, 241, 127), 'en': (89, 115, 159), 'jp': (233, 241, 127), 'tw': (233, 241, 127)}, button={'cn': (498, 140, 557, 154), 'en': (1138, 40, 1266, 145), 'jp': (498, 140, 557, 154), 'tw': (498, 140, 557, 154)}, file={'cn': './assets/cn/commission/EXP_INFO_S_REWARD.png', 'en': './assets/en/commission/EXP_INFO_S_REWARD.png', 'jp': './assets/jp/commission/EXP_INFO_S_REWARD.png', 'tw': './assets/tw/commission/EXP_INFO_S_REWARD.png'}) +OIL_MAXED = Button(area={'cn': (428, 310, 534, 335), 'en': (428, 310, 534, 335), 'jp': (428, 310, 534, 335), 'tw': (428, 310, 534, 335)}, color={'cn': (106, 103, 110), 'en': (106, 103, 110), 'jp': (106, 103, 110), 'tw': (106, 103, 110)}, button={'cn': (428, 310, 534, 335), 'en': (428, 310, 534, 335), 'jp': (428, 310, 534, 335), 'tw': (428, 310, 534, 335)}, file={'cn': './assets/cn/commission/OIL_MAXED.png', 'en': './assets/cn/commission/OIL_MAXED.png', 'jp': './assets/cn/commission/OIL_MAXED.png', 'tw': './assets/cn/commission/OIL_MAXED.png'}) REWARD_1 = Button(area={'cn': (383, 285, 503, 297), 'en': (403, 274, 504, 290), 'jp': (432, 273, 476, 294), 'tw': (383, 285, 503, 297)}, color={'cn': (238, 168, 81), 'en': (241, 198, 145), 'jp': (241, 188, 122), 'tw': (238, 168, 81)}, button={'cn': (383, 285, 503, 297), 'en': (392, 262, 515, 303), 'jp': (403, 271, 514, 303), 'tw': (383, 285, 503, 297)}, file={'cn': './assets/cn/commission/REWARD_1.png', 'en': './assets/en/commission/REWARD_1.png', 'jp': './assets/jp/commission/REWARD_1.png', 'tw': './assets/tw/commission/REWARD_1.png'}) REWARD_SAVE_CLICK = Button(area={'cn': (415, 184, 496, 214), 'en': (415, 184, 496, 214), 'jp': (415, 184, 496, 214), 'tw': (415, 184, 496, 214)}, color={'cn': (152, 150, 168), 'en': (152, 150, 168), 'jp': (152, 150, 168), 'tw': (152, 150, 168)}, button={'cn': (415, 184, 496, 214), 'en': (415, 184, 496, 214), 'jp': (415, 184, 496, 214), 'tw': (415, 184, 496, 214)}, file={'cn': './assets/cn/commission/REWARD_SAVE_CLICK.png', 'en': './assets/en/commission/REWARD_SAVE_CLICK.png', 'jp': './assets/jp/commission/REWARD_SAVE_CLICK.png', 'tw': './assets/tw/commission/REWARD_SAVE_CLICK.png'}) diff --git a/module/commission/commission.py b/module/commission/commission.py index 08a70a4d8..7c3a0b6ed 100644 --- a/module/commission/commission.py +++ b/module/commission/commission.py @@ -11,6 +11,7 @@ from module.commission.preset import DICT_FILTER_PRESET, SHORTEST_FILTER from module.commission.project import COMMISSION_FILTER, Commission from module.config.config_generated import GeneratedConfig from module.config.utils import get_server_last_update, get_server_next_update +from module.dorm.dorm import RewardDorm from module.exception import GameStuckError from module.handler.info_handler import InfoHandler from module.logger import logger @@ -557,6 +558,15 @@ class RewardCommission(UI, InfoHandler): # no need to reset click_timer, just instant click REWARD_1 # click_timer.reset() continue + # handle oil maxed + # run once to prevent accidental oil consumption + if self.config.SERVER in ['cn']: + if self.appear(OIL_MAXED, offset=(20, 20), interval=3): + logger.info("Oil maxed, buy food to consume oil") + RewardDorm(self.config, self.device).dorm_run( + feed=False, collect=False, buy_furniture=False, buy_food=10) + self.ui_ensure(page_reward) + continue # Check GET_SHIP at last to handle random white background at page_main for button in [GET_SHIP]: if click_timer.reached() and self.appear(button, interval=1): diff --git a/module/dorm/assets.py b/module/dorm/assets.py index 7a23d4d42..8e758f506 100644 --- a/module/dorm/assets.py +++ b/module/dorm/assets.py @@ -4,6 +4,9 @@ from module.base.template import Template # This file was automatically generated by dev_tools/button_extract.py. # Don't modify it manually. +DORM_BUY_FOOD_CHECK = Button(area={'cn': (607, 427, 675, 459), 'en': (607, 427, 675, 459), 'jp': (607, 427, 675, 459), 'tw': (607, 427, 675, 459)}, color={'cn': (184, 182, 182), 'en': (184, 182, 182), 'jp': (184, 182, 182), 'tw': (184, 182, 182)}, button={'cn': (607, 427, 675, 459), 'en': (607, 427, 675, 459), 'jp': (607, 427, 675, 459), 'tw': (607, 427, 675, 459)}, file={'cn': './assets/cn/dorm/DORM_BUY_FOOD_CHECK.png', 'en': './assets/cn/dorm/DORM_BUY_FOOD_CHECK.png', 'jp': './assets/cn/dorm/DORM_BUY_FOOD_CHECK.png', 'tw': './assets/cn/dorm/DORM_BUY_FOOD_CHECK.png'}) +DORM_BUY_FOOD_CONFIRM = Button(area={'cn': (751, 499, 792, 520), 'en': (751, 499, 792, 520), 'jp': (751, 499, 792, 520), 'tw': (751, 499, 792, 520)}, color={'cn': (255, 238, 186), 'en': (255, 238, 186), 'jp': (255, 238, 186), 'tw': (255, 238, 186)}, button={'cn': (751, 499, 792, 520), 'en': (751, 499, 792, 520), 'jp': (751, 499, 792, 520), 'tw': (751, 499, 792, 520)}, file={'cn': './assets/cn/dorm/DORM_BUY_FOOD_CONFIRM.png', 'en': './assets/cn/dorm/DORM_BUY_FOOD_CONFIRM.png', 'jp': './assets/cn/dorm/DORM_BUY_FOOD_CONFIRM.png', 'tw': './assets/cn/dorm/DORM_BUY_FOOD_CONFIRM.png'}) +DORM_BUY_FOOD_ENTER = Button(area={'cn': (866, 375, 888, 398), 'en': (866, 375, 888, 398), 'jp': (866, 375, 888, 398), 'tw': (866, 375, 888, 398)}, color={'cn': (119, 110, 71), 'en': (119, 110, 71), 'jp': (119, 110, 71), 'tw': (119, 110, 71)}, button={'cn': (866, 375, 888, 398), 'en': (866, 375, 888, 398), 'jp': (866, 375, 888, 398), 'tw': (866, 375, 888, 398)}, file={'cn': './assets/cn/dorm/DORM_BUY_FOOD_ENTER.png', 'en': './assets/cn/dorm/DORM_BUY_FOOD_ENTER.png', 'jp': './assets/cn/dorm/DORM_BUY_FOOD_ENTER.png', 'tw': './assets/cn/dorm/DORM_BUY_FOOD_ENTER.png'}) DORM_FEED_CHECK = Button(area={'cn': (162, 342, 274, 370), 'en': (162, 342, 274, 370), 'jp': (162, 342, 274, 370), 'tw': (162, 342, 274, 370)}, color={'cn': (182, 179, 171), 'en': (182, 179, 171), 'jp': (182, 179, 171), 'tw': (182, 179, 171)}, button={'cn': (162, 342, 274, 370), 'en': (162, 342, 274, 370), 'jp': (162, 342, 274, 370), 'tw': (162, 342, 274, 370)}, file={'cn': './assets/cn/dorm/DORM_FEED_CHECK.png', 'en': './assets/en/dorm/DORM_FEED_CHECK.png', 'jp': './assets/jp/dorm/DORM_FEED_CHECK.png', 'tw': './assets/tw/dorm/DORM_FEED_CHECK.png'}) DORM_FEED_ENTER = Button(area={'cn': (254, 581, 300, 605), 'en': (298, 581, 344, 605), 'jp': (254, 581, 300, 605), 'tw': (254, 581, 300, 605)}, color={'cn': (204, 192, 177), 'en': (204, 192, 176), 'jp': (204, 192, 177), 'tw': (204, 192, 177)}, button={'cn': (254, 581, 300, 605), 'en': (298, 581, 344, 605), 'jp': (254, 581, 300, 605), 'tw': (254, 581, 300, 605)}, file={'cn': './assets/cn/dorm/DORM_FEED_ENTER.png', 'en': './assets/en/dorm/DORM_FEED_ENTER.png', 'jp': './assets/jp/dorm/DORM_FEED_ENTER.png', 'tw': './assets/tw/dorm/DORM_FEED_ENTER.png'}) DORM_FURNITURE_BUY_ALL = Button(area={'cn': (818, 621, 1072, 677), 'en': (819, 621, 1072, 677), 'jp': (899, 636, 991, 661), 'tw': (818, 621, 1072, 677)}, color={'cn': (249, 202, 66), 'en': (248, 201, 66), 'jp': (215, 171, 65), 'tw': (248, 201, 66)}, button={'cn': (818, 621, 1072, 677), 'en': (819, 621, 1072, 677), 'jp': (899, 636, 991, 661), 'tw': (818, 621, 1072, 677)}, file={'cn': './assets/cn/dorm/DORM_FURNITURE_BUY_ALL.png', 'en': './assets/en/dorm/DORM_FURNITURE_BUY_ALL.png', 'jp': './assets/jp/dorm/DORM_FURNITURE_BUY_ALL.png', 'tw': './assets/tw/dorm/DORM_FURNITURE_BUY_ALL.png'}) @@ -21,6 +24,9 @@ DORM_MANAGE = Button(area={'cn': (949, 600, 1005, 659), 'en': (949, 600, 1005, 6 DORM_MANAGE_CHECK = Button(area={'cn': (1128, 116, 1150, 135), 'en': (1128, 116, 1150, 135), 'jp': (1128, 116, 1150, 135), 'tw': (1128, 116, 1150, 135)}, color={'cn': (173, 147, 77), 'en': (173, 147, 77), 'jp': (173, 147, 77), 'tw': (173, 147, 77)}, button={'cn': (1128, 116, 1150, 135), 'en': (1128, 116, 1150, 135), 'jp': (1128, 116, 1150, 135), 'tw': (1128, 116, 1150, 135)}, file={'cn': './assets/cn/dorm/DORM_MANAGE_CHECK.png', 'en': './assets/en/dorm/DORM_MANAGE_CHECK.png', 'jp': './assets/jp/dorm/DORM_MANAGE_CHECK.png', 'tw': './assets/tw/dorm/DORM_MANAGE_CHECK.png'}) DORM_QUICK_COLLECT = Button(area={'cn': (1191, 497, 1251, 519), 'en': (1191, 497, 1251, 519), 'jp': (1191, 497, 1251, 519), 'tw': (1191, 497, 1251, 519)}, color={'cn': (243, 194, 138), 'en': (243, 194, 138), 'jp': (243, 194, 138), 'tw': (243, 194, 138)}, button={'cn': (1191, 497, 1251, 519), 'en': (1191, 497, 1251, 519), 'jp': (1191, 497, 1251, 519), 'tw': (1191, 497, 1251, 519)}, file={'cn': './assets/cn/dorm/DORM_QUICK_COLLECT.png', 'en': './assets/en/dorm/DORM_QUICK_COLLECT.png', 'jp': './assets/jp/dorm/DORM_QUICK_COLLECT.png', 'tw': './assets/tw/dorm/DORM_QUICK_COLLECT.png'}) DORM_RED_DOT = Button(area={'cn': (528, 339, 543, 356), 'en': (528, 339, 543, 356), 'jp': (528, 339, 543, 356), 'tw': (528, 339, 543, 356)}, color={'cn': (214, 126, 114), 'en': (214, 126, 114), 'jp': (214, 126, 114), 'tw': (214, 126, 114)}, button={'cn': (528, 339, 543, 356), 'en': (528, 339, 543, 356), 'jp': (528, 339, 543, 356), 'tw': (528, 339, 543, 356)}, file={'cn': './assets/cn/dorm/DORM_RED_DOT.png', 'en': './assets/en/dorm/DORM_RED_DOT.png', 'jp': './assets/jp/dorm/DORM_RED_DOT.png', 'tw': './assets/tw/dorm/DORM_RED_DOT.png'}) +FOOD_MINUS = Button(area={'cn': (532, 370, 554, 397), 'en': (532, 370, 554, 397), 'jp': (532, 370, 554, 397), 'tw': (532, 370, 554, 397)}, color={'cn': (246, 246, 247), 'en': (246, 246, 247), 'jp': (246, 246, 247), 'tw': (246, 246, 247)}, button={'cn': (532, 370, 554, 397), 'en': (532, 370, 554, 397), 'jp': (532, 370, 554, 397), 'tw': (532, 370, 554, 397)}, file={'cn': './assets/cn/dorm/FOOD_MINUS.png', 'en': './assets/cn/dorm/FOOD_MINUS.png', 'jp': './assets/cn/dorm/FOOD_MINUS.png', 'tw': './assets/cn/dorm/FOOD_MINUS.png'}) +FOOD_PLUS = Button(area={'cn': (807, 370, 826, 397), 'en': (807, 370, 826, 397), 'jp': (807, 370, 826, 397), 'tw': (807, 370, 826, 397)}, color={'cn': (248, 248, 248), 'en': (248, 248, 248), 'jp': (248, 248, 248), 'tw': (248, 248, 248)}, button={'cn': (807, 370, 826, 397), 'en': (807, 370, 826, 397), 'jp': (807, 370, 826, 397), 'tw': (807, 370, 826, 397)}, file={'cn': './assets/cn/dorm/FOOD_PLUS.png', 'en': './assets/cn/dorm/FOOD_PLUS.png', 'jp': './assets/cn/dorm/FOOD_PLUS.png', 'tw': './assets/cn/dorm/FOOD_PLUS.png'}) +OCR_DORM_BUY_FOOD_AMOUNT = Button(area={'cn': (653, 374, 706, 395), 'en': (653, 374, 706, 395), 'jp': (653, 374, 706, 395), 'tw': (653, 374, 706, 395)}, color={'cn': (203, 203, 204), 'en': (203, 203, 204), 'jp': (203, 203, 204), 'tw': (203, 203, 204)}, button={'cn': (653, 374, 706, 395), 'en': (653, 374, 706, 395), 'jp': (653, 374, 706, 395), 'tw': (653, 374, 706, 395)}, file={'cn': './assets/cn/dorm/OCR_DORM_BUY_FOOD_AMOUNT.png', 'en': './assets/cn/dorm/OCR_DORM_BUY_FOOD_AMOUNT.png', 'jp': './assets/cn/dorm/OCR_DORM_BUY_FOOD_AMOUNT.png', 'tw': './assets/cn/dorm/OCR_DORM_BUY_FOOD_AMOUNT.png'}) OCR_DORM_FILL = Button(area={'cn': (813, 271, 987, 296), 'en': (813, 271, 987, 296), 'jp': (813, 271, 987, 296), 'tw': (813, 271, 987, 296)}, color={'cn': (222, 213, 193), 'en': (222, 213, 193), 'jp': (222, 213, 193), 'tw': (222, 213, 193)}, button={'cn': (813, 271, 987, 296), 'en': (813, 271, 987, 296), 'jp': (813, 271, 987, 296), 'tw': (813, 271, 987, 296)}, file={'cn': './assets/cn/dorm/OCR_DORM_FILL.png', 'en': './assets/en/dorm/OCR_DORM_FILL.png', 'jp': './assets/jp/dorm/OCR_DORM_FILL.png', 'tw': './assets/tw/dorm/OCR_DORM_FILL.png'}) OCR_DORM_FURNITURE_COIN = Button(area={'cn': (897, 20, 988, 49), 'en': (897, 20, 988, 49), 'jp': (897, 20, 988, 49), 'tw': (897, 20, 988, 49)}, color={'cn': (203, 197, 194), 'en': (203, 197, 194), 'jp': (203, 197, 194), 'tw': (203, 197, 194)}, button={'cn': (897, 20, 988, 49), 'en': (897, 20, 988, 49), 'jp': (897, 20, 988, 49), 'tw': (897, 20, 988, 49)}, file={'cn': './assets/cn/dorm/OCR_DORM_FURNITURE_COIN.png', 'en': './assets/en/dorm/OCR_DORM_FURNITURE_COIN.png', 'jp': './assets/jp/dorm/OCR_DORM_FURNITURE_COIN.png', 'tw': './assets/tw/dorm/OCR_DORM_FURNITURE_COIN.png'}) OCR_DORM_FURNITURE_PRICE = Button(area={'cn': (819, 417, 896, 442), 'en': (819, 417, 896, 442), 'jp': (819, 417, 896, 442), 'tw': (819, 417, 896, 442)}, color={'cn': (227, 223, 220), 'en': (227, 223, 220), 'jp': (227, 223, 220), 'tw': (227, 223, 220)}, button={'cn': (819, 417, 896, 442), 'en': (819, 417, 896, 442), 'jp': (819, 417, 896, 442), 'tw': (819, 417, 896, 442)}, file={'cn': './assets/cn/dorm/OCR_DORM_FURNITURE_PRICE.png', 'en': './assets/en/dorm/OCR_DORM_FURNITURE_PRICE.png', 'jp': './assets/jp/dorm/OCR_DORM_FURNITURE_PRICE.png', 'tw': './assets/tw/dorm/OCR_DORM_FURNITURE_PRICE.png'}) diff --git a/module/dorm/dorm.py b/module/dorm/dorm.py index 0496c5c8a..b854a441a 100644 --- a/module/dorm/dorm.py +++ b/module/dorm/dorm.py @@ -21,6 +21,7 @@ MASK_DORM = Mask(file='./assets/mask/MASK_DORM.png') DORM_CAMERA_SWIPE = (300, 250) DORM_CAMERA_RANDOM = (-20, -20, 20, 20) OCR_SLOT = DigitCounter(OCR_DORM_SLOT, letter=(107, 89, 82), threshold=128, name='OCR_DORM_SLOT') +OCR_BUY_FOOD_AMOUNT = Digit(OCR_DORM_BUY_FOOD_AMOUNT, letter=(96, 96, 100), threshold=128, name='OCR_DORM_BUY_FOOD_AMOUNT') class OcrDormFood(DigitCounter): @@ -199,7 +200,7 @@ class RewardDorm(UI): f'does not support DOWN/UP events, use multi-click instead') self.device.multi_click(button, count) - def dorm_view_reset(self, skip_first_screenshot=True): + def dorm_view_reset(self): """ Use Dorm manage and Back to reset dorm view. @@ -208,12 +209,7 @@ class RewardDorm(UI): out: page_dorm """ logger.info('Dorm view reset') - while 1: - if skip_first_screenshot: - skip_first_screenshot = False - else: - self.device.screenshot() - + for _ in self.loop(): # End if self.appear(DORM_MANAGE_CHECK, offset=(20, 20)): break @@ -226,13 +222,7 @@ class RewardDorm(UI): if self.appear_then_click(DORM_FURNITURE_CONFIRM, offset=(30, 30), interval=3): continue - skip_first_screenshot = True - while 1: - if skip_first_screenshot: - skip_first_screenshot = False - else: - self.device.screenshot() - + for _ in self.loop(): if self.appear(DORM_MANAGE, offset=(20, 20)): break @@ -251,17 +241,11 @@ class RewardDorm(UI): logger.hr('Dorm collect') self.ensure_no_info_bar() - skip_first_screenshot = True # Set a timer to avoid Alas failing to detect the info_bar by accident. timeout = Timer(1.5, count=3).start() - while 1: - if skip_first_screenshot: - skip_first_screenshot = False - else: - self.device.screenshot() - + for _ in self.loop(): # Handle all popups if self.ui_additional(get_ship=False): continue @@ -312,11 +296,7 @@ class RewardDorm(UI): skip_first_screenshot = True self.popup_interval_clear() - while 1: - if skip_first_screenshot: - skip_first_screenshot = False - else: - self.device.screenshot() + for _ in self.loop(skip_first=skip_first_screenshot): # End if self.appear(DORM_FEED_CHECK, offset=(20, 20)): break @@ -354,13 +334,7 @@ class RewardDorm(UI): timeout = Timer(1.5, count=3).start() food: t.List[Food] = [] fill: int = 0 - skip_first_screenshot = True - while 1: - if skip_first_screenshot: - skip_first_screenshot = False - else: - self.device.screenshot() - + for _ in self.loop(): # End if timeout.reached(): logger.warning('Get dorm food timeout, probably because food is empty') @@ -406,19 +380,14 @@ class RewardDorm(UI): logger.warning('Dorm feed run count reached') return 10 - def dorm_feed_enter(self, skip_first_screenshot=False): + def dorm_feed_enter(self): """ Pages: in: DORM_CHECK out: DORM_FEED_CHECK """ self.interval_clear(DORM_CHECK) - while 1: - if skip_first_screenshot: - skip_first_screenshot = False - else: - self.device.screenshot() - + for _ in self.loop(skip_first=False): # End if self.appear(DORM_FEED_CHECK, offset=(20, 20)): break @@ -442,19 +411,14 @@ class RewardDorm(UI): logger.info(f'{DORM_FURNITURE_SHOP_FIRST_SELECTED} -> {DORM_FURNITURE_SHOP_QUIT}') continue - def dorm_feed_quit(self, skip_first_screenshot=True): + def dorm_feed_quit(self): """ Pages: in: DORM_FEED_CHECK out: DORM_CHECK """ self.interval_clear(DORM_FEED_CHECK) - while 1: - if skip_first_screenshot: - skip_first_screenshot = False - else: - self.device.screenshot() - + for _ in self.loop(): # End if self.appear(DORM_CHECK): break @@ -469,13 +433,61 @@ class RewardDorm(UI): self.interval_clear(DORM_CHECK) continue - def dorm_run(self, feed=True, collect=True, buy_furniture=False): + def dorm_buy_food_enter(self): + """ + Pages: + in: DORM_FEED_CHECK + out: DORM_BUY_FOOD_CHECK + """ + self.interval_clear(DORM_FEED_CHECK) + for _ in self.loop(): + # End + if self.appear(DORM_BUY_FOOD_CHECK, offset=(20, 20)): + break + + if self.match_template_color(DORM_FEED_CHECK, offset=(20, 20), interval=5): + self.device.click(DORM_BUY_FOOD_ENTER) + continue + + def dorm_buy_food(self, amount): + """ + Pages: + in: DORM_BUY_FOOD_CHECK + out: DORM_BUY_FOOD_CHECK + """ + logger.hr('Dorm buy food') + index_offset = (20, 20) + # In case either -/+ shift position, use + # shipyard ocr trick to accurately parse + self.appear(FOOD_PLUS, offset=index_offset) + self.appear(FOOD_MINUS, offset=index_offset) + + self.ui_ensure_index(amount, letter=OCR_BUY_FOOD_AMOUNT, prev_button=FOOD_MINUS, next_button=FOOD_PLUS, + skip_first_screenshot=True) + return True + + def dorm_buy_food_confirm(self): + """ + Pages: + in: DORM_BUY_FOOD_CHECK + out: DORM_FEED_CHECK + """ + self.interval_clear(DORM_BUY_FOOD_CONFIRM) + for _ in self.loop(): + # End + if self.match_template_color(DORM_FEED_CHECK, offset=(20, 20)): + break + + if self.appear_then_click(DORM_BUY_FOOD_CONFIRM, offset=(20, 20), interval=5): + continue + + def dorm_run(self, feed=True, collect=True, buy_furniture=False, buy_food=0): """ Pages: in: Any page out: page_dorm """ - if not feed and not collect and not buy_furniture: + if not feed and not collect and not buy_furniture and buy_food <= 0: return self.ui_ensure(page_dormmenu) @@ -504,7 +516,15 @@ class RewardDorm(UI): logger.hr('Dorm buy furniture', level=1) BuyFurniture(self.config, self.device).run() - def get_dorm_ship_amount(self, skip_first_screenshot=True): + if buy_food > 0: + logger.hr('Dorm buy food', level=1) + self.dorm_feed_enter() + self.dorm_buy_food_enter() + self.dorm_buy_food(amount=buy_food) + self.dorm_buy_food_confirm() + self.dorm_feed_quit() + + def get_dorm_ship_amount(self): """ Args: skip_first_screenshot: @@ -517,12 +537,7 @@ class RewardDorm(UI): """ timeout = Timer(2, count=4).start() current = 0 - while 1: - if skip_first_screenshot: - skip_first_screenshot = False - else: - self.device.screenshot() - + for _ in self.loop(): # Handle popups if self.appear_then_click(DORM_FURNITURE_CONFIRM, offset=(30, 30), interval=3): timeout.reset() From 1155f277ef7d13cfe6891b0e66d21a9083237ddd Mon Sep 17 00:00:00 2001 From: sui-feng-cb <2518179942@qq.com> Date: Mon, 11 May 2026 16:15:33 +0800 Subject: [PATCH 2/8] Upd: method dorm_food_run --- module/commission/commission.py | 3 +-- module/dorm/dorm.py | 37 +++++++++++++++++++++------------ 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/module/commission/commission.py b/module/commission/commission.py index 7c3a0b6ed..b259d8e34 100644 --- a/module/commission/commission.py +++ b/module/commission/commission.py @@ -563,8 +563,7 @@ class RewardCommission(UI, InfoHandler): if self.config.SERVER in ['cn']: if self.appear(OIL_MAXED, offset=(20, 20), interval=3): logger.info("Oil maxed, buy food to consume oil") - RewardDorm(self.config, self.device).dorm_run( - feed=False, collect=False, buy_furniture=False, buy_food=10) + RewardDorm(self.config, self.device).dorm_food_run(amount=10) self.ui_ensure(page_reward) continue # Check GET_SHIP at last to handle random white background at page_main diff --git a/module/dorm/dorm.py b/module/dorm/dorm.py index b854a441a..c3c954599 100644 --- a/module/dorm/dorm.py +++ b/module/dorm/dorm.py @@ -481,13 +481,35 @@ class RewardDorm(UI): if self.appear_then_click(DORM_BUY_FOOD_CONFIRM, offset=(20, 20), interval=5): continue - def dorm_run(self, feed=True, collect=True, buy_furniture=False, buy_food=0): + def dorm_food_run(self, amount): + """ + Args: + amount (int): amount of food to buy + + Pages: + in: Any page + out: page_dorm + """ + if amount <= 0: + return + + self.ui_ensure(page_dormmenu) + self.handle_info_bar() + self.ui_goto(page_dorm, skip_first_screenshot=True) + logger.hr('Dorm buy food', level=1) + self.dorm_feed_enter() + self.dorm_buy_food_enter() + self.dorm_buy_food(amount=amount) + self.dorm_buy_food_confirm() + self.dorm_feed_quit() + + def dorm_run(self, feed=True, collect=True, buy_furniture=False): """ Pages: in: Any page out: page_dorm """ - if not feed and not collect and not buy_furniture and buy_food <= 0: + if not feed and not collect and not buy_furniture: return self.ui_ensure(page_dormmenu) @@ -516,19 +538,8 @@ class RewardDorm(UI): logger.hr('Dorm buy furniture', level=1) BuyFurniture(self.config, self.device).run() - if buy_food > 0: - logger.hr('Dorm buy food', level=1) - self.dorm_feed_enter() - self.dorm_buy_food_enter() - self.dorm_buy_food(amount=buy_food) - self.dorm_buy_food_confirm() - self.dorm_feed_quit() - def get_dorm_ship_amount(self): """ - Args: - skip_first_screenshot: - Returns: int: Number of ships in dorm From 90c06f905446a809777544a38bded76eea4433a7 Mon Sep 17 00:00:00 2001 From: sui-feng-cb <2518179942@qq.com> Date: Mon, 11 May 2026 16:36:48 +0800 Subject: [PATCH 3/8] Upd: exception OilMaxed to control buy food trial --- module/commission/commission.py | 31 ++++++++++++++++++++++++------- module/exception.py | 4 ++++ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/module/commission/commission.py b/module/commission/commission.py index b259d8e34..195d84a13 100644 --- a/module/commission/commission.py +++ b/module/commission/commission.py @@ -12,7 +12,7 @@ from module.commission.project import COMMISSION_FILTER, Commission from module.config.config_generated import GeneratedConfig from module.config.utils import get_server_last_update, get_server_next_update from module.dorm.dorm import RewardDorm -from module.exception import GameStuckError +from module.exception import GameStuckError, OilMaxed, RequestHumanTakeover from module.handler.info_handler import InfoHandler from module.logger import logger from module.map.map_grids import SelectedGrids @@ -493,7 +493,7 @@ class RewardCommission(UI, InfoHandler): if not self.daily_choose and not self.urgent_choose: logger.info('No commission chose') - def commission_receive(self, skip_first_screenshot=True): + def _commission_receive(self, skip_first_screenshot=True): """ Args: skip_first_screenshot: @@ -559,13 +559,9 @@ class RewardCommission(UI, InfoHandler): # click_timer.reset() continue # handle oil maxed - # run once to prevent accidental oil consumption if self.config.SERVER in ['cn']: if self.appear(OIL_MAXED, offset=(20, 20), interval=3): - logger.info("Oil maxed, buy food to consume oil") - RewardDorm(self.config, self.device).dorm_food_run(amount=10) - self.ui_ensure(page_reward) - continue + raise OilMaxed # Check GET_SHIP at last to handle random white background at page_main for button in [GET_SHIP]: if click_timer.reached() and self.appear(button, interval=1): @@ -583,6 +579,27 @@ class RewardCommission(UI, InfoHandler): return reward + def commission_receive(self): + """ + Returns: + bool: If rewarded. + + Pages: + in: page_reward + out: page_commission + """ + for _ in range(3): + try: + reward = self._commission_receive() + return reward + except OilMaxed: + logger.info("Oil maxed, buy food to consume oil") + RewardDorm(self.config, self.device).dorm_food_run(amount=10) + self.ui_ensure(page_reward) + + logger.critical(f'Failed to handle oil maxed after 3 trial') + raise RequestHumanTakeover + def run(self): """ Pages: diff --git a/module/exception.py b/module/exception.py index e0d3ecf39..2e810c57c 100644 --- a/module/exception.py +++ b/module/exception.py @@ -6,6 +6,10 @@ class OilExhausted(Exception): pass +class OilMaxed(Exception): + pass + + class MapDetectionError(Exception): pass From 6dd8eff8d3e497a4bdea5d486546ec135ed772a1 Mon Sep 17 00:00:00 2001 From: LmeSzinc <37934724+LmeSzinc@users.noreply.github.com> Date: Mon, 11 May 2026 17:00:20 +0800 Subject: [PATCH 4/8] Upd: [TW] event entrance of event_20201126_cn rerun (#5615) --- campaign/Readme.md | 1 + module/config/argument/args.json | 8 ++++++++ module/config/i18n/zh-TW.json | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/campaign/Readme.md b/campaign/Readme.md index d439ebb8b..0072c8e81 100644 --- a/campaign/Readme.md +++ b/campaign/Readme.md @@ -291,3 +291,4 @@ To add a new event, add a new row in here, and run `python -m module.config.conf | 20260417 | event 20201126 cn | Vacation Lane Rerun | 复刻假日航线 | Vacation Lane Rerun | バケーションレーン(復刻) | - | | 20260417 | event 20250424 cn | Toward Tulipa’s Seas Rerun | 复刻扬起郁金之旗 | Toward Tulipa’s Seas Rerun | チュリッパの海へ(復刻) | - | | 20260417 | event 20260417 cn | Vacation Lane – Beachside Brilliance | - | - | - | 假日航線閃耀海濱 | +| 20260417 | event 20201126 cn | Vacation Lane Rerun | - | - | - | 復刻假日航線 | diff --git a/module/config/argument/args.json b/module/config/argument/args.json index 63ad123fa..3f5c6672c 100644 --- a/module/config/argument/args.json +++ b/module/config/argument/args.json @@ -1662,6 +1662,7 @@ "event_20260417_cn" ], "option_tw": [ + "event_20201126_cn", "event_20260417_cn" ], "option_bold": [ @@ -1952,6 +1953,7 @@ "event_20260417_cn" ], "option_tw": [ + "event_20201126_cn", "event_20260417_cn" ], "option_bold": [ @@ -2357,6 +2359,7 @@ "event_20260417_cn" ], "option_tw": [ + "event_20201126_cn", "event_20260417_cn" ], "option_bold": [ @@ -4092,6 +4095,7 @@ "event_20260417_cn" ], "option_tw": [ + "event_20201126_cn", "event_20260417_cn" ], "option_bold": [ @@ -4514,6 +4518,7 @@ "event_20260417_cn" ], "option_tw": [ + "event_20201126_cn", "event_20260417_cn" ], "option_bold": [ @@ -4936,6 +4941,7 @@ "event_20260417_cn" ], "option_tw": [ + "event_20201126_cn", "event_20260417_cn" ], "option_bold": [ @@ -5358,6 +5364,7 @@ "event_20260417_cn" ], "option_tw": [ + "event_20201126_cn", "event_20260417_cn" ], "option_bold": [ @@ -5770,6 +5777,7 @@ "event_20260417_cn" ], "option_tw": [ + "event_20201126_cn", "event_20260417_cn" ], "option_bold": [ diff --git a/module/config/i18n/zh-TW.json b/module/config/i18n/zh-TW.json index 761ad94ee..4fed5f6b1 100644 --- a/module/config/i18n/zh-TW.json +++ b/module/config/i18n/zh-TW.json @@ -706,7 +706,7 @@ "event_20201002_en": "Counterattack Within the Fjord", "event_20201012_cn": "復刻劃破海空之翼", "event_20201029_cn": "激唱的UNIVERSE", - "event_20201126_cn": "假日航線", + "event_20201126_cn": "復刻假日航線", "event_20201229_cn": "復刻-負象限作戰", "event_20210121_cn": "復刻神聖的悲喜劇", "event_20210225_cn": "復刻破曉冰華", From 884c77c8f02d8b021845e1f332c987c84dc75bb0 Mon Sep 17 00:00:00 2001 From: guoh064 <50830808+guoh064@users.noreply.github.com> Date: Mon, 11 May 2026 17:04:48 +0800 Subject: [PATCH 5/8] Upd: method _load_file for class LuaLoader (#5662) --- dev_tools/utils.py | 58 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/dev_tools/utils.py b/dev_tools/utils.py index e85e9682a..c8d75fb36 100644 --- a/dev_tools/utils.py +++ b/dev_tools/utils.py @@ -45,6 +45,52 @@ class LuaLoader: def filepath(self, path): return os.path.join(self.folder, self.server, path) + def _find_matching_brace(self, text, start_index): + depth = 0 + in_string = None + escape = False + for i in range(start_index, len(text)): + ch = text[i] + if in_string: + if escape: + escape = False + elif ch == '\\': + escape = True + elif ch == in_string: + in_string = None + else: + if ch in ('"', "'"): + in_string = ch + elif ch == '{': + depth += 1 + elif ch == '}': + depth -= 1 + if depth == 0: + return i + return -1 + + def _infer_base_name(self, file, keyword): + if keyword: + keyword = keyword.strip() + if keyword.startswith('pg.base.'): + return keyword[len('pg.base.') :] + if keyword.startswith('pg.'): + return keyword[len('pg.') :] + return keyword + return os.path.splitext(os.path.basename(file))[0] + + def _load_pg_base_entries(self, text, base_name): + pattern = rf"pg\.base\.{re.escape(base_name)}\[(\d+)\]\s*=\s*\{{" + result = {} + for m in re.finditer(pattern, text): + start = m.end() - 1 + end = self._find_matching_brace(text, start) + if end == -1: + continue + table_text = text[start:end + 1] + result[int(m.group(1))] = slpp.decode(table_text) + return result + def _load_file(self, file, keyword=None): """ Args: @@ -56,6 +102,16 @@ class LuaLoader: with open(self.filepath(file), 'r', encoding='utf-8') as f: text = f.read() + if 'pg.base.' in text: + base_name = self._infer_base_name(file, keyword) + if not base_name: + m = re.search(r"pg\.base\.([A-Za-z0-9_]+)\[", text) + base_name = m.group(1) if m else None + if base_name: + result = self._load_pg_base_entries(text, base_name) + if result: + return result + result = {} if text.startswith('_G'): text = '{' + text + '}' @@ -86,7 +142,7 @@ class LuaLoader: if os.path.isdir(self.filepath(path)): result = {} for file in tqdm(os.listdir(self.filepath(path))): - result.update(self._load_file(f'./{path}/{file}')) + result.update(self._load_file(f'./{path}/{file}', keyword=keyword)) else: result = self._load_file(path, keyword=keyword) From 0f679ce3e847e735dc3f30fbc0a8085649b085ae Mon Sep 17 00:00:00 2001 From: LmeSzinc <37934724+LmeSzinc@users.noreply.github.com> Date: Mon, 11 May 2026 19:10:32 +0800 Subject: [PATCH 6/8] Fix: [TW] Enter event 20201126 --- .../cn/campaign/EVENT_20201126_ENTRANCE_TEMP.png | Bin 0 -> 7741 bytes campaign/event_20201126_cn/campaign_base.py | 9 ++++++++- module/campaign/assets.py | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 assets/cn/campaign/EVENT_20201126_ENTRANCE_TEMP.png diff --git a/assets/cn/campaign/EVENT_20201126_ENTRANCE_TEMP.png b/assets/cn/campaign/EVENT_20201126_ENTRANCE_TEMP.png new file mode 100644 index 0000000000000000000000000000000000000000..4420fac7bb978ebdb0c8c859721dc6676d18ca64 GIT binary patch literal 7741 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 Date: Mon, 11 May 2026 19:25:06 +0800 Subject: [PATCH 7/8] Upd: detect 5 story options at max (#5653) --- module/handler/info_handler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/handler/info_handler.py b/module/handler/info_handler.py index bb64d52e7..89d2e9355 100644 --- a/module/handler/info_handler.py +++ b/module/handler/info_handler.py @@ -340,8 +340,8 @@ class InfoHandler(ModuleBase): list[Button]: List of story options, from upper to bottom. If no option found, return an empty list. """ # Area to detect the options, should include at least 3 options. - story_option_area = (330, 200, 980, 465) - story_detect_area = (330, 200, 355, 465) + story_option_area = (330, 135, 980, 555) + story_detect_area = (330, 135, 355, 555) story_option_color = (247, 247, 247) image = color_similarity_2d(self.image_crop(story_detect_area, copy=False), color=story_option_color) From d0b6e629645ab7af4e1a4d40168e81024539ab16 Mon Sep 17 00:00:00 2001 From: ArecaSapling <115386623+sui-feng-cb@users.noreply.github.com> Date: Mon, 11 May 2026 19:26:19 +0800 Subject: [PATCH 8/8] Add: war_archives_20220818_cn and war_archives_20230803_cn (#5660) --- .../TEMPLATE_ANTHEM_OF_REMEMBRANCE.png | Bin 0 -> 6412 bytes .../TEMPLATE_OPERATION_CONVERGENCE.png | Bin 0 -> 6644 bytes campaign/Readme.md | 2 + .../war_archives_20220818_cn/campaign_base.py | 35 ++++++ campaign/war_archives_20220818_cn/sp1.py | 77 +++++++++++++ campaign/war_archives_20220818_cn/sp2.py | 76 +++++++++++++ campaign/war_archives_20220818_cn/sp3.py | 81 ++++++++++++++ campaign/war_archives_20220818_cn/sp4.py | 84 ++++++++++++++ .../war_archives_20230803_cn/campaign_base.py | 7 ++ campaign/war_archives_20230803_cn/sp1.py | 104 ++++++++++++++++++ campaign/war_archives_20230803_cn/sp2.py | 80 ++++++++++++++ campaign/war_archives_20230803_cn/sp3.py | 86 +++++++++++++++ config/template.json | 2 +- module/config/argument/args.json | 10 ++ module/config/i18n/en-US.json | 2 + module/config/i18n/ja-JP.json | 2 + module/config/i18n/zh-CN.json | 2 + module/config/i18n/zh-TW.json | 2 + module/war_archives/assets.py | 2 + module/war_archives/dictionary.py | 2 + 20 files changed, 655 insertions(+), 1 deletion(-) create mode 100644 assets/cn/war_archives/TEMPLATE_ANTHEM_OF_REMEMBRANCE.png create mode 100644 assets/cn/war_archives/TEMPLATE_OPERATION_CONVERGENCE.png create mode 100644 campaign/war_archives_20220818_cn/campaign_base.py create mode 100644 campaign/war_archives_20220818_cn/sp1.py create mode 100644 campaign/war_archives_20220818_cn/sp2.py create mode 100644 campaign/war_archives_20220818_cn/sp3.py create mode 100644 campaign/war_archives_20220818_cn/sp4.py create mode 100644 campaign/war_archives_20230803_cn/campaign_base.py create mode 100644 campaign/war_archives_20230803_cn/sp1.py create mode 100644 campaign/war_archives_20230803_cn/sp2.py create mode 100644 campaign/war_archives_20230803_cn/sp3.py diff --git a/assets/cn/war_archives/TEMPLATE_ANTHEM_OF_REMEMBRANCE.png b/assets/cn/war_archives/TEMPLATE_ANTHEM_OF_REMEMBRANCE.png new file mode 100644 index 0000000000000000000000000000000000000000..1a004fcc1de94f25cbd1544bc3b6249e15c52faf GIT binary patch literal 6412 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 SP2 > SP3', + ] diff --git a/campaign/war_archives_20230803_cn/sp1.py b/campaign/war_archives_20230803_cn/sp1.py new file mode 100644 index 000000000..2c92e5099 --- /dev/null +++ b/campaign/war_archives_20230803_cn/sp1.py @@ -0,0 +1,104 @@ +from .campaign_base import CampaignBase +from module.map.map_base import CampaignMap +from module.map.map_grids import SelectedGrids, RoadGrids +from module.logger import logger + +MAP = CampaignMap('SP1') +MAP.shape = 'I6' +MAP.camera_data = ['F2', 'F4'] +MAP.camera_data_spawn_point = ['D2', 'D4'] +MAP.map_data = """ + ++ ++ ++ -- -- ME -- -- -- + -- -- Me -- Me -- Me ++ ++ + SP -- -- -- -- ME -- MB ++ + -- -- -- MS -- -- __ -- ME + SP -- -- -- ++ ME -- ME -- + -- ++ ME -- Me -- ME ++ -- +""" +MAP.weight_data = """ + 50 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 50 +""" +MAP.spawn_data = [ + {'battle': 0, 'enemy': 1, 'siren': 1}, + {'battle': 1, 'enemy': 1}, + {'battle': 2, 'enemy': 1}, + {'battle': 3, 'enemy': 1}, + {'battle': 4, 'boss': 1}, +] +A1, B1, C1, D1, E1, F1, G1, H1, I1, \ +A2, B2, C2, D2, E2, F2, G2, H2, I2, \ +A3, B3, C3, D3, E3, F3, G3, H3, I3, \ +A4, B4, C4, D4, E4, F4, G4, H4, I4, \ +A5, B5, C5, D5, E5, F5, G5, H5, I5, \ +A6, B6, C6, D6, E6, F6, G6, H6, I6, \ + = MAP.flatten() + + +class Config: + # ===== Start of generated config ===== + MAP_SIREN_TEMPLATE = ['DD'] + MOVABLE_ENEMY_TURN = (2,) + MAP_HAS_SIREN = True + MAP_HAS_MOVABLE_ENEMY = True + MAP_HAS_MAP_STORY = False + MAP_HAS_FLEET_STEP = True + MAP_HAS_AMBUSH = False + MAP_HAS_MYSTERY = False + # ===== End of generated config ===== + + MAP_HAS_WALK_SPEEDUP = True + MAP_HAS_MOVABLE_NORMAL_ENEMY = True + MOVABLE_NORMAL_ENEMY_TURN = (2,) + MAP_SIREN_MOVE_WAIT = 0.5 + + MAP_WALK_USE_CURRENT_FLEET = True + INTERNAL_LINES_FIND_PEAKS_PARAMETERS = { + 'height': (80, 255 - 24), + 'width': (0.9, 10), + 'prominence': 10, + 'distance': 35, + } + EDGE_LINES_FIND_PEAKS_PARAMETERS = { + 'height': (255 - 24, 255), + 'prominence': 10, + 'distance': 50, + 'wlen': 1000 + } + HOMO_EDGE_COLOR_RANGE = (0, 24) + MAP_ENSURE_EDGE_INSIGHT_CORNER = 'bottom' + MAP_ENEMY_GENRE_DETECTION_SCALING = { + 'DD': 1.111, + 'CL': 1.111, + 'CAred': 1.111, + 'BBred': 1.111, + 'CV': 1.111, + } + + MAP_SWIPE_MULTIPLY = (1.179, 1.201) + MAP_SWIPE_MULTIPLY_MINITOUCH = (1.140, 1.161) + MAP_SWIPE_MULTIPLY_MAATOUCH = (1.107, 1.127) + + +class Campaign(CampaignBase): + MAP = MAP + ENEMY_FILTER = '1L > 1M > 1E > 1C > 2L > 2M > 2E > 2C > 3L > 3M > 3E > 3C' + + def battle_0(self): + if self.map_is_clear_mode: + if self.clear_siren(): + return True + if self.clear_filter_enemy(self.ENEMY_FILTER, preserve=1): + return True + else: + if self.clear_any_enemy(sort=('cost_2',)): + return True + + return self.battle_default() + + def battle_4(self): + return self.clear_boss() diff --git a/campaign/war_archives_20230803_cn/sp2.py b/campaign/war_archives_20230803_cn/sp2.py new file mode 100644 index 000000000..93656d57c --- /dev/null +++ b/campaign/war_archives_20230803_cn/sp2.py @@ -0,0 +1,80 @@ +from .campaign_base import CampaignBase +from module.map.map_base import CampaignMap +from module.map.map_grids import SelectedGrids, RoadGrids +from module.logger import logger +from .sp1 import Config as ConfigBase + +MAP = CampaignMap('SP2') +MAP.shape = 'H7' +MAP.camera_data = ['D2', 'D5', 'E2', 'E5'] +MAP.camera_data_spawn_point = ['E5', 'D5'] +MAP.map_data = """ + ++ ME -- -- -- -- ME -- + ME -- -- Me Me -- ++ -- + ME -- Me ++ ++ ME ++ ME + -- __ -- ++ ++ -- Me -- + ME -- MS MB MB MS __ ME + ++ -- -- -- -- -- -- ME + ++ ME -- SP SP -- ME ++ +""" +MAP.weight_data = """ + 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 +""" +MAP.spawn_data = [ + {'battle': 0, 'enemy': 2, 'siren': 2}, + {'battle': 1, 'enemy': 2}, + {'battle': 2, 'enemy': 1}, + {'battle': 3, 'enemy': 1}, + {'battle': 4, 'boss': 1}, +] +A1, B1, C1, D1, E1, F1, G1, H1, \ +A2, B2, C2, D2, E2, F2, G2, H2, \ +A3, B3, C3, D3, E3, F3, G3, H3, \ +A4, B4, C4, D4, E4, F4, G4, H4, \ +A5, B5, C5, D5, E5, F5, G5, H5, \ +A6, B6, C6, D6, E6, F6, G6, H6, \ +A7, B7, C7, D7, E7, F7, G7, H7, \ + = MAP.flatten() + + +class Config(ConfigBase): + # ===== Start of generated config ===== + MAP_SIREN_TEMPLATE = ['CL', 'CAred'] + MOVABLE_ENEMY_TURN = (2,) + MAP_HAS_SIREN = True + MAP_HAS_MOVABLE_ENEMY = True + MAP_HAS_MAP_STORY = True + MAP_HAS_FLEET_STEP = True + MAP_HAS_AMBUSH = False + MAP_HAS_MYSTERY = False + # ===== End of generated config ===== + + MAP_SWIPE_MULTIPLY = (1.133, 1.155) + MAP_SWIPE_MULTIPLY_MINITOUCH = (1.096, 1.116) + MAP_SWIPE_MULTIPLY_MAATOUCH = (1.064, 1.083) + + +class Campaign(CampaignBase): + MAP = MAP + ENEMY_FILTER = '1L > 1M > 1E > 1C > 2L > 2M > 2E > 2C > 3L > 3M > 3E > 3C' + + def battle_0(self): + if self.map_is_clear_mode: + if self.clear_siren(): + return True + if self.clear_filter_enemy(self.ENEMY_FILTER, preserve=1): + return True + else: + if self.clear_any_enemy(sort=('cost_2',)): + return True + + return self.battle_default() + + def battle_4(self): + return self.clear_boss() diff --git a/campaign/war_archives_20230803_cn/sp3.py b/campaign/war_archives_20230803_cn/sp3.py new file mode 100644 index 000000000..477c67f57 --- /dev/null +++ b/campaign/war_archives_20230803_cn/sp3.py @@ -0,0 +1,86 @@ +from .campaign_base import CampaignBase +from module.map.map_base import CampaignMap +from module.map.map_grids import SelectedGrids, RoadGrids +from module.logger import logger +from .sp1 import Config as ConfigBase + +MAP = CampaignMap('SP3') +MAP.shape = 'I8' +MAP.camera_data = ['D2', 'D4', 'D6', 'F2', 'F4', 'F6'] +MAP.camera_data_spawn_point = ['F2', 'D2'] +MAP.map_data = """ + -- -- ME ++ ++ ++ ME -- -- + ++ Me -- -- MB -- -- Me ++ + ME -- -- SP -- SP -- -- ME + -- MS -- -- __ -- -- MS -- + ME -- ++ -- ++ -- ++ -- ME + -- Me ++ MS -- MS ++ Me -- + ME -- Me -- -- -- Me -- ME + ++ ME -- ++ ++ ++ -- ME ++ +""" +MAP.weight_data = """ + 50 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 50 +""" +MAP.spawn_data = [ + {'battle': 0, 'enemy': 2, 'siren': 2}, + {'battle': 1, 'enemy': 2, 'siren': 1}, + {'battle': 2, 'enemy': 2}, + {'battle': 3, 'enemy': 1}, + {'battle': 4, 'enemy': 1}, + {'battle': 5, 'boss': 1}, +] +A1, B1, C1, D1, E1, F1, G1, H1, I1, \ +A2, B2, C2, D2, E2, F2, G2, H2, I2, \ +A3, B3, C3, D3, E3, F3, G3, H3, I3, \ +A4, B4, C4, D4, E4, F4, G4, H4, I4, \ +A5, B5, C5, D5, E5, F5, G5, H5, I5, \ +A6, B6, C6, D6, E6, F6, G6, H6, I6, \ +A7, B7, C7, D7, E7, F7, G7, H7, I7, \ +A8, B8, C8, D8, E8, F8, G8, H8, I8, \ + = MAP.flatten() + + +class Config(ConfigBase): + # ===== Start of generated config ===== + MAP_SIREN_TEMPLATE = ['SirenBoss15'] + MOVABLE_ENEMY_TURN = (2,) + MAP_HAS_SIREN = True + MAP_HAS_MOVABLE_ENEMY = True + MAP_HAS_MAP_STORY = False + MAP_HAS_FLEET_STEP = True + MAP_HAS_AMBUSH = False + MAP_HAS_MYSTERY = False + # ===== End of generated config ===== + + HOMO_EDGE_HOUGHLINES_THRESHOLD = 210 + + MAP_SWIPE_MULTIPLY = (1.205, 1.227) + MAP_SWIPE_MULTIPLY_MINITOUCH = (1.165, 1.187) + MAP_SWIPE_MULTIPLY_MAATOUCH = (1.131, 1.151) + + +class Campaign(CampaignBase): + MAP = MAP + ENEMY_FILTER = '1L > 1M > 1E > 1C > 2L > 2M > 2E > 2C > 3L > 3M > 3E > 3C' + + def battle_0(self): + if self.map_is_clear_mode: + if self.clear_siren(): + return True + if self.clear_filter_enemy(self.ENEMY_FILTER, preserve=1): + return True + else: + if self.clear_any_enemy(sort=('cost_2',)): + return True + + return self.battle_default() + + def battle_5(self): + return self.fleet_boss.clear_boss() diff --git a/config/template.json b/config/template.json index 8fd8a1558..aef804051 100644 --- a/config/template.json +++ b/config/template.json @@ -669,7 +669,7 @@ }, "Campaign": { "Name": "D3", - "Event": "war_archives_20230223_cn", + "Event": "war_archives_20230803_cn", "Mode": "normal", "UseClearMode": true, "UseFleetLock": true, diff --git a/module/config/argument/args.json b/module/config/argument/args.json index 3f5c6672c..fbb932d38 100644 --- a/module/config/argument/args.json +++ b/module/config/argument/args.json @@ -3497,12 +3497,16 @@ "war_archives_20220428_cn", "war_archives_20220526_cn", "war_archives_20220728_cn", + "war_archives_20220818_cn", "war_archives_20220915_cn", "war_archives_20221222_cn", "war_archives_20230223_cn", + "war_archives_20230803_cn", "war_archives_20231026_cn" ], "option_cn": [ + "war_archives_20230803_cn", + "war_archives_20220818_cn", "war_archives_20230223_cn", "war_archives_20221222_cn", "war_archives_20220915_cn", @@ -3549,6 +3553,8 @@ "war_archives_20181020_en" ], "option_en": [ + "war_archives_20230803_cn", + "war_archives_20220818_cn", "war_archives_20230223_cn", "war_archives_20221222_cn", "war_archives_20220915_cn", @@ -3595,6 +3601,8 @@ "war_archives_20181020_en" ], "option_jp": [ + "war_archives_20230803_cn", + "war_archives_20220818_cn", "war_archives_20230223_cn", "war_archives_20221222_cn", "war_archives_20220915_cn", @@ -3641,6 +3649,8 @@ "war_archives_20181020_en" ], "option_tw": [ + "war_archives_20230803_cn", + "war_archives_20220818_cn", "war_archives_20230223_cn", "war_archives_20221222_cn", "war_archives_20220915_cn", diff --git a/module/config/i18n/en-US.json b/module/config/i18n/en-US.json index af6eb61c3..690eb97f5 100644 --- a/module/config/i18n/en-US.json +++ b/module/config/i18n/en-US.json @@ -821,9 +821,11 @@ "war_archives_20220428_cn": "archives Rondo at Rainbows End", "war_archives_20220526_cn": "archives Pledge of the Radiant Court", "war_archives_20220728_cn": "archives Aquilifers Ballade", + "war_archives_20220818_cn": "archives Operation Convergence", "war_archives_20220915_cn": "archives Violet Tempest Blooming Lycoris", "war_archives_20221222_cn": "archives Parallel Superimposition", "war_archives_20230223_cn": "archives Revelations of Dust", + "war_archives_20230803_cn": "archives Anthem of Remembrance", "war_archives_20231026_cn": "archives Tempesta and the Fountain of Youth" }, "Mode": { diff --git a/module/config/i18n/ja-JP.json b/module/config/i18n/ja-JP.json index c7b68226d..b98863229 100644 --- a/module/config/i18n/ja-JP.json +++ b/module/config/i18n/ja-JP.json @@ -821,9 +821,11 @@ "war_archives_20220428_cn": "檔案 吟ずる瑠璃の楽章", "war_archives_20220526_cn": "檔案 诚閃の剣 搖光の城", "war_archives_20220728_cn": "檔案 鋼鷲の冒険譚", + "war_archives_20220818_cn": "檔案 結像点作戦", "war_archives_20220915_cn": "檔案 赫の涙月 菫の暁風", "war_archives_20221222_cn": "檔案 積重なる事象の幻界", "war_archives_20230223_cn": "檔案 黙示の遺構", + "war_archives_20230803_cn": "檔案 燃ゆる聖都の回想曲", "war_archives_20231026_cn": "檔案 テンペスタと若返りの泉" }, "Mode": { diff --git a/module/config/i18n/zh-CN.json b/module/config/i18n/zh-CN.json index c48b283dd..9a0dd5810 100644 --- a/module/config/i18n/zh-CN.json +++ b/module/config/i18n/zh-CN.json @@ -821,9 +821,11 @@ "war_archives_20220428_cn": "档案 虹彩的终幕曲", "war_archives_20220526_cn": "档案 泠誓光庭", "war_archives_20220728_cn": "档案 雄鹰的叙事歌", + "war_archives_20220818_cn": "档案 远汇点作战", "war_archives_20220915_cn": "档案 紫绛槿岚", "war_archives_20221222_cn": "档案 定向折叠", "war_archives_20230223_cn": "档案 湮烬尘墟", + "war_archives_20230803_cn": "档案 奏响鸢尾之歌", "war_archives_20231026_cn": "档案 飓风与青春之泉" }, "Mode": { diff --git a/module/config/i18n/zh-TW.json b/module/config/i18n/zh-TW.json index 4fed5f6b1..3f35efbd0 100644 --- a/module/config/i18n/zh-TW.json +++ b/module/config/i18n/zh-TW.json @@ -821,9 +821,11 @@ "war_archives_20220428_cn": "檔案 虹彩的終幕曲", "war_archives_20220526_cn": "檔案 泠誓光庭", "war_archives_20220728_cn": "檔案 雄鷹的敘事歌", + "war_archives_20220818_cn": "檔案 遠匯點作戰", "war_archives_20220915_cn": "檔案 紫絳槿嵐", "war_archives_20221222_cn": "檔案 定向折疊", "war_archives_20230223_cn": "檔案 湮燼塵墟", + "war_archives_20230803_cn": "檔案 奏響鳶尾之歌", "war_archives_20231026_cn": "檔案 飓風與青春之泉" }, "Mode": { diff --git a/module/war_archives/assets.py b/module/war_archives/assets.py index b95de8d8c..b1c41af68 100644 --- a/module/war_archives/assets.py +++ b/module/war_archives/assets.py @@ -6,6 +6,7 @@ from module.base.template import Template OCR_DATA_KEY_CAMPAIGN = Button(area={'cn': (1188, 107, 1272, 131), 'en': (1188, 107, 1272, 131), 'jp': (1188, 107, 1272, 131), 'tw': (1188, 107, 1272, 131)}, color={'cn': (104, 101, 107), 'en': (104, 101, 107), 'jp': (104, 101, 107), 'tw': (104, 101, 107)}, button={'cn': (1188, 107, 1272, 131), 'en': (1188, 107, 1272, 131), 'jp': (1188, 107, 1272, 131), 'tw': (1188, 107, 1272, 131)}, file={'cn': './assets/cn/war_archives/OCR_DATA_KEY_CAMPAIGN.png', 'en': './assets/en/war_archives/OCR_DATA_KEY_CAMPAIGN.png', 'jp': './assets/jp/war_archives/OCR_DATA_KEY_CAMPAIGN.png', 'tw': './assets/tw/war_archives/OCR_DATA_KEY_CAMPAIGN.png'}) TEMPLATE_ABYSSAL_REFRAIN = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_ABYSSAL_REFRAIN.png', 'en': './assets/cn/war_archives/TEMPLATE_ABYSSAL_REFRAIN.png', 'jp': './assets/cn/war_archives/TEMPLATE_ABYSSAL_REFRAIN.png', 'tw': './assets/cn/war_archives/TEMPLATE_ABYSSAL_REFRAIN.png'}) +TEMPLATE_ANTHEM_OF_REMEMBRANCE = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_ANTHEM_OF_REMEMBRANCE.png', 'en': './assets/cn/war_archives/TEMPLATE_ANTHEM_OF_REMEMBRANCE.png', 'jp': './assets/cn/war_archives/TEMPLATE_ANTHEM_OF_REMEMBRANCE.png', 'tw': './assets/cn/war_archives/TEMPLATE_ANTHEM_OF_REMEMBRANCE.png'}) TEMPLATE_AQUILIFERS_BALLADE = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_AQUILIFERS_BALLADE.png', 'en': './assets/cn/war_archives/TEMPLATE_AQUILIFERS_BALLADE.png', 'jp': './assets/cn/war_archives/TEMPLATE_AQUILIFERS_BALLADE.png', 'tw': './assets/cn/war_archives/TEMPLATE_AQUILIFERS_BALLADE.png'}) TEMPLATE_ASHEN_SIMULACRUM = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_ASHEN_SIMULACRUM.png', 'en': './assets/en/war_archives/TEMPLATE_ASHEN_SIMULACRUM.png', 'jp': './assets/cn/war_archives/TEMPLATE_ASHEN_SIMULACRUM.png', 'tw': './assets/cn/war_archives/TEMPLATE_ASHEN_SIMULACRUM.png'}) TEMPLATE_AURORA_NOCTIS = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_AURORA_NOCTIS.png', 'en': './assets/en/war_archives/TEMPLATE_AURORA_NOCTIS.png', 'jp': './assets/cn/war_archives/TEMPLATE_AURORA_NOCTIS.png', 'tw': './assets/cn/war_archives/TEMPLATE_AURORA_NOCTIS.png'}) @@ -27,6 +28,7 @@ TEMPLATE_MICROLAYER_MEDLEY = Template(file={'cn': './assets/cn/war_archives/TEMP TEMPLATE_MIRROR_INVOLUTION = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_MIRROR_INVOLUTION.png', 'en': './assets/cn/war_archives/TEMPLATE_MIRROR_INVOLUTION.png', 'jp': './assets/cn/war_archives/TEMPLATE_MIRROR_INVOLUTION.png', 'tw': './assets/cn/war_archives/TEMPLATE_MIRROR_INVOLUTION.png'}) TEMPLATE_MOONLIT_OVERTURE = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_MOONLIT_OVERTURE.png', 'en': './assets/cn/war_archives/TEMPLATE_MOONLIT_OVERTURE.png', 'jp': './assets/cn/war_archives/TEMPLATE_MOONLIT_OVERTURE.png', 'tw': './assets/cn/war_archives/TEMPLATE_MOONLIT_OVERTURE.png'}) TEMPLATE_NORTHERN_OVERTURE = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_NORTHERN_OVERTURE.png', 'en': './assets/en/war_archives/TEMPLATE_NORTHERN_OVERTURE.png', 'jp': './assets/cn/war_archives/TEMPLATE_NORTHERN_OVERTURE.png', 'tw': './assets/cn/war_archives/TEMPLATE_NORTHERN_OVERTURE.png'}) +TEMPLATE_OPERATION_CONVERGENCE = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_OPERATION_CONVERGENCE.png', 'en': './assets/cn/war_archives/TEMPLATE_OPERATION_CONVERGENCE.png', 'jp': './assets/cn/war_archives/TEMPLATE_OPERATION_CONVERGENCE.png', 'tw': './assets/cn/war_archives/TEMPLATE_OPERATION_CONVERGENCE.png'}) TEMPLATE_PARALLEL_SUPERIMPOSITION = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_PARALLEL_SUPERIMPOSITION.png', 'en': './assets/cn/war_archives/TEMPLATE_PARALLEL_SUPERIMPOSITION.png', 'jp': './assets/cn/war_archives/TEMPLATE_PARALLEL_SUPERIMPOSITION.png', 'tw': './assets/cn/war_archives/TEMPLATE_PARALLEL_SUPERIMPOSITION.png'}) TEMPLATE_PLEDGE_OF_THE_RADIANT_COURT = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_PLEDGE_OF_THE_RADIANT_COURT.png', 'en': './assets/cn/war_archives/TEMPLATE_PLEDGE_OF_THE_RADIANT_COURT.png', 'jp': './assets/cn/war_archives/TEMPLATE_PLEDGE_OF_THE_RADIANT_COURT.png', 'tw': './assets/cn/war_archives/TEMPLATE_PLEDGE_OF_THE_RADIANT_COURT.png'}) TEMPLATE_PRELUDE_UNDER_THE_MOON = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_PRELUDE_UNDER_THE_MOON.png', 'en': './assets/cn/war_archives/TEMPLATE_PRELUDE_UNDER_THE_MOON.png', 'jp': './assets/cn/war_archives/TEMPLATE_PRELUDE_UNDER_THE_MOON.png', 'tw': './assets/cn/war_archives/TEMPLATE_PRELUDE_UNDER_THE_MOON.png'}) diff --git a/module/war_archives/dictionary.py b/module/war_archives/dictionary.py index d7cce3888..6c965187e 100644 --- a/module/war_archives/dictionary.py +++ b/module/war_archives/dictionary.py @@ -45,4 +45,6 @@ dic_archives_template = { 'war_archives_20220915_cn': TEMPLATE_VIOLET_TEMPEST_BLOOMING_LYCORIS, 'war_archives_20221222_cn': TEMPLATE_PARALLEL_SUPERIMPOSITION, 'war_archives_20230223_cn': TEMPLATE_REVELATIONS_OF_DUST, + 'war_archives_20220818_cn': TEMPLATE_OPERATION_CONVERGENCE, + 'war_archives_20230803_cn': TEMPLATE_ANTHEM_OF_REMEMBRANCE, }