From 56c094a2d760195c589c16be9fbfd085e2aa0bd4 Mon Sep 17 00:00:00 2001 From: "Melvin \"Dumbass\" Shwuaner" <83349478+MelvinShwuaner@users.noreply.github.com> Date: Mon, 9 Nov 2026 14:57:06 +0300 Subject: [PATCH 01/14] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e3c854c..02d647e 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ The logo is generated by Image Creator on 2023/10/13. Inform the remedy if there is infringement.
-A new mod loader for [Worldbox](http://www.superworldbox.com/) after [NCMS](https://denq04.github.io/ncms/), with an Android version, called NML +A new mod loader for [Worldbox](http://www.superworldbox.com/) after [NCMS](https://denq04.github.io/ncms/), with Complete Platform Support, called NML for short. Detailed introduction look [Gitbook](https://markamibox.github.io/worldbox-modding-box/#/index).u zaa&k9mbIBT6JiBcK1{X1z5vNs@2E{R%fd_#x|NHW9y5O9)7Zh=%q;miO*LE?8aAH7 zARZX`I*N+&sv(G%7h`22KF}(&O6hq6#e8K}KYpPNFLdBl<5+*I zKi*=sO2H@MQC81du13xks4HGewTe+!yzzO+a(Y>{#459c=m5OgTB>SZp3^i4W}iF- z MA=W@o_2X8Ysy`$)kg7k>s&}eC&>G^ceuLFO)vpI1S08z})wfZ78+i^u z^&73mLr$gY*I5H)^#?(x?D#=B@wiAt^ThI$cTv(~Q`YOgUu1~y!&nB8A4#4W%G#IM ze)Ir8rORoe0}p%fCAKfgMhAuc+xzw t?n-eTj{I4ySC#Gh3gQqxNQ8mu~%vPQ19;7d^ze=)2z$ThL z1MqL}! %-h4$zh=6XiJ;D^+K2$zF}dvCju^_YqD076a@Gb1?R#iNVLObgF%) zv~=`oJS`p8;OI||0{d(zGVP0!S@9m#WboEeUObR6?HP76vH0y9(CCpJ!=hM54bG=s ze%j&A@w`{en^0ybvLhNi6P1t+#(U7PT6$x;piB(JybCi7h^8Z*{c}?soslQr1YO|G zwGp`*Af5?gR#^&7 he1wxH&g>#jZd2iF#Otai*CrmMJKFUR@5q6#+M!xO z?cq85a%JVhM>^?U@N1!`KG|M{k^W)(L6j1fL 8jJW z0!+Ni8$m|+0)#9FR+fHQj_au$o>zi7fa)&-G)+;gp$E=P985i7+QTsG$cG~SSYSu4 zEVlhiF2^gpFqZ9MiGc@;kZh09V#+1_Y9#vIC+;@zJ{#K@_E!++MG_Z7b+m~h9epLj z3#~CIqsF+O!wtNs$kA9%Xyjouu07FM$8ee(DbR`}?qV%-p~d4pB?E<6k;FaBa4<8t zep50~B}+u&0dPpanK;9uGKHDh^_Y^G!m5a3c!#|(EI@`Ul7RxMNaAeP@B}kpTzDBM zl!_#}nc-$;aQ&myKtWU_v6dOuF@x(FB?Gy vHC+1V=LLr&Yrg1UU#l^yIwEUMiM{-FAprd1<>EiJybYugXMUrD+6< zi=dUK*2ud5fP(axf @-XfeYbtINUC3d$`Vi&w)o4A|lWjcM7!Oy#^_&`T_ z;t3{K`1PTI#51_Zd%L|v;%|1ykuJN2p1jc5*2OQiK|AI57IblwKIpeP;$XRkYr}OA zkL`wlekq5fB^ctt#4f0e#*g7jhW-6*Sw*4a!!u^Q5}S3KV?N=xe4fg}T_Iq@*bd>f z;aB~MkD)@nYpg2myhEXj%lpo^GVuk3(q rZ^@INR^|G~2SY^ds$&$D5b8O5V@ zEw+f&oXG9yopO0jrpAN4)0}Ic0VQfW=Cvuds+=?yE>2FzoQ@|}PCDMYUFS;Ey4IWK zvsb00W$I1N&grtno|!v6&1awG(VOz_KbG^dD)c-mj&j;uM}G1b7IrDZFF!v4)a_Hi zin)9s9&_4Fuy65Ixq6-~@cMF5KM{ow!n3Iq{Ru}uwK2sVm}k+3_z(`(lsdghHxjDs zWniNn3&DG~^n7bHc(Ht8UOd-41YA5Mv3*;Yz?*r?p@TQrR3hKYdGAp0o{4T^r9+OO z9^*__P$ol$5H4@2Ox}L&ate#QGuv>bo9fgNJ_+UH!JuL 4yXsP77d&d=ohi3_1WaT9?3L)2Jx z;vQwNxo!Fr&ydV}*~*l$Olcux4g<(4AH)vG=M<8;Fk2af5RlnQGTXD2fv<(k7bH_z zlx5lIiJ(6*5$uWO*~(yd8!}r+=J7Nc=UFly6O(=YnBqh}uad=?6S6_XtD=Er`5{E& zW75Bctk=-}&c_r2_Gi#LgX|+sh8{*FcK0oV?REdmK4j=2O2RDeGoRg%nbn63J;+Ez z`HW>qCYfa3t#bmU#~{eYF8S97;6w zE%OCrR9hSL9 |<;eF~su;{j%tQUepPkG+T&~readfraaLvuYML)K%zi=^jd6yfy2 zfhl?XH6xFM`pjcjN*>gg2dC(HFGCMz?>^e@{R};rOFVV{FhdU} ~>D$CH* z_joGL(33izDl_!-J)Zhy=t&(<{WJ9RJ)Wvl^rVcZS|okrcp8wAN8jTKPXyEYAay(q z%+S;Kc*2r3O;7508l0i0@9{JwLr>~>YRJ&j_jqc|(33iz_RG-I_jtlYBJ1TDPuTGN z*71Y`P~R|~aJVdWJdI_QJa6IThnoKy@X=WuiEv)ql|u?VI>)`EcpTG#AgmICykQxM z*X#8;4L+<+8-2yS(Re6Sd>O`{){Da)SVGv-pe?!Xka{qM!moY1o@$St>3!%KlcgSn zkZyTq^r2^LmU<9cyLzy@l2Na5S?YmLboI>XL(lju^ Y3Yzo(Wm%p |$IIo^ml)C |tGxuEc>e%Xb#+)3jkc;YJG>tW04>F&$5!vYSQG_^I9 oenW02g2`Cc)?CnJH z;X{DMyai+bk#N5}kxs{d C=B z6vbh3*#_w{WLA4C^SgbJc{U4~)IP=7Nh{g6_vu~xAVZ@rwFNTsan=Id*6!Nl78skH zS!k@&_(=8zuj^ARa!-9h{Q^n!-zYX-kC6L4{+!&@{!7Xnxeqeq_CaRSKFCbm2brVx zL1z3u$Z$}K$F#1?$fB)B??XNlvXGI#^WfNyeIP{A4AQY3d|y >+UTUWMaVlH;A%XWwYIefz3yQ~*Bh;OKPh&9r$h!ZQ@)drI^> zAkMtu=uF)U`BjEaHBZ8q@jgjbI#bu=k7ej|?A5e+y`GiM)OGda89E(%Hf>&WXQeZB z&5!r`)7sOqchlzmfUI<;uG^o?(CLf^)8;jORytGnW1h~?>5LcC=DnJ%bf)fS;-o=Z z-JS7d+PpWDl};HaI{SFrGjuxR&9r%MDl45l-rV{5xeT4oc*O5zP}(=@bjC??>;)l% zqeFW&X9V^^Cb|zYcvo+)%a*?nGI{$Tld}&pya~IPZ5`T&d~&mpNt>U)%nTU6b$;HR zy^Q1UYz;+AHBom>lO6{+{>=7gFXQ+t8*eCPn~&p 9IOxXvSsrw)^c^_nE zW+jtm2WMvr?a2<5ud WIBLSZpNxTH4!^Y#3Zc-me{KLgb9e% *J@0TrtVvP1YL5?)p+iOt8euvzWP^>#&rmOCxf`@O6+tce!3DrU5THr% {;34BFesco;r^+c+(e%1se<5vc8TFyp` zqr()f1JAI+9e7|Bj>f0p_ayO%D(v}0iw|$X?l?KrfiwO7%Ax(_P5ID5c~dboB5&{{ zk&fWg6Dj=q6hz`U$Z1c5uEyJU &6&IjHs)LG=P95gAF~`ww@bT{y$}`~u#qsCx zkz?#Rhs8x#%KjUocVKFxpVyS%md4JGIB5^{f MO= zn`M>s%%MSyUy&?-_xGeNQ28H))|0a;KW6rDPJ9W9fcYA)_)ynl77kP4ot`fcK~Uj? z!m7magH>Nweslj*RekAIg^vk0UM8zrm^AvJtZFc|s`&bytm`1L@|t8_Z@VCDVl3A;mJD2jN5ke *+*!qZbe8O`dpYejvsyq-41h)QomxbD4d!xmY# zJ?Pr|x|1TO?sQdk&(v?Mrov`a+UcXhDp_ZWFUV=-QaSBWuqzo^ICM+{pikZdeM$;F z3O%jFU(B!SvLgIWC!ggAAZ-z)6(;o)ZE+v8C22G&AD4sQtVzlz>BXgDd0+Iy9D2AI zjYaz>7@DFD`t`Hm+40lk5&W#;d>B<19>P{c^|Of@4AAQ?al9RIz-!dTdy<1)?}Z$k zejoV}^_%lc%6aqqb~#K9edI^fZ_Y0%=glue?hrlEj@DJb!af8qYIBR$HyQ)u0iy$U ziLNIql{A$~=RL5mpw5JxMXF^`N>LPHN?gS0Ck->?dH;-b422FEZ^CaY6~Q%hk9afj zG)l+OZ8uRA8S$n(lM;ihL3XB&_?h^5XtTsQA7%1;N<1c1x*oSm)bC;ITMF&@FnqTh z6>eRU@6vII9n@V;dS9ZS%LhNq3?7{@L$6LMpUgi^CvqJ#^XM@ejR^eFm^*F6&|yOl z7 *o z^c#Q>PX9uRPWNbc_BqwK4pKOVAM;Tf@nDU_?F+T|JCedt{Q1QcD^cthrTqy$UqtY% zQi5+55`3YG>E#4_EB;Udo_xB$sg&-YWjKN1;|xnJqMuYo@IHn=%_aWPf}j;6_#*Ce z#lb}b^ZjC4+2R_%c#?S%%yU&S@r+~6u?+8L`p+1C$(%oDSX4%wdL6+>a?2{h;swhr z3X8u3`o(ILGc2YT{0;PXD*slID^4q@0B0v^7Z#5){bhzX _%hqExf#<-2znA;P$=2V?b48?->hc5euJ)$*XNeGRiEGQL zZSO7LP?#$&D5TV5IaSgx#Jyjf!8N)*_lr`$IDjeVFl8dc+1xLyj17f;@nHewSRW%; zgM0^Rb1_8x;%3khWz>=WUsyNRQIGzL0D2t%p^KN~4$Su{EML^3oE9)2IP%4OlncL; zjqd~yR$M
dhS|m3{)NtAn{RtZ{>KVJQWSaRZeiwF- zZq($9zd&ypPP`7~v>$NV(PDqb5{yk1O*)nOm`c)ej5wTgpOH_wA0wtRXI_NTW&k73 z@*;^%=d@ 2fHS~UjrSE|kj{440kcCXiJk$MO7oCu!bVg$o?QQP6-)qH~eA_T{j z6I|VIJZxut{TRTV+9N(}fas3_F01+t;4h1w1bn3Ew}2NHZU?+C{5;^v#U!;muNE-Z zBKQ=vS)#LMiDij<>IlAGw#4%LU(lZP&FQ|j^mo>r?w=MC+`{k?hMyQj*~st`hFgn> z@*~_kvgefl6O`j~2~J{oOby*186-H8DV5B#)F8^IIRxi%>g!Cojp1PM)QIo pj; 68xm(W%edU{>yt>s~qKw^(;`{(9^>R^qzg&u4`ZY4(U^lC~yA96#` zS1pV^9(+AK0w %;&nAK}MXi9v1= zu;W$QcT4l(HI^{;xY$2;6|je0&U(BJ{5u!B03Kx*V=})yQCCYjP>lv_d7=d~tHch| zEb)66TZQ-Of;6>(b6w@hT9If{SWDz0tyo;Bus;-zz-iRG89QG*QgsE=ey_0o>VFLE zJJ^yFVngYj<<|qdf-!1|n^Ul#YNejEd$n>8_7Il8Nx8?hD)CcS%QITFc+AD7iCR%U znDV0>{-_NQBN_XPM(sIJOqOZlz~Z;GfnvUkeW2N5rHehI4H4(M*ymb % z*y3UzXv4&PF7}MJzj)NeKG#Nw?FxIVDy$zQcDb0PA1ru73qAdHRjJ;D&rNZufmQ2= z&^npwAS&>3`C;NP7qj%k1-~GQw1Il5euQXNX#@3YeUw eS%o)V$<}AqDNtVeYk$Kc+ABP)u)KJU2MEQ zO_+$ms1AO8nm%1rGqzUL*3^p`Vw{Ves?QW3Gj^_6UG ae(z$I-YV`tSf>3IeY8mIbg^oEiKxWpE$Q^>&uFKJi7xiJwp2XmV&nC8 zvCGA#>C46R(NeA)eVY(xyO^bSiuvPZT0Q! tJPj+SXng~N<9#f6Nm6}Q3)&JuSk?0HzhS>jp7Xmr$zv&2ru&J{=Ws~2aBVUtM< zwe>WyT68hCQ7n$FG1iFn3R_kDk~l})!q^6UaCxn9uGp!t3BcBh>M5jUqZnCsg>iwn zN@0V`HW?R*CJMNbRu1eE@ruG)`}G(b#BPPXpMQsOg=m^4Irod)V_Ye&V(d!MR{or^ zQM|_()gd3dl%Fvs{mUlt1h$JQ2Y>y`#wM{#VQ1&QZd@&**dL~}%fo*&t`QRz_DpTA z`C~D0rcC>C!13mFq6=GQ8wY@#YrMbDYHPsp&DV7uzTdLs~E7ZV*khbO82zO`-25 z(T(jd!XB;}X51|57D#NFcDU~rF-~C KIVyD8Wt#^ps3VWvZ zB>!u|K2_#Nz1b^PDy+A*#s7x*u8ZZGJH_P+qh9%oxI O>eO$l?|sprFzUa*i-`);te^Y-A?7o-LEKZb%KxdjU!~nsbAkU0vCGBQ z`~NAbmr0%X)NJtY7PDMzqyI~Bp^IJZ|4KaQVm 4*H{s#bFl}) z*K0}4U*^RQF8`5-Q_J5HsCVV^^LvbeF19PyV+?Y!`(if-Y=vDZeg+KZXSqgKii2zJ zz(WqFet&{o68jA}<8Iol!XBf+#l{!j9B6d0YpN!Sp)PiK-If5hOF0Ml!Kxl(xHdxd z*nL&^1@_lwx!ALT16|Ii#H#@u7gutRp*?Y^TVXfGCW^ycY=UO{k8rWw!uF4LF?{64 zKhDKoM%q!@*($%@!gYb8RoVve$MSUnJoi>P^cMalfT!&WyG2_Uz;kqkRrI^VnC4>L zMOOrHHbJE=05;vlLf|}ByGrGEa%fjzhIY4$iQsIPb8R#loU6T}(yGGu1y0m g4oL2+QTHOlDaHE(SE(^A3<6NvUh;uorEO+IM44$GbRcW_}#srsX>s@S4aJkF* zPIN)AQ@dNGtq6AnPt$(yV&?}}xty=(ToycA+pW^7Le~V((Ml7tET0FB(0N*ui &hJ)9T2)uo3GNI3k?fhtaZECxX`68XJyXx&<5=mmG)`qJE5zzCtPer=m#$6)ST6! z&DsZ!mf-h7Khp9$Wm%pJUK{FhIjf?#g|63{RNC6meW9DQxi0op=vJ5W-sm4fcWCFR zv^#>mp*yw9UF`3npShg7B43B@ak0bv!SMYqc2yuZ{Bsw3+&@t~s6D8(H2Dg{54mao zFqen7xmYxCTKHEkRvbJ#{FsZq7&tHdxQliBFAP87V$%YbhM#n?t>#tXr(JBae{=X5 z7rQ=iUHDlSd(nSO`1jh2s$}DRcZUDqrkTEI l3R@N@QK!-(gGL{ zpJ`KE?AgFSUCxCV4_|3rDs3djgQj2QVvRw3`Bmxs0mef>e^8}eiSZEDUvaTHL3~46 zaXy9dkguC73Ee18#CVA5buM;(u-N7NHO51kK1HR4Fdi!PB?@~J #>2t-D3$gL zjE6(?`7U;C=x~=)!+02_U#QYLFdoM0x476-p$RVM)ff+x^xvtpA7DI8(R*F&?;-k{ zFaFTe&tg2xaIpf6huJQ63dX~6F18ut;dniIx~xM1#>0tj+A|mr-*K_O_)iPZbFudV zXNQ|z>}MDc3tj94j0gHqq%6xojEBW8whrT=&BX>`Je=xc=U_avyVzEYhZXujRkC`F z2m0>2)cJ-PjhyacpZjBxGhIx_cv$UXk6}D?yVx>}hx1+R5R3=<;-%DiHO9k53fmxz z0gI#S^${xfFtAHp&ZBFWMK9Ios zL727Df+?>Nic-x%<9bfZ4(3_>@G2M6TmY;w~c98jF|L;Vbuc2Dh~oU7fmdukhV zuFz=E6`^y!N8iUD0Y zH|v{R?5vzyUCxhc&&|2b#SW{zAm?@$E2#Z*&K)i`e869Ge&S-!5BM 6--#oh<@fQ$VG*w0<;5y<_*#k!F8po Zbg^x!CvmADRDwi*2o*kWat)g+F+y^<`7@ z|Dofv%J?H}ZvJO_wTmst|6FfkY=c->yDt9=eXUB pRl=7n}HfBs$7)9cR##)6@d|hPRuP} #? zGZaRiz0tTsVdSBQ8NCW4PkVq-c&@ =U&-c}gRN7IbT^Q9J=tEL;%6-M*e z3}darXvUjm+^;a28|N6i6h^b?T%&re)Izi23C1ji(L8;UvBbsx9-3!dqcDo478nn@ z*t3CF;{%0JM7G4p|E| mOFxf4?S-jrZ8HkzG$4}V$TL%HZE5ft#)5A zwz`-IzGm!H7_I-_Fw9G&&gVkoLVq@z91OPfwlUYmt_}UwSg$Zz4ZdgG;bJR79~!+1 zqgCC sw;T7`Lwi p+4QKVC0u2 x!b`ISq(A0`|NRZ*j21ExVmPk6*s3VY+D^+%Ng4sep`3F7B`6x z^Ly~3niYY#`I6#%zl=BwzE6q#jG-WIPGW3b@Uy%TVz_y%!dj|MC>U-Yudr)k^MExg z>?NJBHieZ{Ed;hgVHcDy2DXYZ%3%$#O)8CY7-9A(jB*%Z-r|uPVQzKhHtHkHM^xGv zvsWBwKF!$U!H)|G+q9ADur9cNK4CW~Y$(cdpt OB>QIXKZ6IY?S#AGjCz+%HTzLU4@64+Z1*WW2A#(uw6QFz9i+u;)>Pa z{6Jw-^z(py>|z@Wk8sl#>OU$x(hUBH)NB+B^*akkyJ^Gpdke>yl`3tR{&?Y7bC|-8 zEqV%=lf#4h_QG*4_Gr ~L|71xVn%!!O`5cgFs zwWgbE8QUnzN+Q5+P}qSbKMEXcZdcePmD>wvn4h_6CzZ@J>v~A%MsZ2y!jjn-{hD~K ziq3oA6sG%6is+swnpoDKAdYu|0&~Xw4yHd09!+cpT@&qjl&V+K{Zp(#LP;-Vx|hd$ zFZH~~8YJic kuCG@ zE9U{+Ylon0I` 98 !$9PPUo#?{g5h}-#7s}KKa|Y{3kA$-1 z(#E{CAWCX2WbHEPvUcA3X459wx0S4gETM$o;Z~Z?eM->j1$j@JHIck`dN7^h)K1c+ zEhX<$r80Xk*$YlfCQGOb+0I1i>pq({_tx6mQ`z)_ED8A>U7UdSaq1%5Eqh31@OlPK zJX{3NE~JKk$Ng^ZyTe1&gEM>t<+vj+ZKyFNDdb(f6peoqR2R2mCZlpDWofpObCxFB z*z*5cp5&37-wYQ)r!H<_%~AuEA+>C>&Ap}F6D66K&b4#&P~8o2342$mXKyJ(ctm*N zjTKbR_qo2AkV>Kp*|xH@|DpV+HU1rzAY&nEUH>od4HbzcOY(n*l8tZq507{J{--te ztu^Ebm96*x^4=Mn$&&ovp?G8L^m{}p9G@iV|2q_!iy?YBPN3X%&%G1JCQG&Vlpc=E z_XWyW$WW1+EZdz}2gx$%;(z X=grr69+dNrgrr9o*K(?ShC-Y=KU;C6GAZ=rMHA2R z{3SKZ`|lb=&t@O*HJ0_l$t5H!;ZwXDO!vB2$@fH|`+yja7g^~Yvl>Bfzz!B2RZVyk zn%>wNDR!2Q2TasW1cly#9Vyn}elRGVpxl@LYy7T{zv4-Jh2aD|wH=JqPO(A^>-QY! ziMp5YCAce?=X5-Oog`Kj?_~Y&;(ovIhj{OQO`WE#z cd!}KX2xcklf=U) zb4a_qDBv3`PODn!n z9fDDzBW`mqd;2OJh? fX%CgJ%D+fk zSNlNzVDVO6#JY~9ZUsEF;AQPkWj`%gD{ilNs9?Rgy8QWqt3+|l+khw6^op0YSpPS) z2Q+#PzE(8WT%^6Oy;B;BUBj((jrhHOFzyErI6Sr%vdd#PK=!+_JH({e+XZ)s+`7%6 zke&xP$GagF77sEE>BH)_LaMF!{n%i=Dt|@Ma6Oj0wrH^48Cy~G7<%*I*hu}>@>5Gj z1LliKfSXE=2do#(Olf17D~5@Kji9(nJZ}Z@cHj$IP+TKk!hMf;74Qb}2H-8?Ex brBWq1t3{TLQ8{HLrJ!wVTc z#(KWXWjK`K;bo+=oZ;uCbpH~=dl_zEcsj!q7#_&5nBndc;_qen0K;1V4={cV7&le{ z4ltH8{RGxOk8?bo?|;RxiYXsgke(+Q-puekhKm@EW7v } zhJxXrIhU&e$Ev=5O}1(+Y50>(@NR~eFkHm&NQR{hKODqmV|YEovl-52IGkY(Lm%t> zbRhBTg9*OM_k;QVbcVl+6a7YpXE8jM;UI=z4x!W+8Q#h8LWa!@4`CQ%xQn&@n&Gt! zr!)L-&M}wEb1mOr!=>8B@Lr~DsiRyjWVo2&kqm1X<}iGF0P)<-a6Q9Q7|vkW!0-{~ z4DkI&e7|2kNnOmjoXYSxh6gf?F?^qSo@00;!_i!}?=b9SxR&8%oVtwR6o$DBU#T6d z-HtK7Q2Q@!hwpsAPkq-j<$CQ+?Gyj?+F!M%!1dbSwG#u6DoFH4nQrJrH}t=1zpxDb zO>Ld^rao4GK^tqlsr|8VtnpW^vZ&7dC;ZqA3|oAB(pWjDpVa+`wdgOu@MUlD$qr zqCCR%N0{=uf<)JX5)yw+P(q@N=KIl{+N>a@p3C>=a_V&o693L1m7y*~a3{mMFx`(1 zlho)i@iZ&QdiefaPBkOMIga5C40kfDixRy>!W_Eq&N&e+d;{O_WLTF=^!Y`9)m8@P z7yT2d-3)seZe!TXP!v;YHN#O1=QHeP*u!ue!(N7>g!vhcVmO~+H^Ux=+ZgsT6s641 za1_J&47(ZjFx }J@*a2vzk{xKbsdNu1|IEvwXhTRN%7;a miZZWGwfwJY5>uD7>YXPsf+1{N4ojGm*J>-=3yuX(*1mf-3)seZe!RxFs5H0 z5rbF{!%+<9Gwf#A!*CnJUWUSEeuks$nC^?t=lgDkJq))o>}4nhGe5&o47&%%^v-BE z-*00mh7ivvhTROeF%)s8Gn~(G8^c}&WBMgIqJi}@9K~=x!)}H>47V}tWhfe%pW+ zm|m1SpYOXF_AuPWu$Q42%KQvRF`Un^duU8wliS1h+ZgsT6#Fqh!%+<9Gwf#AvtLXv z%iG5Hy|}+WPYh#zhNBqHXV}fKhv7Dcy$r>0;_qQNYJa+)?e4?{7Q>0`+wbu;W? zxQ$^iLotq0M=_kwu$$pFhGHW5?dqeMhv9sN-3)seZetk4s_(-%t(xRF wuRma{U*92`hL`( z(=TU4&g7g^a+c;_k-sJX#r${jcjw#ILDr$xC~LfRv~`R%%R1gV*;;6=uuiwWU+}kr z{Mf|Uo3Vz%{R^84Clr3C@QlI@g|`(xQg~8P6}QJQa{=miqCxPT;ssbSYxsJRjxUSR z?}i6NA+RD~#rQT;DPS2|ryT83DXJl1MvefST=bzICmL&3V^?`c9l=X#&I9~=8Qt&B zBc3HyOA7>6<0}AP(FyjeS_yb@`6@s!kEBd6F97|sLV^e76WpKq`&E94mH0sny{S_3 zwG}h5NA0CA>)!!Nu0bWdB=1GsKfv&m{9}sp#SC4?*PxCCr0*sgsOK!*1Z5_mF1oR2 zpy8yZ50u%uAE|Qyb$pdA09dSt088} <_ zgF<6U{%PVTI4hd|*95NgzZ#~MsPT7{c%GF^QrBbD^;mU1PE5q^5Pf}KUQbll@2KlM zb!}GHh3eX>uFJ#)`INyjrLRNb9SUCoob-39>q?crQl+1+@Y5B(O7Wegu9vCn26eqs z<@ lOV*b-h_#Z&lYj72jLp87}AF6#l-teyOf;O{O<$vOfE1 zvb}~gUMflqYUfhX57#U3&7`aFZzKL~!oMx}cLV<2gnzf--=+9>IsRRXe?9oup!xKl z;yM)9A^3N^IKo^m#^B#k<{4r#uE*d?INc}k?=<{76aUuW-+B1A&fE?8zu@04{Cf}o zij7(M#YV!s826XpUnTHL;3q@RFU5 a7 zok%pV0@ktMl;L9G(&jVIgm`<`0sD&yE87>&-`^42UrcUYHK%#$%GT-4Z3)oFwXweD z#3~?=-d{@ZFJ^T>{-6=0W%xl XM4q+}m#V>{YAyAms@rBSAZDcFqhQ^t>-HR+gX^Cpg;GJX7vd1I%Ho;h>gw9!+? zQ|07WVrS2qAV#;hBs$t!j-ED&s(EztY0Yz{im^))9m`senJH$8)2Joq%@bprsh`9G zw9`T{b5& $0I^JC>?O=p1@fYkO;=ZK0Sqwt4AN*;=BlQ{BvS+d|Bn=`^O8(Yj(~ zYiHN2j@g~9Q#%&4Eo~jw+|@j~b5;97D$D53&epE!%?nQ@C9RS?uH*Ffr5(*JZki;I zUb+-tA|8K6S8JlZ8M${PnisduXl-s0<666#7cLpQGLdL)@0ztFLA23bnY6LZ?F(C% zx@w(##ORh5vADHs-hx$Kt(^|FwMC5WNVLvwZ|hp+ig;5=V&OM(G`F 1wPw;g+A~;3FI?E#*{S4Uz^w_iz^TyD+D?NB1>_3hW wna?q z=$Zs`LFWJ&y?i XJKh%c2R ziMcwGB)23<61b8G(vwJ{b&<^Yum!31cf_gl=8eJ7z^9%SgKD #HE18y@$Aa@5;_x(ve7) z_Rxqgl_QBQqN$R+QENL~wes!oOcOd*f*@x<7oEPec@??#R+p0E4& V zqVo{bP}u|01$ekJ2$GM-yoW6V=YWBRvWLloV#1YijY`H)_b{qFcz~pkX-uRLoFU*L zlHGeysY}_ghn`81oMfsVwlq}ouq}F+(s9WpP0hoWLV#g-lB5Kz%R@`WBnR7)hsTRU z $b+g$Yh3GTZD7s}84-qYxp-Pe^g%Jt z^tN`MzcHt^B4Pn??9z^Qgfb4gL ydY9W3fdETb780W6hwF(T*Igfy^D z6l6l8wbc{q&1_!ODks>K7;Z|(=~G%yYh5~Yc6%pr^fhukNy+i!A)*1`QN4r4leh=6 zl<|xpkH{XVoQs@QWWRbvJi{i1oH|xKNy!o8A<9yvj1o`kp6F64IcPj0eG( }a#V^ju+esPKYDo^eER6q5UEn|Dk$im-Hy?ua7+*>s9LgsVa7^1UW5!$ zX+XN9W$xW635PAY+!T|>agfUyO1s2TZz4Pb3INHjwq>oeRxNK;l$O?|t&0%^D-=VO z5@`Zbl$mhMknAIBg{POx%9KP}K=eVL3Fq62Hj*ouPQ^ivXBy%-!4oFmog)1h-=j3N za-wEqoY-5u1TbK%v^Fn8A$h^lnZk=;zR$E~X9dPuvC37;6-KcH@9cE5Yp2ppU)i~2 zO2@+Hr4tg2b}aW`SST!jv+_0qJJdEToIsx1wlLALd HKw_<6?+l9u*&ezw0?zkiDTMlFGtUzIaV%(8*T3F z8m9~oE7=7r7cXv2j7fBy-bq$VRdJihU4}|(+EVzqL>pLXsfM*6_A0PchinTL!kFz= zB58K}X;{54Y9qb0KaotKMS2@da?C0@o1~^<<-Ug$xz?tMCaFtSf$~VFd8(C6k{MDL zBx%Pi=tKmM?Etsv<60Lrqp`UElT@d$?JaGzwryUTOmYX;oVLz3lx0>&GEIt2#4bT= zB1ug(nj~E|C}x$8_8F~9o6q38&SW~99`9QvY09;bDA=*-L3;>pWq7vZVZrsGSzg|p zavJT!sP*{tMB6e{>ol6_X~#gc$x!7?#3b`(VrBRLwRd*0Z6#TLuX{<6v@B63J?>`D zkZ!trJeGIVY|GP~nN5#(SC%Zd8nUgiWV?H^8#g7 RbEke2|-d-9L~dDw>}4|zy7z$806`TeWzNAZ&Muy<#H02$f5w?0mt zI(6!tQ>W_Qs%th+kB>D|TivJWN|4rQ&S%#8vA^-)nfbwK=d>dUJL%lzJ3#FN91R3b z@h6@3i!=>iWhf!djXWJ$-(^_^hr#N;5PI2ec*^9 ODdAwKN*ZQ&Oq1 z%WHB2w;5Yhy|ZO&E30uDOm~@wPaiNsSQVhhEU>NfVY~ZcfGx59X=%|d7aAcMfQdyW z9y(jQ0H~>JtUDTU$OhaxBr*-fGPh{6gvmV9MPt2*+_cQ%lv_8W5{4dF{9 !;CIte_^HAwrT4wWEXW)HFYycPBuZ{AjTkZHpFrV} `HjFNG #57EH1%j57rMZ@3J!OwM`_$!%a0PBqTfE JC5799hXx*@UTgw5Av@9lJ 5=Qt0+O*0r?~3LiMe;gGQI 4s ?Ppz4^rSbqd| f@P)P#aeRoHh zU2VJ3>K w@&YH6<>_;1H$vpW0-yS2{ZfZMiTGr2kYN(>l{{C#-R5YQ3F~yL8Gs=gLL( z;O=4ja~ElAM&yErPk*!{Pfx;#ui5D(vB>IJ)560uIiXhCvd<7~;&JpqA$n?M1s&(M zd(s~=Ba-A(hf0!65R=IWVQ^m#xg|C$aSx4Ef7cpZgiSOgibSo7VkmbMqA_+wE{a0k z7cZkQ4L-6DgpCT@r wb(uw7{9Vaa@|@6s9Hn7i#pUC%i6S?7M|i<5XX*;4rMDOzx%kgdiGdm}Rn zY?uQbeU7BNfZ5;uf=T0UhZjPQzQC4aV5Cnh0-V^{*!?xzusCh&h(#=yqHIsL7$g0d z+z$KLH3d$kOH-;ugzT7_#)LMFZ5^dyP!2@0ZjDO1Y5M@lXdd&e?%oRC#nzDzpaO}6 zLQ@*1sx%U %ZSVN6_FNyc4uKvih&1d}HGJjTcljRRDWNX$ZBjeN z6ni$s+*;zjxo!3V?h!xY*Edb>p8?YY@`w_ #Nz7ndFL+p5BO(tEq?R-7WiEU&wVg9spr(}SX{hgM#>lFC8-X_ zbK<*(?=~7U+hMQbDcBDvVJgoF^(nP%A!ysXP4j*5ylv@7@x**l`?mR-ZwHtY!@H|j z;vAo2o7CO6v>yVoPu*(SiEZsm^I^8mZ_k@`a1L|+fmhcD?2ugJMaPfKeeP<@8aTzj zYnHD|#CYii`c&UX5jG!#&+nL<;x^6$`#{a|GG)}yN2D}qpL(zh ?kzzqE!$FU%M(di(@aADGuysH zVL1E852^5kYI;=GB=i#EMC|v?ZNd_q-yjx?Tg;F_kx(-w3I{-{d9Hi=G*W^t9BPmR zTbR|*(KT)k)VU8uuKT3`=KZwG9+C5c-w~oOs>flx2E+KB{gYM5>OhP%XYwZQSwhwL zwDebLs9(;n^_9*1&iH1I#`hO!p!!2X>LdP3Z{TlEDzwXVn9Pdg$rITpDT5|aT^~zo zC}YL)6!-29@^pxymYJ48c**C}cZnZcI$px7o;BlASIM P-(r<-|s& z(8;gNykKRp*USp?_~UVwDkb)VF}7?IL_MmNw#$}{ws=yAl*o6jT^=Up12$$jV($U3 z5k&Ugk@$~(StO1oaIhIaoVX!Ap^$&ck-wTKs3ZO-|8EkXk_qW=XG!0r5qtEjthvlF z GQweH_95pbNvky2xz00_88TNQ*4U`;y-yLnt%SO#G6;VOaU& zhhO=F&X}g-&uA}ESO$jPUw0<=1Mp{u-Ykv&_{zvM5o?!h$F(uIrV<;^*!276^w9cE zl3Q_OD{@uLoGWvm_K8#GqKmIvxIG}BW9P&d$@)Gp5>)3Wo1$8JV$9q&e0A=M (D5EnTs*Uy%HnqSxx)nQrb6OsVk$}v*P#M>wZ6aC9jPtxg7O! z8xx>jpa(9-J@1vRNM8r~d`^<+N&MOGXI*wpOni?*lN4EDSv*xF;dRb_+#SwTXtJlt z+ISNXd*HqSkf^352h=`c+2Ewi6X1~$zI8Q`J3G#F#5JexvE138{P|guI*NbE%vny| z(5y|AM#@Ub+U(FFK8pt$$_!6kDSN~WZ!;amo91`f4g0q!>t^|BsXowyUV>m3Eo?mJ zOxFp_)zQPR-$e{UIcCJUAHw)Q`bCUynY%QMHOwJ0B&CwCVc8tD5b;%|bR3QWdClFX z8Jqk*; R@>&!>w&rYJw>G0PL~s+jp)gN$2{N=0AJ$)S}H%{aHAT*Cc~s~{EQ@uwZYo0xJb zkQ=(Sa%0gT2p$b0A}tpAl%^h0L&&CT73Hzn+17jx5xTuF% Wh^cq5^Tx9>+@^Gz`Hol1b18y48wzYWKU#VBYI-|3}O%#j8+e@ zKlY9dvUkj?yiqo`sSyXEzs^Nh3 z5Xlja8Zt7j2Qqf{nkd%@qN(N%>v&t1LQOe+NV7R^@;gl5_=ON3BfWIX&1PHBAJ12{ z#?u;D<7wGR&hTv3G 1bdJ1Yd#KF_pb43{ zp-G^4VHQ&;M|+1HO<80QQ+Q2gq7uI|S)0}^>(#|-MX`L-RIe7B0Z^4IQ%w%bdxuji!s^xPRcH-CPM9+ 6%M{Amm9P(;7UdSF=9%++^A0%3yr!et=3B} zsan5SoQ1+VZL8L6VW~!5NZV_!=K5SQcd4=#R2JN|RB(48o(oEaW^m!6DM4r{Uks|2 zf_kwyRih4dM@{EvS|S={h=8POJ-Roedo8+yOZoMDV6bS-Tu`eKF+or--3XL(+1Nmh zfIyX73@)4eG?&7SfNR;^YDHV%va$CX<%)SVxmrJWBMbp+Tn=0aT!D}(%~o^SfEF1D z&lRVtpM)ezkgA`QOU*n2B=TTQjs7p^a<3Jq23X@FR*u3;#r%l8DGFaUzgB#GM4l+K zqG2z9(FHZq3MQytt^CgG#fu{$s>KUwDOZ%Prz_PTO$D2^BB!QZHlVs7F4b0@vj0UF zsln|evj$@d#jsIXkb2Z=<)X=REr;}8t>$vdgwdF$nMRar{6Uin)M#Gi?8kL(HSPt< zS1TObBABYv#FDs%43k#1B`=lKFPT<{I^QK|)E#H*#Y@$udc0h!p8f662QG!MK}XEy zrh_`dQ>_yy^DFT~=rJTEnnu}baV``JuO>k9{0jW0`OWZ~<(IoutV(Y(f3_p)=Zb}r zm89@{#a8tyijjad%B5NjmBUQbOAR%y I;+F%?EKuv{>eAp<2jp?v46E x;pXAi FT||7X%>*XLo1G4f1l!)S(`qrjBqLC&N#O%sN& *kLUIT*v?y046N~ChUNx07iSj{7GQ8Qf9aG(yCr%a&MqF z_xsJGXg5=<$=iO-45)oqDuO+ GzcEHmBPiKIq0VXX0CJZou@&YOg zXbw>c3UDMPaD>S~;OKih_UH=VAMsg2kCVJ*Bc9urV_(T~04>KIWR~IJhOu1X5?4B# zD}uxog1N#FuCx?&fHY|Zw lk=_G%G-lS(G*j 1(%B;c=L ztu;WQy-sZg=Dyb+?;XWg%9a1pV>2sO=WtJJbNM@sysbmS0@0F7&fRIq`q$=iQ9|KP zqhR4QZq()qQF7@{LvBm0p>d=(SBjFS?=+@uvc{F#+;o&YbEh$5lQquN=4PVg**lF{ zo2+rCHaA<+KsSen;%KSeX&}pC4Nt{F>DthoC}>R8p70$>k288{P?BWd27D!N?CXUo zXqG#|p0{=6>{ZjXprKJFXiVGdjJ?j<>yYa6f?|sMRn}H-GNzDODo`5OKoxjE@EIFZ z+6l~G_Zl487~9_H73^0wJ2o`~1+vvrQ{L7`?Su>VTC&$^d!4b@S$mB&y)9cLQD! z@raX=@m^7l=$q#iPj #rnvA}myMeMrQu&B4W!=_%zioD Zi`3N0%yR|H=#HwH#0@+SJQt z2KRLiUlEYY<~$Jx&SbP0%t?#q^70C&Yp)fHbNT5of{boqcmWSPiZF?;oc$Z&h!Su| zT~K7$G-NGG%Ew80CRyj0tv4z+N|hU|Do|U r&8VN*7v;a_drJk%O7Isn+p#Lnf8F)^R qrt7_GNlXWg2G;1_*yewSLMU}&-u&$ znJz!m v%>%K7s% zpl+JVO0H?n^P5rR!~DEb=1G|+g~*4cW=`;x4@n8n6)siJ{&QHat~0ZZgX;JHqO|Hd zQ$8$bP`?nC;@tC1L-3Eoi{@gW#6K3K5>?10M#UlEV(^XPbX+o=nej2tN|I;zd$X7z z4}txYpzMRO8srkEX!}Jo#ZuEn1L{WkTJc _>iX3Sxty)&a=?MB)i2MXJvNWUi69Oz4`hN_T^E&9SyW3bW5XiT z7x6_o)ph!yQARR ly9 *Ym7B)R}T`hy~RR zG@CguxX&vItkn(BZWRPn-J&JcEnDLjHCDHfN~=LkZK%IYpEk-=I~%Gr+EV>g3pSrN z$}@3RMZ}Wvu`)hxl&1~4Uj35fEhX=QNEcB|4s9x#@=_2VL-~qHUb5k=pP9mGu6I2! z@myjoT%vXd&`>!*u_^~eF|iVqzs9 3e(%=OOpsn5@V{z?aPfimaHY6nn&djrje^iZ4-k85EoR zdumoGdY{-+o<%&c)NDCq=HZ_Qo# QqiO zouf&WJ{iI%6j-x}o>J)5C}pk6)h`%Q5XtHnXcW_GKKF#JG-xYJGh5+nPkL?6knAQK zuk8k-J`27W*DtRFt}l%l!+P6!Z>y*=-wMnXFQGO1z#H?8z`W*zdB^3LHv;oDKW`~M zUq{5f;pc2Tf7$2E1vf+)^Uc7#>1Thm`QSdgZ1?RE88J{jFt7VSYu)41lQ?sz>W6Vo z7PmWMCOY6F2D%cMx{o_`(_)BbV7@U3vCr;C_Rfz3`0(h2vqv}*H3oQ#70v+++HQNB z^Yjkl^M*{eiA$%u`$uv4Y$gYgoji{--ww=WANleD8~wFg-s4fWha;GWoVUT5X1y3y zmQK6Vrptc9v?*T?%q73Jt@X{gbe0ec28u3w<71d_2j*LTaT{LZK$Mp{h=Xm`hbddL zL|fP=o$YA%U5xT7rgc2ZaZt-WPHjsL{)nO849wSkTq~O!oP&Ct@OmiUZiPBZ7?_pC zyNMcP8?$!U-s4ywZST{06fpr=X}rr0*<}t>Nc$+Og?D=#plFXs9#$spM|6GccB*rZ zvN73Cwt}+GNm@HEV?2yj-}KoaJks`6HZ!{8Uw;v#N(@3~Wq9r0-A4&`vZ7=6obCV3 z0WHh+GyAlW8O~g?2Oq}-Wd)4=>G3&yL%p38r3TT#1ooyPJ(+&vaT-oS*G2^4WKN zvfoL}+iwNt1D})8c>`;lZ{SSagRa%Cb{BC#XXE6gimVM|mA%vHvh7Z%TaBY*^H_&V z-D~$>#1Pp|cMur*;{-{T8*G<%Cy>QBh5$~t+4k)YIJA |Ie;9_7Fh5%E`W &$?AFr z^OGk};^t*d|Krt< e^a>a$YzG5fI}bQ5jKGGk-&y%=v+h{#G?JzOq& ze8e|XGG5Nc=KE>6Y(t`RziBETWC={gZwT(e>8^DP2RtvE+=`AcG3IN5nX{!h$~zi= z`G!koc=xih%4y3c`EKaum6^;4y0ohe?E7plW)$P4k!(9QPJ25XplaKZ&6DbAe=aB3 z*e75SwWl0oWJd r;9hgmM-Qlb`4w5m+0MlCG;Mk*=_DDg{_hWwe zq}kJ8_T0HyqJg|$3wYT_XUh-eaWE^%2_L*cco=kx11t}8;G#*GISgbEYSfwTeruv} zBcdiTWGz3v<&{kIV+=$q!t|ZMxCXSmfzsyr1zjh^Ws)Ju2kEys+GDM|821+|N@d5e zw9!(yc&GV0%bH~zzjFeAbw(I3uA$P|+-Ljr>T$c@_u#T-m@ialEY wFyD4GJEv)5|JZg{Us&X*wGUc1S8R{z zn+BdRE7=XHiNqyj4&_CxPt?8jXbthTXG#s1b^;7Y1Q8pVR0M`fNBH&3*tI4d=Zskh z%r%?pyfYBTW1w73cNW303HHDe5>u5*akO*}6(n{d8WJjpYKw&_ff%kL!jVW)g2S^i zt<(;->`{R_$&VErzQ*L*e!8>Q`oYnruS@YEPA)wKh3yYKW!p+Hg;pSw$aC5R=xH(xb+@u#0H+mf3ICI{q z>V%L`I3XlNP6# I_H z<3~+e5yg>oH+$`n_i%G%Gy8tCO87%(cBQa&yt^#~e-Hfe-ybU6jAMiMf8fEn98Qkv ztsETO)5)iY{T+sbjy+{nxj(;Zn!n}1es%pNZ~*TJEPTK6Y!I1yn-Oa>lrFdr`F(sA zm_Kk2Ym`J7y<)?Z9$Y-Oj|DcPhZRrlV~kZE4e0NW^8fwMv==S=_nT1yPks3A;Nag1 z(EzO49-_U3+D4@ @94y(~tg=EjSw`Jpw-729C6CH3Yare*j(dOEFw0M_I58_XYkUbBHI(ZgM9ojd( zXR&L8$1z)K)q*|qoHiJ%o I(VQVjjo-~V?U_`j1GI&%O3 literal 0 HcmV?d00001 diff --git a/constants/Paths.cs b/constants/Paths.cs index de19c4b..bc27edf 100644 --- a/constants/Paths.cs +++ b/constants/Paths.cs @@ -18,10 +18,6 @@ public static class Paths /// public static readonly string PersistentDataPath = Combine(Application.persistentDataPath); /// - /// path to special folder. on PC its just the Users home directory. on Mobile its app-specific directories. - /// - public static string SpecialFolderPath => System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal); - ////// Path to folder StreamingAssets /// public static readonly string StreamingAssetsPath = Combine(Application.streamingAssetsPath); diff --git a/resources/commit b/resources/commit index 83ef0fe..0adda88 100644 --- a/resources/commit +++ b/resources/commit @@ -1 +1 @@ -17c7aa59e67d7b8eecf451070fe3efc09a0a0532 +48443abae34350efacbb670f3199fea1735d7a58 diff --git a/services/NativeLibraryManager.cs b/services/NativeLibraryManager.cs index 5fb0457..573745d 100644 --- a/services/NativeLibraryManager.cs +++ b/services/NativeLibraryManager.cs @@ -1,26 +1,16 @@ -using System.Collections.Concurrent; -using System.Data; using System.Reflection; -using System.Runtime.InteropServices; using NeoModLoader.constants; using Newtonsoft.Json; -using UnityEngine; - namespace NeoModLoader.services; using System; using System.Collections.Generic; using System.Collections.Concurrent; using System.IO; -using System.Linq; using System.Runtime.InteropServices; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Json; -using System.Text; using UnityEngine; public static class NativeLibraryManager { - // Windows [DllImport("kernel32.dll", EntryPoint = "LoadLibraryW", SetLastError = true, CharSet = CharSet.Unicode)] @@ -120,8 +110,7 @@ static NativeLibraryManager() case RuntimePlatform.Android: PlatformFolder = "android"; - SpecialPath = Path.Combine( - Paths.SpecialFolderPath, "NML"); + SpecialPath = Path.Combine(IL2CPP2MONO.App.InternalPath, "NML"); GetAddress = AndroidDlSym; Loadlib = (path, out error) => { @@ -205,7 +194,7 @@ public static T GetNativeFunction( string Name, string Symbol) where T : Delegate { if (!Libraries.TryGetValue(Name, out var lib)) - return null; + throw new DllNotFoundException($"native library {Name} was not found!"); IntPtr function = GetAddress(lib.Handle, Symbol); if (function == IntPtr.Zero) { @@ -237,4 +226,26 @@ private static List GetOrder( "Failed to read order.json.", ex); } } + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate bool NativeModEntry (IntPtr NMLAPI); + + static IntPtr NMLAPI(string type, string method) + { + Assembly NML = typeof(WorldBoxMod).Assembly; + Type Type = NML.GetType(type); + if (Type == null) + { + return IntPtr.Zero; + } + MethodInfo Method = Type.GetMethod(method, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); + return Method == null ? IntPtr.Zero : Method.MethodHandle.GetFunctionPointer(); + } + /// + /// native libraries which act as mods may use the NML API for assistance. the entry point is always bool ModEntry(IntPtr NMLAPIFUNC) where NMLAPIFUNC is IntPtr (string type, string method). this returns a neomodloader function which may be used + /// + public static bool LoadNativeMod(string Name) + { + NativeModEntry EntryPoint = GetNativeFunction(Name, "ModEntry"); + return EntryPoint(Marshal.GetFunctionPointerForDelegate(NMLAPI)); + } } \ No newline at end of file diff --git a/utils/MobileStuff.cs b/utils/MobileStuff.cs new file mode 100644 index 0000000..cd41a7d --- /dev/null +++ b/utils/MobileStuff.cs @@ -0,0 +1,9 @@ +using System.Runtime.CompilerServices; + +namespace IL2CPP2MONO; + +public class App +{ + public static string InternalPath { [MethodImpl(MethodImplOptions.InternalCall)] get; } +} +//we will add an IOS class used for detours once we make them good \ No newline at end of file From 8454fb0025ac9544ec88c029df703305c804e548 Mon Sep 17 00:00:00 2001 From: "Melvin \"Dumbass\" Shwuaner" <83349478+MelvinShwuaner@users.noreply.github.com> Date: Tue, 10 Nov 2026 18:49:09 +0300 Subject: [PATCH 09/14] fix --- resources/commit | 2 +- services/NativeLibraryManager.cs | 16 ++++------------ 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/resources/commit b/resources/commit index 0adda88..0ce6225 100644 --- a/resources/commit +++ b/resources/commit @@ -1 +1 @@ -48443abae34350efacbb670f3199fea1735d7a58 +919ad111295239c1e55bae042df1b500623f1385 diff --git a/services/NativeLibraryManager.cs b/services/NativeLibraryManager.cs index 573745d..fe23f9b 100644 --- a/services/NativeLibraryManager.cs +++ b/services/NativeLibraryManager.cs @@ -34,18 +34,14 @@ public static class NativeLibraryManager private static extern IntPtr LinuxDlError(); // Android - [DllImport("libdl.so", EntryPoint = "dlopen", + [DllImport("libmain.so", EntryPoint = "load_library", CallingConvention = CallingConvention.Cdecl)] - private static extern IntPtr AndroidDlOpen(string filename, int flags); + private static extern IntPtr AndroidDlOpen(string filename); [DllImport("libdl.so", EntryPoint = "dlsym", CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr AndroidDlSym(IntPtr handle, string symbol); - [DllImport("libdl.so", EntryPoint = "dlerror", - CallingConvention = CallingConvention.Cdecl)] - private static extern IntPtr AndroidDlError(); - private const int OPEN_FLAGS = 2 | 0x100; delegate IntPtr loadlib(string Path, out string Error); @@ -114,12 +110,8 @@ static NativeLibraryManager() GetAddress = AndroidDlSym; Loadlib = (path, out error) => { - error = null; - IntPtr handle = AndroidDlOpen(path, OPEN_FLAGS); - if (handle == IntPtr.Zero) - { - error = Marshal.PtrToStringAnsi(AndroidDlError()); - } + error = ""; //it already logs the error inside libmain + IntPtr handle = AndroidDlOpen(path); return handle; }; break; From 2d7a4a3ab8bb95241b1df582a2a479ae80819fbc Mon Sep 17 00:00:00 2001 From: "Melvin \"Dumbass\" Shwuaner" <83349478+MelvinShwuaner@users.noreply.github.com> Date: Tue, 10 Nov 2026 20:05:38 +0300 Subject: [PATCH 10/14] fix nmlapi --- general/RF.cs | 8 ++++++++ resources/commit | 2 +- services/NativeLibraryManager.cs | 34 +++++++++++++++++++++++--------- utils/ReflectionHelper.cs | 6 +++++- 4 files changed, 39 insertions(+), 11 deletions(-) diff --git a/general/RF.cs b/general/RF.cs index 051c316..e27c85a 100644 --- a/general/RF.cs +++ b/general/RF.cs @@ -45,11 +45,19 @@ public static Delegate GetMethodDelegate(this Type type, string name, bool is_st return method; } var newMethod1 = ReflectionHelper.GetMethod(type, name, is_static); + if (newMethod1 == null) + { + return null; + } methods.Add(name, newMethod1); return newMethod1; } var newMethod = ReflectionHelper.GetMethod(type, name, is_static); + if (newMethod == null) + { + return null; + } _method_cache.Add(type, new Dictionary { { name, newMethod } }); return newMethod; } diff --git a/resources/commit b/resources/commit index 0ce6225..945849a 100644 --- a/resources/commit +++ b/resources/commit @@ -1 +1 @@ -919ad111295239c1e55bae042df1b500623f1385 +8454fb0025ac9544ec88c029df703305c804e548 diff --git a/services/NativeLibraryManager.cs b/services/NativeLibraryManager.cs index fe23f9b..07a1f50 100644 --- a/services/NativeLibraryManager.cs +++ b/services/NativeLibraryManager.cs @@ -1,5 +1,6 @@ using System.Reflection; using NeoModLoader.constants; +using NeoModLoader.General; using Newtonsoft.Json; namespace NeoModLoader.services; using System; @@ -219,25 +220,40 @@ private static List GetOrder( } } [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - delegate bool NativeModEntry (IntPtr NMLAPI); + delegate IntPtr NMLAPIFunc( + [MarshalAs(UnmanagedType.LPUTF8Str)] string signature + ); - static IntPtr NMLAPI(string type, string method) + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate bool NativeModEntry( [MarshalAs(UnmanagedType.FunctionPtr)] NMLAPIFunc NMLAPI); + + static ConcurrentDictionary Delegates = new(); + static IntPtr NMLAPI(string signature) { - Assembly NML = typeof(WorldBoxMod).Assembly; - Type Type = NML.GetType(type); - if (Type == null) + Assembly NML = WorldBoxMod.NeoModLoaderAssembly; + string[] args = signature.Split(':'); + Type Type = NML.GetType(args[0]); + Delegate Method = Type?.GetMethodDelegate(args[1], true); + if (Method == null) { return IntPtr.Zero; } - MethodInfo Method = Type.GetMethod(method, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); - return Method == null ? IntPtr.Zero : Method.MethodHandle.GetFunctionPointer(); + if (Delegates.TryGetValue(Method, out var lib)) + { + return lib; + } + + IntPtr ptr = Marshal.GetFunctionPointerForDelegate(Method); + Delegates.TryAdd(Method, ptr); + return ptr; } + static readonly NMLAPIFunc NMLAPICallback = NMLAPI; /// - /// native libraries which act as mods may use the NML API for assistance. the entry point is always bool ModEntry(IntPtr NMLAPIFUNC) where NMLAPIFUNC is IntPtr (string type, string method). this returns a neomodloader function which may be used + /// native libraries which act as mods may use the NML API for assistance. the entry point is always bool ModEntry(IntPtr NMLAPIFUNC) where NMLAPIFUNC is IntPtr (string type, string method). this returns a neomodloader static function which may be used /// public static bool LoadNativeMod(string Name) { NativeModEntry EntryPoint = GetNativeFunction(Name, "ModEntry"); - return EntryPoint(Marshal.GetFunctionPointerForDelegate(NMLAPI)); + return EntryPoint(NMLAPICallback); } } \ No newline at end of file diff --git a/utils/ReflectionHelper.cs b/utils/ReflectionHelper.cs index ea07b18..dabae19 100644 --- a/utils/ReflectionHelper.cs +++ b/utils/ReflectionHelper.cs @@ -21,7 +21,7 @@ internal static Delegate GetMethod (string method_name, bool is_static = false internal static Delegate GetMethod(Type type, string method_name, bool is_static = false) { return createMethodDelegate(is_static - ? type.GetMethod(method_name, BindingFlags.Static | BindingFlags.NonPublic) + ? type.GetMethod(method_name, BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public) : AccessTools.Method(type, method_name)); } @@ -138,6 +138,10 @@ internal static Action CreateFieldSetter (string field_name) private static Delegate createMethodDelegate(MethodInfo method_info) { + if (method_info == null) + { + return null; + } List paramExpressions = method_info.GetParameters() .Select((p, i) => Expression.Parameter(p.ParameterType, p.Name)).ToList(); From 18dc6eb527b5152d631f4d69554b8461aba0495a Mon Sep 17 00:00:00 2001 From: "Melvin \"Dumbass\" Shwuaner" <83349478+MelvinShwuaner@users.noreply.github.com> Date: Tue, 10 Nov 2026 20:33:54 +0300 Subject: [PATCH 11/14] Update NativeLibraryManager.cs --- services/NativeLibraryManager.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/services/NativeLibraryManager.cs b/services/NativeLibraryManager.cs index 07a1f50..d693fe2 100644 --- a/services/NativeLibraryManager.cs +++ b/services/NativeLibraryManager.cs @@ -1,4 +1,5 @@ using System.Reflection; +using NeoModLoader.api; using NeoModLoader.constants; using NeoModLoader.General; using Newtonsoft.Json; @@ -225,7 +226,7 @@ delegate IntPtr NMLAPIFunc( ); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - delegate bool NativeModEntry( [MarshalAs(UnmanagedType.FunctionPtr)] NMLAPIFunc NMLAPI); + delegate bool NativeModEntry( [MarshalAs(UnmanagedType.FunctionPtr)] NMLAPIFunc NMLAPI, [MarshalAs(UnmanagedType.U8)] ModDeclare Declare); static ConcurrentDictionary Delegates = new(); static IntPtr NMLAPI(string signature) @@ -249,11 +250,12 @@ static IntPtr NMLAPI(string signature) } static readonly NMLAPIFunc NMLAPICallback = NMLAPI; /// - /// native libraries which act as mods may use the NML API for assistance. the entry point is always bool ModEntry(IntPtr NMLAPIFUNC) where NMLAPIFUNC is IntPtr (string type, string method). this returns a neomodloader static function which may be used + /// native libraries which act as mods may use the NML API for assistance. the entry point is always bool ModEntry(IntPtr NMLAPIFUNC) /// - public static bool LoadNativeMod(string Name) + ///NMLAPIFUNC is IntPtr (string signature). this returns a neomodloader static function which may be used + public static bool LoadNativeMod(string Name, ModDeclare Mod) { NativeModEntry EntryPoint = GetNativeFunction(Name, "ModEntry"); - return EntryPoint(NMLAPICallback); + return EntryPoint(NMLAPICallback, Mod); } } \ No newline at end of file From 734fb8182c04674efbee244be70a9c6ab1a3c080 Mon Sep 17 00:00:00 2001 From: "Melvin \"Dumbass\" Shwuaner" <83349478+MelvinShwuaner@users.noreply.github.com> Date: Tue, 10 Nov 2026 20:37:21 +0300 Subject: [PATCH 12/14] Update Paths.cs --- constants/Paths.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/constants/Paths.cs b/constants/Paths.cs index bc27edf..86390db 100644 --- a/constants/Paths.cs +++ b/constants/Paths.cs @@ -109,7 +109,7 @@ public static class Paths public static readonly string ModDefaultConfigFileName = "default_config.json"; /// - /// Folder name of a mod's resource folder which will be patched to public static readonly string NativeLibrariesFolder = "Native"; ///+ /// Folder name of a mods native libraries /// From 9902208ed4b6c31c3f1cf0d57235c288afaa7a19 Mon Sep 17 00:00:00 2001 From: "Melvin \"Dumbass\" Shwuaner" <83349478+MelvinShwuaner@users.noreply.github.com> Date: Tue, 10 Nov 2026 20:47:03 +0300 Subject: [PATCH 13/14] Update NativeLibraryManager.cs --- services/NativeLibraryManager.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/NativeLibraryManager.cs b/services/NativeLibraryManager.cs index d693fe2..ef28551 100644 --- a/services/NativeLibraryManager.cs +++ b/services/NativeLibraryManager.cs @@ -226,7 +226,7 @@ delegate IntPtr NMLAPIFunc( ); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - delegate bool NativeModEntry( [MarshalAs(UnmanagedType.FunctionPtr)] NMLAPIFunc NMLAPI, [MarshalAs(UnmanagedType.U8)] ModDeclare Declare); + delegate bool NativeModEntry( [MarshalAs(UnmanagedType.FunctionPtr)] NMLAPIFunc NMLAPI, [MarshalAs(UnmanagedType.LPUTF8Str)] string DeclareID); static ConcurrentDictionary Delegates = new(); static IntPtr NMLAPI(string signature) @@ -256,6 +256,6 @@ static IntPtr NMLAPI(string signature) public static bool LoadNativeMod(string Name, ModDeclare Mod) { NativeModEntry EntryPoint = GetNativeFunction (Name, "ModEntry"); - return EntryPoint(NMLAPICallback, Mod); + return EntryPoint(NMLAPICallback, Mod.UID); } } \ No newline at end of file From 07036ef598b49dba325559e6b6eba8a23ca3e1df Mon Sep 17 00:00:00 2001 From: "Melvin \"Dumbass\" Shwuaner" <83349478+MelvinShwuaner@users.noreply.github.com> Date: Wed, 11 Nov 2026 21:20:56 +0300 Subject: [PATCH 14/14] actually screw that --- resources/commit | 2 +- services/NativeLibraryManager.cs | 38 -------------------------------- 2 files changed, 1 insertion(+), 39 deletions(-) diff --git a/resources/commit b/resources/commit index 945849a..5420a16 100644 --- a/resources/commit +++ b/resources/commit @@ -1 +1 @@ -8454fb0025ac9544ec88c029df703305c804e548 +9902208ed4b6c31c3f1cf0d57235c288afaa7a19 diff --git a/services/NativeLibraryManager.cs b/services/NativeLibraryManager.cs index ef28551..06a4c10 100644 --- a/services/NativeLibraryManager.cs +++ b/services/NativeLibraryManager.cs @@ -220,42 +220,4 @@ private static List GetOrder( "Failed to read order.json.", ex); } } - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - delegate IntPtr NMLAPIFunc( - [MarshalAs(UnmanagedType.LPUTF8Str)] string signature - ); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - delegate bool NativeModEntry( [MarshalAs(UnmanagedType.FunctionPtr)] NMLAPIFunc NMLAPI, [MarshalAs(UnmanagedType.LPUTF8Str)] string DeclareID); - - static ConcurrentDictionary Delegates = new(); - static IntPtr NMLAPI(string signature) - { - Assembly NML = WorldBoxMod.NeoModLoaderAssembly; - string[] args = signature.Split(':'); - Type Type = NML.GetType(args[0]); - Delegate Method = Type?.GetMethodDelegate(args[1], true); - if (Method == null) - { - return IntPtr.Zero; - } - if (Delegates.TryGetValue(Method, out var lib)) - { - return lib; - } - - IntPtr ptr = Marshal.GetFunctionPointerForDelegate(Method); - Delegates.TryAdd(Method, ptr); - return ptr; - } - static readonly NMLAPIFunc NMLAPICallback = NMLAPI; - /// - /// native libraries which act as mods may use the NML API for assistance. the entry point is always bool ModEntry(IntPtr NMLAPIFUNC) - /// - ///NMLAPIFUNC is IntPtr (string signature). this returns a neomodloader static function which may be used - public static bool LoadNativeMod(string Name, ModDeclare Mod) - { - NativeModEntry EntryPoint = GetNativeFunction(Name, "ModEntry"); - return EntryPoint(NMLAPICallback, Mod.UID); - } } \ No newline at end of file