From fd7d175f6eea03deb30b7acc34bd29c0c64cf81e Mon Sep 17 00:00:00 2001 From: Connor Slade Date: Thu, 27 Jun 2024 15:26:47 -0400 Subject: [PATCH 01/17] Start on update to Minecraft 1.21 Update loom and gradle wrapper --- build.gradle | 2 +- gradle.properties | 10 +++--- gradle/wrapper/gradle-wrapper.jar | Bin 61574 -> 43462 bytes gradle/wrapper/gradle-wrapper.properties | 3 +- .../connorcode/sigmautils/commands/About.java | 30 ++++++------------ .../connorcode/sigmautils/commands/Note.java | 2 -- .../sigmautils/misc/util/NetworkUtils.java | 4 +-- .../connorcode/sigmautils/misc/util/Util.java | 1 + .../modules/_interface/RandomBackground.java | 1 + .../sigmautils/modules/chat/ChatControl.java | 1 + .../sigmautils/modules/hud/Hud.java | 1 + .../sigmautils/modules/misc/AutoSign.java | 1 + .../modules/rendering/LightLevel.java | 1 + .../modules/server/AutoVoidTrade.java | 5 +-- 14 files changed, 27 insertions(+), 35 deletions(-) diff --git a/build.gradle b/build.gradle index 488910d..b2ca41d 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '1.4-SNAPSHOT' + id 'fabric-loom' version '1.6-SNAPSHOT' id 'maven-publish' } diff --git a/gradle.properties b/gradle.properties index 48471b2..92f9bde 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,13 +1,13 @@ # Done to increase the memory available to gradle. org.gradle.jvmargs=-Xmx1G # Fabric Properties -minecraft_version=1.20.4 -yarn_mappings=1.20.4+build.3 -loader_version=0.15.3 +minecraft_version=1.21 +yarn_mappings=1.21+build.4 +loader_version=0.15.11 # Mod Properties mod_version=0.1.9-alpha maven_group=com.connorcode archives_base_name=sigma-utils # Dependencies -fabric_version=0.92.0+1.20.4 -mod_menu_version=9.0.0 +fabric_version=0.100.4+1.21 +mod_menu_version=11.0.1 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 943f0cbfa754578e88a3dae77fce6e3dea56edbf..d64cd4917707c1f8861d8cb53dd15194d4248596 100644 GIT binary patch literal 43462 zcma&NWl&^owk(X(xVyW%ySuwf;qI=D6|RlDJ2cR^yEKh!@I- zp9QeisK*rlxC>+~7Dk4IxIRsKBHqdR9b3+fyL=ynHmIDe&|>O*VlvO+%z5;9Z$|DJ zb4dO}-R=MKr^6EKJiOrJdLnCJn>np?~vU-1sSFgPu;pthGwf}bG z(1db%xwr#x)r+`4AGu$j7~u2MpVs3VpLp|mx&;>`0p0vH6kF+D2CY0fVdQOZ@h;A` z{infNyvmFUiu*XG}RNMNwXrbec_*a3N=2zJ|Wh5z* z5rAX$JJR{#zP>KY**>xHTuw?|-Rg|o24V)74HcfVT;WtQHXlE+_4iPE8QE#DUm%x0 zEKr75ur~W%w#-My3Tj`hH6EuEW+8K-^5P62$7Sc5OK+22qj&Pd1;)1#4tKihi=~8C zHiQSst0cpri6%OeaR`PY>HH_;CPaRNty%WTm4{wDK8V6gCZlG@U3$~JQZ;HPvDJcT1V{ z?>H@13MJcCNe#5z+MecYNi@VT5|&UiN1D4ATT+%M+h4c$t;C#UAs3O_q=GxK0}8%8 z8J(_M9bayxN}69ex4dzM_P3oh@ZGREjVvn%%r7=xjkqxJP4kj}5tlf;QosR=%4L5y zWhgejO=vao5oX%mOHbhJ8V+SG&K5dABn6!WiKl{|oPkq(9z8l&Mm%(=qGcFzI=eLu zWc_oCLyf;hVlB@dnwY98?75B20=n$>u3b|NB28H0u-6Rpl((%KWEBOfElVWJx+5yg z#SGqwza7f}$z;n~g%4HDU{;V{gXIhft*q2=4zSezGK~nBgu9-Q*rZ#2f=Q}i2|qOp z!!y4p)4o=LVUNhlkp#JL{tfkhXNbB=Ox>M=n6soptJw-IDI|_$is2w}(XY>a=H52d z3zE$tjPUhWWS+5h=KVH&uqQS=$v3nRs&p$%11b%5qtF}S2#Pc`IiyBIF4%A!;AVoI zXU8-Rpv!DQNcF~(qQnyyMy=-AN~U>#&X1j5BLDP{?K!%h!;hfJI>$mdLSvktEr*89 zdJHvby^$xEX0^l9g$xW-d?J;L0#(`UT~zpL&*cEh$L|HPAu=P8`OQZV!-}l`noSp_ zQ-1$q$R-gDL)?6YaM!=8H=QGW$NT2SeZlb8PKJdc=F-cT@j7Xags+Pr*jPtlHFnf- zh?q<6;)27IdPc^Wdy-mX%2s84C1xZq9Xms+==F4);O`VUASmu3(RlgE#0+#giLh-& zcxm3_e}n4{%|X zJp{G_j+%`j_q5}k{eW&TlP}J2wtZ2^<^E(O)4OQX8FDp6RJq!F{(6eHWSD3=f~(h} zJXCf7=r<16X{pHkm%yzYI_=VDP&9bmI1*)YXZeB}F? z(%QsB5fo*FUZxK$oX~X^69;x~j7ms8xlzpt-T15e9}$4T-pC z6PFg@;B-j|Ywajpe4~bk#S6(fO^|mm1hKOPfA%8-_iGCfICE|=P_~e;Wz6my&)h_~ zkv&_xSAw7AZ%ThYF(4jADW4vg=oEdJGVOs>FqamoL3Np8>?!W#!R-0%2Bg4h?kz5I zKV-rKN2n(vUL%D<4oj@|`eJ>0i#TmYBtYmfla;c!ATW%;xGQ0*TW@PTlGG><@dxUI zg>+3SiGdZ%?5N=8uoLA|$4isK$aJ%i{hECP$bK{J#0W2gQ3YEa zZQ50Stn6hqdfxJ*9#NuSLwKFCUGk@c=(igyVL;;2^wi4o30YXSIb2g_ud$ zgpCr@H0qWtk2hK8Q|&wx)}4+hTYlf;$a4#oUM=V@Cw#!$(nOFFpZ;0lc!qd=c$S}Z zGGI-0jg~S~cgVT=4Vo)b)|4phjStD49*EqC)IPwyeKBLcN;Wu@Aeph;emROAwJ-0< z_#>wVm$)ygH|qyxZaet&(Vf%pVdnvKWJn9`%DAxj3ot;v>S$I}jJ$FLBF*~iZ!ZXE zkvui&p}fI0Y=IDX)mm0@tAd|fEHl~J&K}ZX(Mm3cm1UAuwJ42+AO5@HwYfDH7ipIc zmI;1J;J@+aCNG1M`Btf>YT>~c&3j~Qi@Py5JT6;zjx$cvOQW@3oQ>|}GH?TW-E z1R;q^QFjm5W~7f}c3Ww|awg1BAJ^slEV~Pk`Kd`PS$7;SqJZNj->it4DW2l15}xP6 zoCl$kyEF%yJni0(L!Z&14m!1urXh6Btj_5JYt1{#+H8w?5QI%% zo-$KYWNMJVH?Hh@1n7OSu~QhSswL8x0=$<8QG_zepi_`y_79=nK=_ZP_`Em2UI*tyQoB+r{1QYZCpb?2OrgUw#oRH$?^Tj!Req>XiE#~B|~ z+%HB;=ic+R@px4Ld8mwpY;W^A%8%l8$@B@1m5n`TlKI6bz2mp*^^^1mK$COW$HOfp zUGTz-cN9?BGEp}5A!mDFjaiWa2_J2Iq8qj0mXzk; z66JBKRP{p%wN7XobR0YjhAuW9T1Gw3FDvR5dWJ8ElNYF94eF3ebu+QwKjtvVu4L zI9ip#mQ@4uqVdkl-TUQMb^XBJVLW(-$s;Nq;@5gr4`UfLgF$adIhd?rHOa%D);whv z=;krPp~@I+-Z|r#s3yCH+c1US?dnm+C*)r{m+86sTJusLdNu^sqLrfWed^ndHXH`m zd3#cOe3>w-ga(Dus_^ppG9AC>Iq{y%%CK+Cro_sqLCs{VLuK=dev>OL1dis4(PQ5R zcz)>DjEkfV+MO;~>VUlYF00SgfUo~@(&9$Iy2|G0T9BSP?&T22>K46D zL*~j#yJ?)^*%J3!16f)@Y2Z^kS*BzwfAQ7K96rFRIh>#$*$_Io;z>ux@}G98!fWR@ zGTFxv4r~v)Gsd|pF91*-eaZ3Qw1MH$K^7JhWIdX%o$2kCbvGDXy)a?@8T&1dY4`;L z4Kn+f%SSFWE_rpEpL9bnlmYq`D!6F%di<&Hh=+!VI~j)2mfil03T#jJ_s?}VV0_hp z7T9bWxc>Jm2Z0WMU?`Z$xE74Gu~%s{mW!d4uvKCx@WD+gPUQ zV0vQS(Ig++z=EHN)BR44*EDSWIyT~R4$FcF*VEY*8@l=218Q05D2$|fXKFhRgBIEE zdDFB}1dKkoO^7}{5crKX!p?dZWNz$m>1icsXG2N+((x0OIST9Zo^DW_tytvlwXGpn zs8?pJXjEG;T@qrZi%#h93?FP$!&P4JA(&H61tqQi=opRzNpm zkrG}$^t9&XduK*Qa1?355wd8G2CI6QEh@Ua>AsD;7oRUNLPb76m4HG3K?)wF~IyS3`fXuNM>${?wmB zpVz;?6_(Fiadfd{vUCBM*_kt$+F3J+IojI;9L(gc9n3{sEZyzR9o!_mOwFC#tQ{Q~ zP3-`#uK#tP3Q7~Q;4H|wjZHO8h7e4IuBxl&vz2w~D8)w=Wtg31zpZhz%+kzSzL*dV zwp@{WU4i;hJ7c2f1O;7Mz6qRKeASoIv0_bV=i@NMG*l<#+;INk-^`5w@}Dj~;k=|}qM1vq_P z|GpBGe_IKq|LNy9SJhKOQ$c=5L{Dv|Q_lZl=-ky*BFBJLW9&y_C|!vyM~rQx=!vun z?rZJQB5t}Dctmui5i31C_;_}CEn}_W%>oSXtt>@kE1=JW*4*v4tPp;O6 zmAk{)m!)}34pTWg8{i>($%NQ(Tl;QC@J@FfBoc%Gr&m560^kgSfodAFrIjF}aIw)X zoXZ`@IsMkc8_=w%-7`D6Y4e*CG8k%Ud=GXhsTR50jUnm+R*0A(O3UKFg0`K;qp1bl z7``HN=?39ic_kR|^R^~w-*pa?Vj#7|e9F1iRx{GN2?wK!xR1GW!qa=~pjJb-#u1K8 zeR?Y2i-pt}yJq;SCiVHODIvQJX|ZJaT8nO+(?HXbLefulKKgM^B(UIO1r+S=7;kLJ zcH}1J=Px2jsh3Tec&v8Jcbng8;V-`#*UHt?hB(pmOipKwf3Lz8rG$heEB30Sg*2rx zV<|KN86$soN(I!BwO`1n^^uF2*x&vJ$2d$>+`(romzHP|)K_KkO6Hc>_dwMW-M(#S zK(~SiXT1@fvc#U+?|?PniDRm01)f^#55;nhM|wi?oG>yBsa?~?^xTU|fX-R(sTA+5 zaq}-8Tx7zrOy#3*JLIIVsBmHYLdD}!0NP!+ITW+Thn0)8SS!$@)HXwB3tY!fMxc#1 zMp3H?q3eD?u&Njx4;KQ5G>32+GRp1Ee5qMO0lZjaRRu&{W<&~DoJNGkcYF<5(Ab+J zgO>VhBl{okDPn78<%&e2mR{jwVCz5Og;*Z;;3%VvoGo_;HaGLWYF7q#jDX=Z#Ml`H z858YVV$%J|e<1n`%6Vsvq7GmnAV0wW4$5qQ3uR@1i>tW{xrl|ExywIc?fNgYlA?C5 zh$ezAFb5{rQu6i7BSS5*J-|9DQ{6^BVQ{b*lq`xS@RyrsJN?-t=MTMPY;WYeKBCNg z^2|pN!Q^WPJuuO4!|P@jzt&tY1Y8d%FNK5xK(!@`jO2aEA*4 zkO6b|UVBipci?){-Ke=+1;mGlND8)6+P;8sq}UXw2hn;fc7nM>g}GSMWu&v&fqh

iViYT=fZ(|3Ox^$aWPp4a8h24tD<|8-!aK0lHgL$N7Efw}J zVIB!7=T$U`ao1?upi5V4Et*-lTG0XvExbf!ya{cua==$WJyVG(CmA6Of*8E@DSE%L z`V^$qz&RU$7G5mg;8;=#`@rRG`-uS18$0WPN@!v2d{H2sOqP|!(cQ@ zUHo!d>>yFArLPf1q`uBvY32miqShLT1B@gDL4XoVTK&@owOoD)OIHXrYK-a1d$B{v zF^}8D3Y^g%^cnvScOSJR5QNH+BI%d|;J;wWM3~l>${fb8DNPg)wrf|GBP8p%LNGN# z3EaIiItgwtGgT&iYCFy9-LG}bMI|4LdmmJt@V@% zb6B)1kc=T)(|L@0;wr<>=?r04N;E&ef+7C^`wPWtyQe(*pD1pI_&XHy|0gIGHMekd zF_*M4yi6J&Z4LQj65)S zXwdM{SwUo%3SbPwFsHgqF@V|6afT|R6?&S;lw=8% z3}@9B=#JI3@B*#4s!O))~z zc>2_4Q_#&+5V`GFd?88^;c1i7;Vv_I*qt!_Yx*n=;rj!82rrR2rQ8u5(Ejlo{15P% zs~!{%XJ>FmJ})H^I9bn^Re&38H{xA!0l3^89k(oU;bZWXM@kn$#aoS&Y4l^-WEn-fH39Jb9lA%s*WsKJQl?n9B7_~P z-XM&WL7Z!PcoF6_D>V@$CvUIEy=+Z&0kt{szMk=f1|M+r*a43^$$B^MidrT0J;RI` z(?f!O<8UZkm$_Ny$Hth1J#^4ni+im8M9mr&k|3cIgwvjAgjH z8`N&h25xV#v*d$qBX5jkI|xOhQn!>IYZK7l5#^P4M&twe9&Ey@@GxYMxBZq2e7?`q z$~Szs0!g{2fGcp9PZEt|rdQ6bhAgpcLHPz?f-vB?$dc*!9OL?Q8mn7->bFD2Si60* z!O%y)fCdMSV|lkF9w%x~J*A&srMyYY3{=&$}H zGQ4VG_?$2X(0|vT0{=;W$~icCI{b6W{B!Q8xdGhF|D{25G_5_+%s(46lhvNLkik~R z>nr(&C#5wwOzJZQo9m|U<;&Wk!_#q|V>fsmj1g<6%hB{jGoNUPjgJslld>xmODzGjYc?7JSuA?A_QzjDw5AsRgi@Y|Z0{F{!1=!NES-#*f^s4l0Hu zz468))2IY5dmD9pa*(yT5{EyP^G>@ZWumealS-*WeRcZ}B%gxq{MiJ|RyX-^C1V=0 z@iKdrGi1jTe8Ya^x7yyH$kBNvM4R~`fbPq$BzHum-3Zo8C6=KW@||>zsA8-Y9uV5V z#oq-f5L5}V<&wF4@X@<3^C%ptp6+Ce)~hGl`kwj)bsAjmo_GU^r940Z-|`<)oGnh7 zFF0Tde3>ui?8Yj{sF-Z@)yQd~CGZ*w-6p2U<8}JO-sRsVI5dBji`01W8A&3$?}lxBaC&vn0E$c5tW* zX>5(zzZ=qn&!J~KdsPl;P@bmA-Pr8T*)eh_+Dv5=Ma|XSle6t(k8qcgNyar{*ReQ8 zTXwi=8vr>!3Ywr+BhggHDw8ke==NTQVMCK`$69fhzEFB*4+H9LIvdt-#IbhZvpS}} zO3lz;P?zr0*0$%-Rq_y^k(?I{Mk}h@w}cZpMUp|ucs55bcloL2)($u%mXQw({Wzc~ z;6nu5MkjP)0C(@%6Q_I_vsWrfhl7Zpoxw#WoE~r&GOSCz;_ro6i(^hM>I$8y>`!wW z*U^@?B!MMmb89I}2(hcE4zN2G^kwyWCZp5JG>$Ez7zP~D=J^LMjSM)27_0B_X^C(M z`fFT+%DcKlu?^)FCK>QzSnV%IsXVcUFhFdBP!6~se&xxrIxsvySAWu++IrH;FbcY$ z2DWTvSBRfLwdhr0nMx+URA$j3i7_*6BWv#DXfym?ZRDcX9C?cY9sD3q)uBDR3uWg= z(lUIzB)G$Hr!){>E{s4Dew+tb9kvToZp-1&c?y2wn@Z~(VBhqz`cB;{E4(P3N2*nJ z_>~g@;UF2iG{Kt(<1PyePTKahF8<)pozZ*xH~U-kfoAayCwJViIrnqwqO}7{0pHw$ zs2Kx?s#vQr7XZ264>5RNKSL8|Ty^=PsIx^}QqOOcfpGUU4tRkUc|kc7-!Ae6!+B{o~7nFpm3|G5^=0#Bnm6`V}oSQlrX(u%OWnC zoLPy&Q;1Jui&7ST0~#+}I^&?vcE*t47~Xq#YwvA^6^} z`WkC)$AkNub|t@S!$8CBlwbV~?yp&@9h{D|3z-vJXgzRC5^nYm+PyPcgRzAnEi6Q^gslXYRv4nycsy-SJu?lMps-? zV`U*#WnFsdPLL)Q$AmD|0`UaC4ND07+&UmOu!eHruzV|OUox<+Jl|Mr@6~C`T@P%s zW7sgXLF2SSe9Fl^O(I*{9wsFSYb2l%-;&Pi^dpv!{)C3d0AlNY6!4fgmSgj_wQ*7Am7&$z;Jg&wgR-Ih;lUvWS|KTSg!&s_E9_bXBkZvGiC6bFKDWZxsD$*NZ#_8bl zG1P-#@?OQzED7@jlMJTH@V!6k;W>auvft)}g zhoV{7$q=*;=l{O>Q4a@ ziMjf_u*o^PsO)#BjC%0^h>Xp@;5$p{JSYDt)zbb}s{Kbt!T*I@Pk@X0zds6wsefuU zW$XY%yyRGC94=6mf?x+bbA5CDQ2AgW1T-jVAJbm7K(gp+;v6E0WI#kuACgV$r}6L? zd|Tj?^%^*N&b>Dd{Wr$FS2qI#Ucs1yd4N+RBUQiSZGujH`#I)mG&VKoDh=KKFl4=G z&MagXl6*<)$6P}*Tiebpz5L=oMaPrN+caUXRJ`D?=K9!e0f{@D&cZLKN?iNP@X0aF zE(^pl+;*T5qt?1jRC=5PMgV!XNITRLS_=9{CJExaQj;lt!&pdzpK?8p>%Mb+D z?yO*uSung=-`QQ@yX@Hyd4@CI^r{2oiu`%^bNkz+Nkk!IunjwNC|WcqvX~k=><-I3 zDQdbdb|!v+Iz01$w@aMl!R)koD77Xp;eZwzSl-AT zr@Vu{=xvgfq9akRrrM)}=!=xcs+U1JO}{t(avgz`6RqiiX<|hGG1pmop8k6Q+G_mv zJv|RfDheUp2L3=^C=4aCBMBn0aRCU(DQwX-W(RkRwmLeuJYF<0urcaf(=7)JPg<3P zQs!~G)9CT18o!J4{zX{_e}4eS)U-E)0FAt}wEI(c0%HkxgggW;(1E=>J17_hsH^sP z%lT0LGgbUXHx-K*CI-MCrP66UP0PvGqM$MkeLyqHdbgP|_Cm!7te~b8p+e6sQ_3k| zVcwTh6d83ltdnR>D^)BYQpDKlLk3g0Hdcgz2}%qUs9~~Rie)A-BV1mS&naYai#xcZ z(d{8=-LVpTp}2*y)|gR~;qc7fp26}lPcLZ#=JpYcn3AT9(UIdOyg+d(P5T7D&*P}# zQCYplZO5|7+r19%9e`v^vfSS1sbX1c%=w1;oyruXB%Kl$ACgKQ6=qNWLsc=28xJjg zwvsI5-%SGU|3p>&zXVl^vVtQT3o-#$UT9LI@Npz~6=4!>mc431VRNN8od&Ul^+G_kHC`G=6WVWM z%9eWNyy(FTO|A+@x}Ou3CH)oi;t#7rAxdIXfNFwOj_@Y&TGz6P_sqiB`Q6Lxy|Q{`|fgmRG(k+!#b*M+Z9zFce)f-7;?Km5O=LHV9f9_87; zF7%R2B+$?@sH&&-$@tzaPYkw0;=i|;vWdI|Wl3q_Zu>l;XdIw2FjV=;Mq5t1Q0|f< zs08j54Bp`3RzqE=2enlkZxmX6OF+@|2<)A^RNQpBd6o@OXl+i)zO%D4iGiQNuXd+zIR{_lb96{lc~bxsBveIw6umhShTX+3@ZJ=YHh@ zWY3(d0azg;7oHn>H<>?4@*RQbi>SmM=JrHvIG(~BrvI)#W(EAeO6fS+}mxxcc+X~W6&YVl86W9WFSS}Vz-f9vS?XUDBk)3TcF z8V?$4Q)`uKFq>xT=)Y9mMFVTUk*NIA!0$?RP6Ig0TBmUFrq*Q-Agq~DzxjStQyJ({ zBeZ;o5qUUKg=4Hypm|}>>L=XKsZ!F$yNTDO)jt4H0gdQ5$f|d&bnVCMMXhNh)~mN z@_UV6D7MVlsWz+zM+inZZp&P4fj=tm6fX)SG5H>OsQf_I8c~uGCig$GzuwViK54bcgL;VN|FnyQl>Ed7(@>=8$a_UKIz|V6CeVSd2(P z0Uu>A8A+muM%HLFJQ9UZ5c)BSAv_zH#1f02x?h9C}@pN@6{>UiAp>({Fn(T9Q8B z^`zB;kJ5b`>%dLm+Ol}ty!3;8f1XDSVX0AUe5P#@I+FQ-`$(a;zNgz)4x5hz$Hfbg z!Q(z26wHLXko(1`;(BAOg_wShpX0ixfWq3ponndY+u%1gyX)_h=v1zR#V}#q{au6; z!3K=7fQwnRfg6FXtNQmP>`<;!N137paFS%y?;lb1@BEdbvQHYC{976l`cLqn;b8lp zIDY>~m{gDj(wfnK!lpW6pli)HyLEiUrNc%eXTil|F2s(AY+LW5hkKb>TQ3|Q4S9rr zpDs4uK_co6XPsn_z$LeS{K4jFF`2>U`tbgKdyDne`xmR<@6AA+_hPNKCOR-Zqv;xk zu5!HsBUb^!4uJ7v0RuH-7?l?}b=w5lzzXJ~gZcxRKOovSk@|#V+MuX%Y+=;14i*%{)_gSW9(#4%)AV#3__kac1|qUy!uyP{>?U#5wYNq}y$S9pCc zFc~4mgSC*G~j0u#qqp9 z${>3HV~@->GqEhr_Xwoxq?Hjn#=s2;i~g^&Hn|aDKpA>Oc%HlW(KA1?BXqpxB;Ydx)w;2z^MpjJ(Qi(X!$5RC z*P{~%JGDQqojV>2JbEeCE*OEu!$XJ>bWA9Oa_Hd;y)F%MhBRi*LPcdqR8X`NQ&1L# z5#9L*@qxrx8n}LfeB^J{%-?SU{FCwiWyHp682F+|pa+CQa3ZLzBqN1{)h4d6+vBbV zC#NEbQLC;}me3eeYnOG*nXOJZEU$xLZ1<1Y=7r0(-U0P6-AqwMAM`a(Ed#7vJkn6plb4eI4?2y3yOTGmmDQ!z9`wzbf z_OY#0@5=bnep;MV0X_;;SJJWEf^E6Bd^tVJ9znWx&Ks8t*B>AM@?;D4oWUGc z!H*`6d7Cxo6VuyS4Eye&L1ZRhrRmN6Lr`{NL(wDbif|y&z)JN>Fl5#Wi&mMIr5i;x zBx}3YfF>>8EC(fYnmpu~)CYHuHCyr5*`ECap%t@y=jD>!_%3iiE|LN$mK9>- zHdtpy8fGZtkZF?%TW~29JIAfi2jZT8>OA7=h;8T{{k?c2`nCEx9$r zS+*&vt~2o^^J+}RDG@+9&M^K*z4p{5#IEVbz`1%`m5c2};aGt=V?~vIM}ZdPECDI)47|CWBCfDWUbxBCnmYivQ*0Nu_xb*C>~C9(VjHM zxe<*D<#dQ8TlpMX2c@M<9$w!RP$hpG4cs%AI){jp*Sj|*`m)5(Bw*A0$*i-(CA5#%>a)$+jI2C9r6|(>J8InryENI z$NohnxDUB;wAYDwrb*!N3noBTKPpPN}~09SEL18tkG zxgz(RYU_;DPT{l?Q$+eaZaxnsWCA^ds^0PVRkIM%bOd|G2IEBBiz{&^JtNsODs;5z zICt_Zj8wo^KT$7Bg4H+y!Df#3mbl%%?|EXe!&(Vmac1DJ*y~3+kRKAD=Ovde4^^%~ zw<9av18HLyrf*_>Slp;^i`Uy~`mvBjZ|?Ad63yQa#YK`4+c6;pW4?XIY9G1(Xh9WO8{F-Aju+nS9Vmv=$Ac0ienZ+p9*O%NG zMZKy5?%Z6TAJTE?o5vEr0r>f>hb#2w2U3DL64*au_@P!J!TL`oH2r*{>ffu6|A7tv zL4juf$DZ1MW5ZPsG!5)`k8d8c$J$o;%EIL0va9&GzWvkS%ZsGb#S(?{!UFOZ9<$a| zY|a+5kmD5N&{vRqkgY>aHsBT&`rg|&kezoD)gP0fsNYHsO#TRc_$n6Lf1Z{?+DLziXlHrq4sf(!>O{?Tj;Eh@%)+nRE_2VxbN&&%%caU#JDU%vL3}Cb zsb4AazPI{>8H&d=jUaZDS$-0^AxE@utGs;-Ez_F(qC9T=UZX=>ok2k2 ziTn{K?y~a5reD2A)P${NoI^>JXn>`IeArow(41c-Wm~)wiryEP(OS{YXWi7;%dG9v zI?mwu1MxD{yp_rrk!j^cKM)dc4@p4Ezyo%lRN|XyD}}>v=Xoib0gOcdXrQ^*61HNj z=NP|pd>@yfvr-=m{8$3A8TQGMTE7g=z!%yt`8`Bk-0MMwW~h^++;qyUP!J~ykh1GO z(FZ59xuFR$(WE;F@UUyE@Sp>`aVNjyj=Ty>_Vo}xf`e7`F;j-IgL5`1~-#70$9_=uBMq!2&1l zomRgpD58@)YYfvLtPW}{C5B35R;ZVvB<<#)x%srmc_S=A7F@DW8>QOEGwD6suhwCg z>Pa+YyULhmw%BA*4yjDp|2{!T98~<6Yfd(wo1mQ!KWwq0eg+6)o1>W~f~kL<-S+P@$wx*zeI|1t7z#Sxr5 zt6w+;YblPQNplq4Z#T$GLX#j6yldXAqj>4gAnnWtBICUnA&-dtnlh=t0Ho_vEKwV` z)DlJi#!@nkYV#$!)@>udAU*hF?V`2$Hf=V&6PP_|r#Iv*J$9)pF@X3`k;5})9^o4y z&)~?EjX5yX12O(BsFy-l6}nYeuKkiq`u9145&3Ssg^y{5G3Pse z9w(YVa0)N-fLaBq1`P!_#>SS(8fh_5!f{UrgZ~uEdeMJIz7DzI5!NHHqQtm~#CPij z?=N|J>nPR6_sL7!f4hD_|KH`vf8(Wpnj-(gPWH+ZvID}%?~68SwhPTC3u1_cB`otq z)U?6qo!ZLi5b>*KnYHWW=3F!p%h1;h{L&(Q&{qY6)_qxNfbP6E3yYpW!EO+IW3?@J z);4>g4gnl^8klu7uA>eGF6rIGSynacogr)KUwE_R4E5Xzi*Qir@b-jy55-JPC8c~( zo!W8y9OGZ&`xmc8;=4-U9=h{vCqfCNzYirONmGbRQlR`WWlgnY+1wCXbMz&NT~9*| z6@FrzP!LX&{no2!Ln_3|I==_4`@}V?4a;YZKTdw;vT<+K+z=uWbW(&bXEaWJ^W8Td z-3&1bY^Z*oM<=M}LVt>_j+p=2Iu7pZmbXrhQ_k)ysE9yXKygFNw$5hwDn(M>H+e1&9BM5!|81vd%r%vEm zqxY3?F@fb6O#5UunwgAHR9jp_W2zZ}NGp2%mTW@(hz7$^+a`A?mb8|_G*GNMJ) zjqegXQio=i@AINre&%ofexAr95aop5C+0MZ0m-l=MeO8m3epm7U%vZB8+I+C*iNFM z#T3l`gknX;D$-`2XT^Cg*vrv=RH+P;_dfF++cP?B_msQI4j+lt&rX2)3GaJx%W*Nn zkML%D{z5tpHH=dksQ*gzc|}gzW;lwAbxoR07VNgS*-c3d&8J|;@3t^ zVUz*J*&r7DFRuFVDCJDK8V9NN5hvpgGjwx+5n)qa;YCKe8TKtdnh{I7NU9BCN!0dq zczrBk8pE{{@vJa9ywR@mq*J=v+PG;?fwqlJVhijG!3VmIKs>9T6r7MJpC)m!Tc#>g zMtVsU>wbwFJEfwZ{vB|ZlttNe83)$iz`~#8UJ^r)lJ@HA&G#}W&ZH*;k{=TavpjWE z7hdyLZPf*X%Gm}i`Y{OGeeu^~nB8=`{r#TUrM-`;1cBvEd#d!kPqIgYySYhN-*1;L z^byj%Yi}Gx)Wnkosi337BKs}+5H5dth1JA{Ir-JKN$7zC)*}hqeoD(WfaUDPT>0`- z(6sa0AoIqASwF`>hP}^|)a_j2s^PQn*qVC{Q}htR z5-)duBFXT_V56-+UohKXlq~^6uf!6sA#ttk1o~*QEy_Y-S$gAvq47J9Vtk$5oA$Ct zYhYJ@8{hsC^98${!#Ho?4y5MCa7iGnfz}b9jE~h%EAAv~Qxu)_rAV;^cygV~5r_~?l=B`zObj7S=H=~$W zPtI_m%g$`kL_fVUk9J@>EiBH zOO&jtn~&`hIFMS5S`g8w94R4H40mdNUH4W@@XQk1sr17b{@y|JB*G9z1|CrQjd+GX z6+KyURG3;!*BQrentw{B2R&@2&`2}n(z-2&X7#r!{yg@Soy}cRD~j zj9@UBW+N|4HW4AWapy4wfUI- zZ`gSL6DUlgj*f1hSOGXG0IVH8HxK?o2|3HZ;KW{K+yPAlxtb)NV_2AwJm|E)FRs&& z=c^e7bvUsztY|+f^k7NXs$o1EUq>cR7C0$UKi6IooHWlK_#?IWDkvywnzg&ThWo^? z2O_N{5X39#?eV9l)xI(>@!vSB{DLt*oY!K1R8}_?%+0^C{d9a%N4 zoxHVT1&Lm|uDX%$QrBun5e-F`HJ^T$ zmzv)p@4ZHd_w9!%Hf9UYNvGCw2TTTbrj9pl+T9%-_-}L(tES>Or-}Z4F*{##n3~L~TuxjirGuIY#H7{%$E${?p{Q01 zi6T`n;rbK1yIB9jmQNycD~yZq&mbIsFWHo|ZAChSFPQa<(%d8mGw*V3fh|yFoxOOiWJd(qvVb!Z$b88cg->N=qO*4k~6;R==|9ihg&riu#P~s4Oap9O7f%crSr^rljeIfXDEg>wi)&v*a%7zpz<9w z*r!3q9J|390x`Zk;g$&OeN&ctp)VKRpDSV@kU2Q>jtok($Y-*x8_$2piTxun81@vt z!Vj?COa0fg2RPXMSIo26T=~0d`{oGP*eV+$!0I<(4azk&Vj3SiG=Q!6mX0p$z7I}; z9BJUFgT-K9MQQ-0@Z=^7R<{bn2Fm48endsSs`V7_@%8?Bxkqv>BDoVcj?K#dV#uUP zL1ND~?D-|VGKe3Rw_7-Idpht>H6XRLh*U7epS6byiGvJpr%d}XwfusjH9g;Z98H`x zyde%%5mhGOiL4wljCaWCk-&uE4_OOccb9c!ZaWt4B(wYl!?vyzl%7n~QepN&eFUrw zFIOl9c({``6~QD+43*_tzP{f2x41h(?b43^y6=iwyB)2os5hBE!@YUS5?N_tXd=h( z)WE286Fbd>R4M^P{!G)f;h<3Q>Fipuy+d2q-)!RyTgt;wr$(?9ox3;q+{E*ZQHhOn;lM`cjnu9 zXa48ks-v(~b*;MAI<>YZH(^NV8vjb34beE<_cwKlJoR;k6lJNSP6v}uiyRD?|0w+X@o1ONrH8a$fCxXpf? z?$DL0)7|X}Oc%h^zrMKWc-NS9I0Utu@>*j}b@tJ=ixQSJ={4@854wzW@E>VSL+Y{i z#0b=WpbCZS>kUCO_iQz)LoE>P5LIG-hv9E+oG}DtlIDF>$tJ1aw9^LuhLEHt?BCj& z(O4I8v1s#HUi5A>nIS-JK{v!7dJx)^Yg%XjNmlkWAq2*cv#tHgz`Y(bETc6CuO1VkN^L-L3j_x<4NqYb5rzrLC-7uOv z!5e`GZt%B782C5-fGnn*GhDF$%(qP<74Z}3xx+{$4cYKy2ikxI7B2N+2r07DN;|-T->nU&!=Cm#rZt%O_5c&1Z%nlWq3TKAW0w zQqemZw_ue--2uKQsx+niCUou?HjD`xhEjjQd3%rrBi82crq*~#uA4+>vR<_S{~5ce z-2EIl?~s z1=GVL{NxP1N3%=AOaC}j_Fv=ur&THz zyO!d9kHq|c73kpq`$+t+8Bw7MgeR5~`d7ChYyGCBWSteTB>8WAU(NPYt2Dk`@#+}= zI4SvLlyk#pBgVigEe`?NG*vl7V6m+<}%FwPV=~PvvA)=#ths==DRTDEYh4V5}Cf$z@#;< zyWfLY_5sP$gc3LLl2x+Ii)#b2nhNXJ{R~vk`s5U7Nyu^3yFg&D%Txwj6QezMX`V(x z=C`{76*mNb!qHHs)#GgGZ_7|vkt9izl_&PBrsu@}L`X{95-2jf99K)0=*N)VxBX2q z((vkpP2RneSIiIUEnGb?VqbMb=Zia+rF~+iqslydE34cSLJ&BJW^3knX@M;t*b=EA zNvGzv41Ld_T+WT#XjDB840vovUU^FtN_)G}7v)1lPetgpEK9YS^OWFkPoE{ovj^=@ zO9N$S=G$1ecndT_=5ehth2Lmd1II-PuT~C9`XVePw$y8J#dpZ?Tss<6wtVglm(Ok7 z3?^oi@pPio6l&!z8JY(pJvG=*pI?GIOu}e^EB6QYk$#FJQ%^AIK$I4epJ+9t?KjqA+bkj&PQ*|vLttme+`9G=L% ziadyMw_7-M)hS(3E$QGNCu|o23|%O+VN7;Qggp?PB3K-iSeBa2b}V4_wY`G1Jsfz4 z9|SdB^;|I8E8gWqHKx!vj_@SMY^hLEIbSMCuE?WKq=c2mJK z8LoG-pnY!uhqFv&L?yEuxo{dpMTsmCn)95xanqBrNPTgXP((H$9N${Ow~Is-FBg%h z53;|Y5$MUN)9W2HBe2TD`ct^LHI<(xWrw}$qSoei?}s)&w$;&!14w6B6>Yr6Y8b)S z0r71`WmAvJJ`1h&poLftLUS6Ir zC$bG9!Im_4Zjse)#K=oJM9mHW1{%l8sz$1o?ltdKlLTxWWPB>Vk22czVt|1%^wnN@*!l)}?EgtvhC>vlHm^t+ogpgHI1_$1ox9e;>0!+b(tBrmXRB`PY1vp-R**8N7 zGP|QqI$m(Rdu#=(?!(N}G9QhQ%o!aXE=aN{&wtGP8|_qh+7a_j_sU5|J^)vxq;# zjvzLn%_QPHZZIWu1&mRAj;Sa_97p_lLq_{~j!M9N^1yp3U_SxRqK&JnR%6VI#^E12 z>CdOVI^_9aPK2eZ4h&^{pQs}xsijXgFYRIxJ~N7&BB9jUR1fm!(xl)mvy|3e6-B3j zJn#ajL;bFTYJ2+Q)tDjx=3IklO@Q+FFM}6UJr6km7hj7th9n_&JR7fnqC!hTZoM~T zBeaVFp%)0cbPhejX<8pf5HyRUj2>aXnXBqDJe73~J%P(2C?-RT{c3NjE`)om! zl$uewSgWkE66$Kb34+QZZvRn`fob~Cl9=cRk@Es}KQm=?E~CE%spXaMO6YmrMl%9Q zlA3Q$3|L1QJ4?->UjT&CBd!~ru{Ih^in&JXO=|<6J!&qp zRe*OZ*cj5bHYlz!!~iEKcuE|;U4vN1rk$xq6>bUWD*u(V@8sG^7>kVuo(QL@Ki;yL zWC!FT(q{E8#on>%1iAS0HMZDJg{Z{^!De(vSIq&;1$+b)oRMwA3nc3mdTSG#3uYO_ z>+x;7p4I;uHz?ZB>dA-BKl+t-3IB!jBRgdvAbW!aJ(Q{aT>+iz?91`C-xbe)IBoND z9_Xth{6?(y3rddwY$GD65IT#f3<(0o#`di{sh2gm{dw*#-Vnc3r=4==&PU^hCv$qd zjw;>i&?L*Wq#TxG$mFIUf>eK+170KG;~+o&1;Tom9}}mKo23KwdEM6UonXgc z!6N(@k8q@HPw{O8O!lAyi{rZv|DpgfU{py+j(X_cwpKqcalcqKIr0kM^%Br3SdeD> zHSKV94Yxw;pjzDHo!Q?8^0bb%L|wC;4U^9I#pd5O&eexX+Im{ z?jKnCcsE|H?{uGMqVie_C~w7GX)kYGWAg%-?8|N_1#W-|4F)3YTDC+QSq1s!DnOML3@d`mG%o2YbYd#jww|jD$gotpa)kntakp#K;+yo-_ZF9qrNZw<%#C zuPE@#3RocLgPyiBZ+R_-FJ_$xP!RzWm|aN)S+{$LY9vvN+IW~Kf3TsEIvP+B9Mtm! zpfNNxObWQpLoaO&cJh5>%slZnHl_Q~(-Tfh!DMz(dTWld@LG1VRF`9`DYKhyNv z2pU|UZ$#_yUx_B_|MxUq^glT}O5Xt(Vm4Mr02><%C)@v;vPb@pT$*yzJ4aPc_FZ3z z3}PLoMBIM>q_9U2rl^sGhk1VUJ89=*?7|v`{!Z{6bqFMq(mYiA?%KbsI~JwuqVA9$H5vDE+VocjX+G^%bieqx->s;XWlKcuv(s%y%D5Xbc9+ zc(_2nYS1&^yL*ey664&4`IoOeDIig}y-E~_GS?m;D!xv5-xwz+G`5l6V+}CpeJDi^ z%4ed$qowm88=iYG+(`ld5Uh&>Dgs4uPHSJ^TngXP_V6fPyl~>2bhi20QB%lSd#yYn zO05?KT1z@?^-bqO8Cg`;ft>ilejsw@2%RR7;`$Vs;FmO(Yr3Fp`pHGr@P2hC%QcA|X&N2Dn zYf`MqXdHi%cGR@%y7Rg7?d3?an){s$zA{!H;Ie5exE#c~@NhQUFG8V=SQh%UxUeiV zd7#UcYqD=lk-}sEwlpu&H^T_V0{#G?lZMxL7ih_&{(g)MWBnCZxtXg znr#}>U^6!jA%e}@Gj49LWG@*&t0V>Cxc3?oO7LSG%~)Y5}f7vqUUnQ;STjdDU}P9IF9d9<$;=QaXc zL1^X7>fa^jHBu_}9}J~#-oz3Oq^JmGR#?GO7b9a(=R@fw@}Q{{@`Wy1vIQ#Bw?>@X z-_RGG@wt|%u`XUc%W{J z>iSeiz8C3H7@St3mOr_mU+&bL#Uif;+Xw-aZdNYUpdf>Rvu0i0t6k*}vwU`XNO2he z%miH|1tQ8~ZK!zmL&wa3E;l?!!XzgV#%PMVU!0xrDsNNZUWKlbiOjzH-1Uoxm8E#r`#2Sz;-o&qcqB zC-O_R{QGuynW14@)7&@yw1U}uP(1cov)twxeLus0s|7ayrtT8c#`&2~Fiu2=R;1_4bCaD=*E@cYI>7YSnt)nQc zohw5CsK%m?8Ack)qNx`W0_v$5S}nO|(V|RZKBD+btO?JXe|~^Qqur%@eO~<8-L^9d z=GA3-V14ng9L29~XJ>a5k~xT2152zLhM*@zlp2P5Eu}bywkcqR;ISbas&#T#;HZSf z2m69qTV(V@EkY(1Dk3`}j)JMo%ZVJ*5eB zYOjIisi+igK0#yW*gBGj?@I{~mUOvRFQR^pJbEbzFxTubnrw(Muk%}jI+vXmJ;{Q6 zrSobKD>T%}jV4Ub?L1+MGOD~0Ir%-`iTnWZN^~YPrcP5y3VMAzQ+&en^VzKEb$K!Q z<7Dbg&DNXuow*eD5yMr+#08nF!;%4vGrJI++5HdCFcGLfMW!KS*Oi@=7hFwDG!h2< zPunUEAF+HncQkbfFj&pbzp|MU*~60Z(|Ik%Tn{BXMN!hZOosNIseT?R;A`W?=d?5X zK(FB=9mZusYahp|K-wyb={rOpdn=@;4YI2W0EcbMKyo~-#^?h`BA9~o285%oY zfifCh5Lk$SY@|2A@a!T2V+{^!psQkx4?x0HSV`(w9{l75QxMk!)U52Lbhn{8ol?S) zCKo*7R(z!uk<6*qO=wh!Pul{(qq6g6xW;X68GI_CXp`XwO zxuSgPRAtM8K7}5E#-GM!*ydOOG_{A{)hkCII<|2=ma*71ci_-}VPARm3crFQjLYV! z9zbz82$|l01mv`$WahE2$=fAGWkd^X2kY(J7iz}WGS z@%MyBEO=A?HB9=^?nX`@nh;7;laAjs+fbo!|K^mE!tOB>$2a_O0y-*uaIn8k^6Y zSbuv;5~##*4Y~+y7Z5O*3w4qgI5V^17u*ZeupVGH^nM&$qmAk|anf*>r zWc5CV;-JY-Z@Uq1Irpb^O`L_7AGiqd*YpGUShb==os$uN3yYvb`wm6d=?T*it&pDk zo`vhw)RZX|91^^Wa_ti2zBFyWy4cJu#g)_S6~jT}CC{DJ_kKpT`$oAL%b^!2M;JgT zM3ZNbUB?}kP(*YYvXDIH8^7LUxz5oE%kMhF!rnPqv!GiY0o}NR$OD=ITDo9r%4E>E0Y^R(rS^~XjWyVI6 zMOR5rPXhTp*G*M&X#NTL`Hu*R+u*QNoiOKg4CtNPrjgH>c?Hi4MUG#I917fx**+pJfOo!zFM&*da&G_x)L(`k&TPI*t3e^{crd zX<4I$5nBQ8Ax_lmNRa~E*zS-R0sxkz`|>7q_?*e%7bxqNm3_eRG#1ae3gtV9!fQpY z+!^a38o4ZGy9!J5sylDxZTx$JmG!wg7;>&5H1)>f4dXj;B+@6tMlL=)cLl={jLMxY zbbf1ax3S4>bwB9-$;SN2?+GULu;UA-35;VY*^9Blx)Jwyb$=U!D>HhB&=jSsd^6yw zL)?a|>GxU!W}ocTC(?-%z3!IUhw^uzc`Vz_g>-tv)(XA#JK^)ZnC|l1`@CdX1@|!| z_9gQ)7uOf?cR@KDp97*>6X|;t@Y`k_N@)aH7gY27)COv^P3ya9I{4z~vUjLR9~z1Z z5=G{mVtKH*&$*t0@}-i_v|3B$AHHYale7>E+jP`ClqG%L{u;*ff_h@)al?RuL7tOO z->;I}>%WI{;vbLP3VIQ^iA$4wl6@0sDj|~112Y4OFjMs`13!$JGkp%b&E8QzJw_L5 zOnw9joc0^;O%OpF$Qp)W1HI!$4BaXX84`%@#^dk^hFp^pQ@rx4g(8Xjy#!X%+X5Jd@fs3amGT`}mhq#L97R>OwT5-m|h#yT_-v@(k$q7P*9X~T*3)LTdzP!*B} z+SldbVWrrwQo9wX*%FyK+sRXTa@O?WM^FGWOE?S`R(0P{<6p#f?0NJvnBia?k^fX2 zNQs7K-?EijgHJY}&zsr;qJ<*PCZUd*x|dD=IQPUK_nn)@X4KWtqoJNHkT?ZWL_hF? zS8lp2(q>;RXR|F;1O}EE#}gCrY~#n^O`_I&?&z5~7N;zL0)3Tup`%)oHMK-^r$NT% zbFg|o?b9w(q@)6w5V%si<$!U<#}s#x@0aX-hP>zwS#9*75VXA4K*%gUc>+yzupTDBOKH8WR4V0pM(HrfbQ&eJ79>HdCvE=F z|J>s;;iDLB^3(9}?biKbxf1$lI!*Z%*0&8UUq}wMyPs_hclyQQi4;NUY+x2qy|0J; zhn8;5)4ED1oHwg+VZF|80<4MrL97tGGXc5Sw$wAI#|2*cvQ=jB5+{AjMiDHmhUC*a zlmiZ`LAuAn_}hftXh;`Kq0zblDk8?O-`tnilIh|;3lZp@F_osJUV9`*R29M?7H{Fy z`nfVEIDIWXmU&YW;NjU8)EJpXhxe5t+scf|VXM!^bBlwNh)~7|3?fWwo_~ZFk(22% zTMesYw+LNx3J-_|DM~`v93yXe=jPD{q;li;5PD?Dyk+b? zo21|XpT@)$BM$%F=P9J19Vi&1#{jM3!^Y&fr&_`toi`XB1!n>sbL%U9I5<7!@?t)~ z;&H%z>bAaQ4f$wIzkjH70;<8tpUoxzKrPhn#IQfS%9l5=Iu))^XC<58D!-O z{B+o5R^Z21H0T9JQ5gNJnqh#qH^na|z92=hONIM~@_iuOi|F>jBh-?aA20}Qx~EpDGElELNn~|7WRXRFnw+Wdo`|# zBpU=Cz3z%cUJ0mx_1($X<40XEIYz(`noWeO+x#yb_pwj6)R(__%@_Cf>txOQ74wSJ z0#F3(zWWaR-jMEY$7C*3HJrohc79>MCUu26mfYN)f4M~4gD`}EX4e}A!U}QV8!S47 z6y-U-%+h`1n`*pQuKE%Av0@)+wBZr9mH}@vH@i{v(m-6QK7Ncf17x_D=)32`FOjjo zg|^VPf5c6-!FxN{25dvVh#fog=NNpXz zfB$o+0jbRkHH{!TKhE709f+jI^$3#v1Nmf80w`@7-5$1Iv_`)W^px8P-({xwb;D0y z7LKDAHgX<84?l!I*Dvi2#D@oAE^J|g$3!)x1Ua;_;<@#l1fD}lqU2_tS^6Ht$1Wl} zBESo7o^)9-Tjuz$8YQSGhfs{BQV6zW7dA?0b(Dbt=UnQs&4zHfe_sj{RJ4uS-vQpC zX;Bbsuju4%!o8?&m4UZU@~ZZjeFF6ex2ss5_60_JS_|iNc+R0GIjH1@Z z=rLT9%B|WWgOrR7IiIwr2=T;Ne?30M!@{%Qf8o`!>=s<2CBpCK_TWc(DX51>e^xh8 z&@$^b6CgOd7KXQV&Y4%}_#uN*mbanXq(2=Nj`L7H7*k(6F8s6{FOw@(DzU`4-*77{ zF+dxpv}%mFpYK?>N_2*#Y?oB*qEKB}VoQ@bzm>ptmVS_EC(#}Lxxx730trt0G)#$b zE=wVvtqOct1%*9}U{q<)2?{+0TzZzP0jgf9*)arV)*e!f`|jgT{7_9iS@e)recI#z zbzolURQ+TOzE!ymqvBY7+5NnAbWxvMLsLTwEbFqW=CPyCsmJ}P1^V30|D5E|p3BC5 z)3|qgw@ra7aXb-wsa|l^in~1_fm{7bS9jhVRkYVO#U{qMp z)Wce+|DJ}4<2gp8r0_xfZpMo#{Hl2MfjLcZdRB9(B(A(f;+4s*FxV{1F|4d`*sRNd zp4#@sEY|?^FIJ;tmH{@keZ$P(sLh5IdOk@k^0uB^BWr@pk6mHy$qf&~rI>P*a;h0C{%oA*i!VjWn&D~O#MxN&f@1Po# zKN+ zrGrkSjcr?^R#nGl<#Q722^wbYcgW@{+6CBS<1@%dPA8HC!~a`jTz<`g_l5N1M@9wn9GOAZ>nqNgq!yOCbZ@1z`U_N`Z>}+1HIZxk*5RDc&rd5{3qjRh8QmT$VyS;jK z;AF+r6XnnCp=wQYoG|rT2@8&IvKq*IB_WvS%nt%e{MCFm`&W*#LXc|HrD?nVBo=(8*=Aq?u$sDA_sC_RPDUiQ+wnIJET8vx$&fxkW~kP9qXKt zozR)@xGC!P)CTkjeWvXW5&@2?)qt)jiYWWBU?AUtzAN}{JE1I)dfz~7$;}~BmQF`k zpn11qmObXwRB8&rnEG*#4Xax3XBkKlw(;tb?Np^i+H8m(Wyz9k{~ogba@laiEk;2! zV*QV^6g6(QG%vX5Um#^sT&_e`B1pBW5yVth~xUs#0}nv?~C#l?W+9Lsb_5)!71rirGvY zTIJ$OPOY516Y|_014sNv+Z8cc5t_V=i>lWV=vNu#!58y9Zl&GsMEW#pPYPYGHQ|;vFvd*9eM==$_=vc7xnyz0~ zY}r??$<`wAO?JQk@?RGvkWVJlq2dk9vB(yV^vm{=NVI8dhsX<)O(#nr9YD?I?(VmQ z^r7VfUBn<~p3()8yOBjm$#KWx!5hRW)5Jl7wY@ky9lNM^jaT##8QGVsYeaVywmpv>X|Xj7gWE1Ezai&wVLt3p)k4w~yrskT-!PR!kiyQlaxl(( zXhF%Q9x}1TMt3~u@|#wWm-Vq?ZerK={8@~&@9r5JW}r#45#rWii};t`{5#&3$W)|@ zbAf2yDNe0q}NEUvq_Quq3cTjcw z@H_;$hu&xllCI9CFDLuScEMg|x{S7GdV8<&Mq=ezDnRZAyX-8gv97YTm0bg=d)(>N z+B2FcqvI9>jGtnK%eO%y zoBPkJTk%y`8TLf4)IXPBn`U|9>O~WL2C~C$z~9|0m*YH<-vg2CD^SX#&)B4ngOSG$ zV^wmy_iQk>dfN@Pv(ckfy&#ak@MLC7&Q6Ro#!ezM*VEh`+b3Jt%m(^T&p&WJ2Oqvj zs-4nq0TW6cv~(YI$n0UkfwN}kg3_fp?(ijSV#tR9L0}l2qjc7W?i*q01=St0eZ=4h zyGQbEw`9OEH>NMuIe)hVwYHsGERWOD;JxEiO7cQv%pFCeR+IyhwQ|y@&^24k+|8fD zLiOWFNJ2&vu2&`Jv96_z-Cd5RLgmeY3*4rDOQo?Jm`;I_(+ejsPM03!ly!*Cu}Cco zrQSrEDHNyzT(D5s1rZq!8#?f6@v6dB7a-aWs(Qk>N?UGAo{gytlh$%_IhyL7h?DLXDGx zgxGEBQoCAWo-$LRvM=F5MTle`M})t3vVv;2j0HZY&G z22^iGhV@uaJh(XyyY%} zd4iH_UfdV#T=3n}(Lj^|n;O4|$;xhu*8T3hR1mc_A}fK}jfZ7LX~*n5+`8N2q#rI$ z@<_2VANlYF$vIH$ zl<)+*tIWW78IIINA7Rr7i{<;#^yzxoLNkXL)eSs=%|P>$YQIh+ea_3k z_s7r4%j7%&*NHSl?R4k%1>Z=M9o#zxY!n8sL5>BO-ZP;T3Gut>iLS@U%IBrX6BA3k z)&@q}V8a{X<5B}K5s(c(LQ=%v1ocr`t$EqqY0EqVjr65usa=0bkf|O#ky{j3)WBR(((L^wmyHRzoWuL2~WTC=`yZ zn%VX`L=|Ok0v7?s>IHg?yArBcync5rG#^+u)>a%qjES%dRZoIyA8gQ;StH z1Ao7{<&}6U=5}4v<)1T7t!J_CL%U}CKNs-0xWoTTeqj{5{?Be$L0_tk>M9o8 zo371}S#30rKZFM{`H_(L`EM9DGp+Mifk&IP|C2Zu_)Ghr4Qtpmkm1osCf@%Z$%t+7 zYH$Cr)Ro@3-QDeQJ8m+x6%;?YYT;k6Z0E-?kr>x33`H%*ueBD7Zx~3&HtWn0?2Wt} zTG}*|v?{$ajzt}xPzV%lL1t-URi8*Zn)YljXNGDb>;!905Td|mpa@mHjIH%VIiGx- zd@MqhpYFu4_?y5N4xiHn3vX&|e6r~Xt> zZG`aGq|yTNjv;9E+Txuoa@A(9V7g?1_T5FzRI;!=NP1Kqou1z5?%X~Wwb{trRfd>i z8&y^H)8YnKyA_Fyx>}RNmQIczT?w2J4SNvI{5J&}Wto|8FR(W;Qw#b1G<1%#tmYzQ zQ2mZA-PAdi%RQOhkHy9Ea#TPSw?WxwL@H@cbkZwIq0B!@ns}niALidmn&W?!Vd4Gj zO7FiuV4*6Mr^2xlFSvM;Cp_#r8UaqIzHJQg_z^rEJw&OMm_8NGAY2)rKvki|o1bH~ z$2IbfVeY2L(^*rMRU1lM5Y_sgrDS`Z??nR2lX;zyR=c%UyGb*%TC-Dil?SihkjrQy~TMv6;BMs7P8il`H7DmpVm@rJ;b)hW)BL)GjS154b*xq-NXq2cwE z^;VP7ua2pxvCmxrnqUYQMH%a%nHmwmI33nJM(>4LznvY*k&C0{8f*%?zggpDgkuz&JBx{9mfb@wegEl2v!=}Sq2Gaty0<)UrOT0{MZtZ~j5y&w zXlYa_jY)I_+VA-^#mEox#+G>UgvM!Ac8zI<%JRXM_73Q!#i3O|)lOP*qBeJG#BST0 zqohi)O!|$|2SeJQo(w6w7%*92S})XfnhrH_Z8qe!G5>CglP=nI7JAOW?(Z29;pXJ9 zR9`KzQ=WEhy*)WH>$;7Cdz|>*i>=##0bB)oU0OR>>N<21e4rMCHDemNi2LD>Nc$;& zQRFthpWniC1J6@Zh~iJCoLOxN`oCKD5Q4r%ynwgUKPlIEd#?QViIqovY|czyK8>6B zSP%{2-<;%;1`#0mG^B(8KbtXF;Nf>K#Di72UWE4gQ%(_26Koiad)q$xRL~?pN71ZZ zujaaCx~jXjygw;rI!WB=xrOJO6HJ!!w}7eiivtCg5K|F6$EXa)=xUC za^JXSX98W`7g-tm@uo|BKj39Dl;sg5ta;4qjo^pCh~{-HdLl6qI9Ix6f$+qiZ$}s= zNguKrU;u+T@ko(Vr1>)Q%h$?UKXCY>3se%&;h2osl2D zE4A9bd7_|^njDd)6cI*FupHpE3){4NQ*$k*cOWZ_?CZ>Z4_fl@n(mMnYK62Q1d@+I zr&O))G4hMihgBqRIAJkLdk(p(D~X{-oBUA+If@B}j& zsHbeJ3RzTq96lB7d($h$xTeZ^gP0c{t!Y0c)aQE;$FY2!mACg!GDEMKXFOPI^)nHZ z`aSPJpvV0|bbrzhWWkuPURlDeN%VT8tndV8?d)eN*i4I@u zVKl^6{?}A?P)Fsy?3oi#clf}L18t;TjNI2>eI&(ezDK7RyqFxcv%>?oxUlonv(px) z$vnPzRH`y5A(x!yOIfL0bmgeMQB$H5wenx~!ujQK*nUBW;@Em&6Xv2%s(~H5WcU2R z;%Nw<$tI)a`Ve!>x+qegJnQsN2N7HaKzrFqM>`6R*gvh%O*-%THt zrB$Nk;lE;z{s{r^PPm5qz(&lM{sO*g+W{sK+m3M_z=4=&CC>T`{X}1Vg2PEfSj2x_ zmT*(x;ov%3F?qoEeeM>dUn$a*?SIGyO8m806J1W1o+4HRhc2`9$s6hM#qAm zChQ87b~GEw{ADfs+5}FJ8+|bIlIv(jT$Ap#hSHoXdd9#w<#cA<1Rkq^*EEkknUd4& zoIWIY)sAswy6fSERVm&!SO~#iN$OgOX*{9@_BWFyJTvC%S++ilSfCrO(?u=Dc?CXZ zzCG&0yVR{Z`|ZF0eEApWEo#s9osV>F{uK{QA@BES#&;#KsScf>y zvs?vIbI>VrT<*!;XmQS=bhq%46-aambZ(8KU-wOO2=en~D}MCToB_u;Yz{)1ySrPZ z@=$}EvjTdzTWU7c0ZI6L8=yP+YRD_eMMos}b5vY^S*~VZysrkq<`cK3>>v%uy7jgq z0ilW9KjVDHLv0b<1K_`1IkbTOINs0=m-22c%M~l=^S}%hbli-3?BnNq?b`hx^HX2J zIe6ECljRL0uBWb`%{EA=%!i^4sMcj+U_TaTZRb+~GOk z^ZW!nky0n*Wb*r+Q|9H@ml@Z5gU&W`(z4-j!OzC1wOke`TRAYGZVl$PmQ16{3196( zO*?`--I}Qf(2HIwb2&1FB^!faPA2=sLg(@6P4mN)>Dc3i(B0;@O-y2;lM4akD>@^v z=u>*|!s&9zem70g7zfw9FXl1bpJW(C#5w#uy5!V?Q(U35A~$dR%LDVnq@}kQm13{} zd53q3N(s$Eu{R}k2esbftfjfOITCL;jWa$}(mmm}d(&7JZ6d3%IABCapFFYjdEjdK z&4Edqf$G^MNAtL=uCDRs&Fu@FXRgX{*0<(@c3|PNHa>L%zvxWS={L8%qw`STm+=Rd zA}FLspESSIpE_^41~#5yI2bJ=9`oc;GIL!JuW&7YetZ?0H}$$%8rW@*J37L-~Rsx!)8($nI4 zZhcZ2^=Y+p4YPl%j!nFJA|*M^gc(0o$i3nlphe+~-_m}jVkRN{spFs(o0ajW@f3K{ zDV!#BwL322CET$}Y}^0ixYj2w>&Xh12|R8&yEw|wLDvF!lZ#dOTHM9pK6@Nm-@9Lnng4ZHBgBSrr7KI8YCC9DX5Kg|`HsiwJHg2(7#nS;A{b3tVO?Z% za{m5b3rFV6EpX;=;n#wltDv1LE*|g5pQ+OY&*6qCJZc5oDS6Z6JD#6F)bWxZSF@q% z+1WV;m!lRB!n^PC>RgQCI#D1br_o^#iPk>;K2hB~0^<~)?p}LG%kigm@moD#q3PE+ zA^Qca)(xnqw6x>XFhV6ku9r$E>bWNrVH9fum0?4s?Rn2LG{Vm_+QJHse6xa%nzQ?k zKug4PW~#Gtb;#5+9!QBgyB@q=sk9=$S{4T>wjFICStOM?__fr+Kei1 z3j~xPqW;W@YkiUM;HngG!;>@AITg}vAE`M2Pj9Irl4w1fo4w<|Bu!%rh%a(Ai^Zhi zs92>v5;@Y(Zi#RI*ua*h`d_7;byQSa*v9E{2x$<-_=5Z<7{%)}4XExANcz@rK69T0x3%H<@frW>RA8^swA+^a(FxK| zFl3LD*ImHN=XDUkrRhp6RY5$rQ{bRgSO*(vEHYV)3Mo6Jy3puiLmU&g82p{qr0F?ohmbz)f2r{X2|T2 z$4fdQ=>0BeKbiVM!e-lIIs8wVTuC_m7}y4A_%ikI;Wm5$9j(^Y z(cD%U%k)X>_>9~t8;pGzL6L-fmQO@K; zo&vQzMlgY95;1BSkngY)e{`n0!NfVgf}2mB3t}D9@*N;FQ{HZ3Pb%BK6;5#-O|WI( zb6h@qTLU~AbVW#_6?c!?Dj65Now7*pU{h!1+eCV^KCuPAGs28~3k@ueL5+u|Z-7}t z9|lskE`4B7W8wMs@xJa{#bsCGDFoRSNSnmNYB&U7 zVGKWe%+kFB6kb)e;TyHfqtU6~fRg)f|>=5(N36)0+C z`hv65J<$B}WUc!wFAb^QtY31yNleq4dzmG`1wHTj=c*=hay9iD071Hc?oYoUk|M*_ zU1GihAMBsM@5rUJ(qS?9ZYJ6@{bNqJ`2Mr+5#hKf?doa?F|+^IR!8lq9)wS3tF_9n zW_?hm)G(M+MYb?V9YoX^_mu5h-LP^TL^!Q9Z7|@sO(rg_4+@=PdI)WL(B7`!K^ND- z-uIuVDCVEdH_C@c71YGYT^_Scf_dhB8Z2Xy6vGtBSlYud9vggOqv^L~F{BraSE_t} zIkP+Hp2&nH^-MNEs}^`oMLy11`PQW$T|K(`Bu*(f@)mv1-qY(_YG&J2M2<7k;;RK~ zL{Fqj9yCz8(S{}@c)S!65aF<=&eLI{hAMErCx&>i7OeDN>okvegO87OaG{Jmi<|}D zaT@b|0X{d@OIJ7zvT>r+eTzgLq~|Dpu)Z&db-P4z*`M$UL51lf>FLlq6rfG)%doyp z)3kk_YIM!03eQ8Vu_2fg{+osaEJPtJ-s36R+5_AEG12`NG)IQ#TF9c@$99%0iye+ zUzZ57=m2)$D(5Nx!n)=5Au&O0BBgwxIBaeI(mro$#&UGCr<;C{UjJVAbVi%|+WP(a zL$U@TYCxJ=1{Z~}rnW;7UVb7+ZnzgmrogDxhjLGo>c~MiJAWs&&;AGg@%U?Y^0JhL ze(x6Z74JG6FlOFK(T}SXQfhr}RIFl@QXKnIcXYF)5|V~e-}suHILKT-k|<*~Ij|VF zC;t@=uj=hot~*!C68G8hTA%8SzOfETOXQ|3FSaIEjvBJp(A)7SWUi5!Eu#yWgY+;n zlm<$+UDou*V+246_o#V4kMdto8hF%%Lki#zPh}KYXmMf?hrN0;>Mv%`@{0Qn`Ujp) z=lZe+13>^Q!9zT);H<(#bIeRWz%#*}sgUX9P|9($kexOyKIOc`dLux}c$7It4u|Rl z6SSkY*V~g_B-hMPo_ak>>z@AVQ(_N)VY2kB3IZ0G(iDUYw+2d7W^~(Jq}KY=JnWS( z#rzEa&0uNhJ>QE8iiyz;n2H|SV#Og+wEZv=f2%1ELX!SX-(d3tEj$5$1}70Mp<&eI zCkfbByL7af=qQE@5vDVxx1}FSGt_a1DoE3SDI+G)mBAna)KBG4p8Epxl9QZ4BfdAN zFnF|Y(umr;gRgG6NLQ$?ZWgllEeeq~z^ZS7L?<(~O&$5|y)Al^iMKy}&W+eMm1W z7EMU)u^ke(A1#XCV>CZ71}P}0x)4wtHO8#JRG3MA-6g=`ZM!FcICCZ{IEw8Dm2&LQ z1|r)BUG^0GzI6f946RrBlfB1Vs)~8toZf~7)+G;pv&XiUO(%5bm)pl=p>nV^o*;&T z;}@oZSibzto$arQgfkp|z4Z($P>dTXE{4O=vY0!)kDO* zGF8a4wq#VaFpLfK!iELy@?-SeRrdz%F*}hjKcA*y@mj~VD3!it9lhRhX}5YOaR9$} z3mS%$2Be7{l(+MVx3 z(4?h;P!jnRmX9J9sYN#7i=iyj_5q7n#X(!cdqI2lnr8T$IfOW<_v`eB!d9xY1P=2q&WtOXY=D9QYteP)De?S4}FK6#6Ma z=E*V+#s8>L;8aVroK^6iKo=MH{4yEZ_>N-N z`(|;aOATba1^asjxlILk<4}f~`39dBFlxj>Dw(hMYKPO3EEt1@S`1lxFNM+J@uB7T zZ8WKjz7HF1-5&2=l=fqF-*@>n5J}jIxdDwpT?oKM3s8Nr`x8JnN-kCE?~aM1H!hAE z%%w(3kHfGwMnMmNj(SU(w42OrC-euI>Dsjk&jz3ts}WHqmMpzQ3vZrsXrZ|}+MHA7 z068obeXZTsO*6RS@o3x80E4ok``rV^Y3hr&C1;|ZZ0|*EKO`$lECUYG2gVFtUTw)R z4Um<0ZzlON`zTdvVdL#KFoMFQX*a5wM0Czp%wTtfK4Sjs)P**RW&?lP$(<}q%r68Z zS53Y!d@&~ne9O)A^tNrXHhXBkj~$8j%pT1%%mypa9AW5E&s9)rjF4@O3ytH{0z6riz|@< zB~UPh*wRFg2^7EbQrHf0y?E~dHlkOxof_a?M{LqQ^C!i2dawHTPYUE=X@2(3<=OOxs8qn_(y>pU>u^}3y&df{JarR0@VJn0f+U%UiF=$Wyq zQvnVHESil@d|8&R<%}uidGh7@u^(%?$#|&J$pvFC-n8&A>utA=n3#)yMkz+qnG3wd zP7xCnF|$9Dif@N~L)Vde3hW8W!UY0BgT2v(wzp;tlLmyk2%N|0jfG$%<;A&IVrOI< z!L)o>j>;dFaqA3pL}b-Je(bB@VJ4%!JeX@3x!i{yIeIso^=n?fDX`3bU=eG7sTc%g%ye8$v8P@yKE^XD=NYxTb zbf!Mk=h|otpqjFaA-vs5YOF-*GwWPc7VbaOW&stlANnCN8iftFMMrUdYNJ_Bnn5Vt zxfz@Ah|+4&P;reZxp;MmEI7C|FOv8NKUm8njF7Wb6Gi7DeODLl&G~}G4be&*Hi0Qw z5}77vL0P+7-B%UL@3n1&JPxW^d@vVwp?u#gVcJqY9#@-3X{ok#UfW3<1fb%FT`|)V~ggq z(3AUoUS-;7)^hCjdT0Kf{i}h)mBg4qhtHHBti=~h^n^OTH5U*XMgDLIR@sre`AaB$ zg)IGBET_4??m@cx&c~bA80O7B8CHR7(LX7%HThkeC*@vi{-pL%e)yXp!B2InafbDF zjPXf1mko3h59{lT6EEbxKO1Z5GF71)WwowO6kY|6tjSVSWdQ}NsK2x{>i|MKZK8%Q zfu&_0D;CO-Jg0#YmyfctyJ!mRJp)e#@O0mYdp|8x;G1%OZQ3Q847YWTyy|%^cpA;m zze0(5p{tMu^lDkpe?HynyO?a1$_LJl2L&mpeKu%8YvgRNr=%2z${%WThHG=vrWY@4 zsA`OP#O&)TetZ>s%h!=+CE15lOOls&nvC~$Qz0Ph7tHiP;O$i|eDwpT{cp>+)0-|; zY$|bB+Gbel>5aRN3>c0x)4U=|X+z+{ zn*_p*EQoquRL+=+p;=lm`d71&1NqBz&_ph)MXu(Nv6&XE7(RsS)^MGj5Q?Fwude-(sq zjJ>aOq!7!EN>@(fK7EE#;i_BGvli`5U;r!YA{JRodLBc6-`n8K+Fjgwb%sX;j=qHQ z7&Tr!)!{HXoO<2BQrV9Sw?JRaLXV8HrsNevvnf>Y-6|{T!pYLl7jp$-nEE z#X!4G4L#K0qG_4Z;Cj6=;b|Be$hi4JvMH!-voxqx^@8cXp`B??eFBz2lLD8RRaRGh zn7kUfy!YV~p(R|p7iC1Rdgt$_24i0cd-S8HpG|`@my70g^y`gu%#Tf_L21-k?sRRZHK&at(*ED0P8iw{7?R$9~OF$Ko;Iu5)ur5<->x!m93Eb zFYpIx60s=Wxxw=`$aS-O&dCO_9?b1yKiPCQmSQb>T)963`*U+Ydj5kI(B(B?HNP8r z*bfSBpSu)w(Z3j7HQoRjUG(+d=IaE~tv}y14zHHs|0UcN52fT8V_<@2ep_ee{QgZG zmgp8iv4V{k;~8@I%M3<#B;2R>Ef(Gg_cQM7%}0s*^)SK6!Ym+~P^58*wnwV1BW@eG z4sZLqsUvBbFsr#8u7S1r4teQ;t)Y@jnn_m5jS$CsW1um!p&PqAcc8!zyiXHVta9QC zY~wCwCF0U%xiQPD_INKtTb;A|Zf29(mu9NI;E zc-e>*1%(LSXB`g}kd`#}O;veb<(sk~RWL|f3ljxCnEZDdNSTDV6#Td({6l&y4IjKF z^}lIUq*ZUqgTPumD)RrCN{M^jhY>E~1pn|KOZ5((%F)G|*ZQ|r4zIbrEiV%42hJV8 z3xS)=!X1+=olbdGJ=yZil?oXLct8FM{(6ikLL3E%=q#O6(H$p~gQu6T8N!plf!96| z&Q3=`L~>U0zZh;z(pGR2^S^{#PrPxTRHD1RQOON&f)Siaf`GLj#UOk&(|@0?zm;Sx ztsGt8=29-MZs5CSf1l1jNFtNt5rFNZxJPvkNu~2}7*9468TWm>nN9TP&^!;J{-h)_ z7WsHH9|F%I`Pb!>KAS3jQWKfGivTVkMJLO-HUGM_a4UQ_%RgL6WZvrW+Z4ujZn;y@ zz9$=oO!7qVTaQAA^BhX&ZxS*|5dj803M=k&2%QrXda`-Q#IoZL6E(g+tN!6CA!CP* zCpWtCujIea)ENl0liwVfj)Nc<9mV%+e@=d`haoZ*`B7+PNjEbXBkv=B+Pi^~L#EO$D$ZqTiD8f<5$eyb54-(=3 zh)6i8i|jp(@OnRrY5B8t|LFXFQVQ895n*P16cEKTrT*~yLH6Z4e*bZ5otpRDri&+A zfNbK1D5@O=sm`fN=WzWyse!za5n%^+6dHPGX#8DyIK>?9qyX}2XvBWVqbP%%D)7$= z=#$WulZlZR<{m#gU7lwqK4WS1Ne$#_P{b17qe$~UOXCl>5b|6WVh;5vVnR<%d+Lnp z$uEmML38}U4vaW8>shm6CzB(Wei3s#NAWE3)a2)z@i{4jTn;;aQS)O@l{rUM`J@K& l00vQ5JBs~;vo!vr%%-k{2_Fq1Mn4QF81S)AQ99zk{{c4yR+0b! literal 61574 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 ScNgau(U?ep-K_E5zy1%ZQTdPn diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 3499ded..b82aa23 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/java/com/connorcode/sigmautils/commands/About.java b/src/main/java/com/connorcode/sigmautils/commands/About.java index ddb23e5..ef4032a 100644 --- a/src/main/java/com/connorcode/sigmautils/commands/About.java +++ b/src/main/java/com/connorcode/sigmautils/commands/About.java @@ -15,27 +15,17 @@ public class About implements Command { public void register(CommandDispatcher dispatcher) { - dispatcher.register(ClientCommandManager.literal("util") - .then(ClientCommandManager.literal("about") - .executes(context -> { - var gameVersion = client.getGameVersion(); - var fabricVersion = FabricLoader.getInstance() - .getModContainer("fabricloader") - .orElseThrow() - .getMetadata() - .getVersion() - .getFriendlyString(); - var fabricDebug = FabricLoader.getInstance().isDevelopmentEnvironment() ? " (debug)" : ""; - var sigmaUtilsVersion = SigmaUtils.VERSION; - var protocolVersion = SharedConstants.getGameVersion().getProtocolVersion(); + dispatcher.register(ClientCommandManager.literal("util").then(ClientCommandManager.literal("about").executes(context -> { + var gameVersion = client.getGameVersion(); + var fabricVersion = FabricLoader.getInstance().getModContainer("fabricloader").orElseThrow().getMetadata().getVersion().getFriendlyString(); + var fabricDebug = FabricLoader.getInstance().isDevelopmentEnvironment() ? " (debug)" : ""; + var sigmaUtilsVersion = SigmaUtils.VERSION; + var protocolVersion = SharedConstants.getGameVersion().getProtocolVersion(); - var message = - Text.of(String.format("SigmaUtils v%s\nFabric v%s%s\nMinecraft v%s\nProtocol v%s", - sigmaUtilsVersion, fabricVersion, fabricDebug, gameVersion, - protocolVersion)); + var message = Text.of(String.format("SigmaUtils v%s\nFabric v%s%s\nMinecraft v%s\nProtocol v%s", sigmaUtilsVersion, fabricVersion, fabricDebug, gameVersion, protocolVersion)); - Objects.requireNonNull(client.player).sendMessage(message, false); - return 0; - }))); + Objects.requireNonNull(client.player).sendMessage(message, false); + return 0; + }))); } } diff --git a/src/main/java/com/connorcode/sigmautils/commands/Note.java b/src/main/java/com/connorcode/sigmautils/commands/Note.java index 6ab6b31..dbcb62a 100644 --- a/src/main/java/com/connorcode/sigmautils/commands/Note.java +++ b/src/main/java/com/connorcode/sigmautils/commands/Note.java @@ -19,8 +19,6 @@ import static net.minecraft.command.CommandSource.suggestMatching; - - /* New note system: - /util note diff --git a/src/main/java/com/connorcode/sigmautils/misc/util/NetworkUtils.java b/src/main/java/com/connorcode/sigmautils/misc/util/NetworkUtils.java index 42352e9..3c7b755 100644 --- a/src/main/java/com/connorcode/sigmautils/misc/util/NetworkUtils.java +++ b/src/main/java/com/connorcode/sigmautils/misc/util/NetworkUtils.java @@ -6,8 +6,8 @@ import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.MappingResolver; +import net.minecraft.network.NetworkPhase; import net.minecraft.network.NetworkSide; -import net.minecraft.network.NetworkState; import net.minecraft.network.packet.Packet; import org.jetbrains.annotations.Nullable; @@ -26,7 +26,7 @@ public class NetworkUtils { public static Object2IntOpenHashMap>> getPackets(NetworkSide side) { var packets = new Object2IntOpenHashMap>>(); - Arrays.stream(NetworkState.values()) + Arrays.stream(NetworkPhase.values()) .map(state -> state.packetHandlers.get(side)) .filter(Objects::nonNull) .forEach(handler -> packets.putAll(handler.backingHandler.packetIds)); diff --git a/src/main/java/com/connorcode/sigmautils/misc/util/Util.java b/src/main/java/com/connorcode/sigmautils/misc/util/Util.java index 098b649..4b07bf9 100644 --- a/src/main/java/com/connorcode/sigmautils/misc/util/Util.java +++ b/src/main/java/com/connorcode/sigmautils/misc/util/Util.java @@ -22,6 +22,7 @@ import static com.connorcode.sigmautils.SigmaUtils.client; + public class Util { static final HashMap uuidCache = new HashMap<>(); static final HashSet invalidUuids = new HashSet<>(); diff --git a/src/main/java/com/connorcode/sigmautils/modules/_interface/RandomBackground.java b/src/main/java/com/connorcode/sigmautils/modules/_interface/RandomBackground.java index d511051..cb3ba90 100644 --- a/src/main/java/com/connorcode/sigmautils/modules/_interface/RandomBackground.java +++ b/src/main/java/com/connorcode/sigmautils/modules/_interface/RandomBackground.java @@ -23,6 +23,7 @@ import static com.connorcode.sigmautils.SigmaUtils.client; import static net.minecraft.client.gui.screen.Screen.OPTIONS_BACKGROUND_TEXTURE; + @ModuleInfo(description = "Uses random textures for the background tessellation", documentation = "It will change every time you open a new screen.") public class RandomBackground extends Module { diff --git a/src/main/java/com/connorcode/sigmautils/modules/chat/ChatControl.java b/src/main/java/com/connorcode/sigmautils/modules/chat/ChatControl.java index fa504c5..f66d16b 100644 --- a/src/main/java/com/connorcode/sigmautils/modules/chat/ChatControl.java +++ b/src/main/java/com/connorcode/sigmautils/modules/chat/ChatControl.java @@ -23,6 +23,7 @@ import static com.connorcode.sigmautils.SigmaUtils.client; + @ModuleInfo(description = "Allows other players to control your client over game chat.", inDevelopment = true) public class ChatControl extends Module { BoolSetting requireSignature = new BoolSetting(ChatControl.class, "Require Signature").description("Whether to require the message to be signed to execute it.").build(); diff --git a/src/main/java/com/connorcode/sigmautils/modules/hud/Hud.java b/src/main/java/com/connorcode/sigmautils/modules/hud/Hud.java index 1986a18..543b274 100644 --- a/src/main/java/com/connorcode/sigmautils/modules/hud/Hud.java +++ b/src/main/java/com/connorcode/sigmautils/modules/hud/Hud.java @@ -17,6 +17,7 @@ import static com.connorcode.sigmautils.SigmaUtils.client; import static com.connorcode.sigmautils.modules.meta.Padding.getPadding; + @ModuleInfo(description = "The basic text hud that can be placed in the corners of the window") public class Hud extends Module { public static List hudModules = new ArrayList<>(); diff --git a/src/main/java/com/connorcode/sigmautils/modules/misc/AutoSign.java b/src/main/java/com/connorcode/sigmautils/modules/misc/AutoSign.java index a2874a2..3b19835 100644 --- a/src/main/java/com/connorcode/sigmautils/modules/misc/AutoSign.java +++ b/src/main/java/com/connorcode/sigmautils/modules/misc/AutoSign.java @@ -27,6 +27,7 @@ import static com.connorcode.sigmautils.SigmaUtils.client; + @ModuleInfo(description = "Automatically writes text on signs you place. If you are looking at a sign, it will edit that sign.") public class AutoSign extends Module { EnumSetting mode = new EnumSetting<>(AutoSign.class, "Mode", Mode.class) diff --git a/src/main/java/com/connorcode/sigmautils/modules/rendering/LightLevel.java b/src/main/java/com/connorcode/sigmautils/modules/rendering/LightLevel.java index d87a744..f196976 100644 --- a/src/main/java/com/connorcode/sigmautils/modules/rendering/LightLevel.java +++ b/src/main/java/com/connorcode/sigmautils/modules/rendering/LightLevel.java @@ -23,6 +23,7 @@ import static com.connorcode.sigmautils.SigmaUtils.client; import static com.connorcode.sigmautils.misc.util.WorldRenderUtils.getMatrices; + @ModuleInfo(description = "Shows the light level the top of blocks") public class LightLevel extends Module { EnumSetting source = new EnumSetting<>(LightLevel.class, "Light Source", LightSource.class).value(LightSource.All).build(); diff --git a/src/main/java/com/connorcode/sigmautils/modules/server/AutoVoidTrade.java b/src/main/java/com/connorcode/sigmautils/modules/server/AutoVoidTrade.java index 7fdb377..fcd8ac9 100644 --- a/src/main/java/com/connorcode/sigmautils/modules/server/AutoVoidTrade.java +++ b/src/main/java/com/connorcode/sigmautils/modules/server/AutoVoidTrade.java @@ -150,10 +150,7 @@ void onPacketReceive_SetTradeOffers(PacketReceiveEvent packet) { } // Verify player has the required items - var requiredItems = new ItemStack[]{ - tradeOffer.getAdjustedFirstBuyItem(), - tradeOffer.getSecondBuyItem() - }; + var requiredItems = new ItemStack[]{tradeOffer.getDisplayedFirstBuyItem(), tradeOffer.getDisplayedSecondBuyItem()}; for (var item : requiredItems) { if (item.isEmpty()) continue; var itemCount = client.player.getInventory().count(item.getItem()); From 915a818caa9d77c49c5601f8f416d16544dc8807 Mon Sep 17 00:00:00 2001 From: Connor Slade Date: Thu, 27 Jun 2024 15:43:55 -0400 Subject: [PATCH 02/17] Complete easy upgrades --- .../connorcode/sigmautils/commands/Map.java | 44 ++++++++----------- .../sigmautils/config/ConfigGui2.java | 2 +- .../sigmautils/mixin/MapRendererAccessor.java | 12 ----- .../sigmautils/mixin/MapTextureAccessor.java | 12 ----- .../sigmautils/modules/hud/EffectHud.java | 21 ++++----- .../modules/rendering/MapBorder.java | 40 ++++++++--------- .../modules/server/AutoTradeCycle.java | 6 +-- .../modules/server/BadlionTimers.java | 10 ++--- .../modules/server/BridgeAnalysis.java | 2 +- .../modules/server/VictoryMute.java | 2 +- src/main/resources/sigma_utils.accesswidener | 26 ++++++----- 11 files changed, 69 insertions(+), 108 deletions(-) delete mode 100644 src/main/java/com/connorcode/sigmautils/mixin/MapRendererAccessor.java delete mode 100644 src/main/java/com/connorcode/sigmautils/mixin/MapTextureAccessor.java diff --git a/src/main/java/com/connorcode/sigmautils/commands/Map.java b/src/main/java/com/connorcode/sigmautils/commands/Map.java index fa5878b..ca78c24 100644 --- a/src/main/java/com/connorcode/sigmautils/commands/Map.java +++ b/src/main/java/com/connorcode/sigmautils/commands/Map.java @@ -1,11 +1,11 @@ package com.connorcode.sigmautils.commands; -import com.connorcode.sigmautils.mixin.MapRendererAccessor; -import com.connorcode.sigmautils.mixin.MapTextureAccessor; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.context.CommandContext; import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.component.type.MapIdComponent; import net.minecraft.entity.decoration.ItemFrameEntity; import net.minecraft.item.FilledMapItem; import net.minecraft.item.ItemStack; @@ -28,19 +28,15 @@ public class Map implements Command { private static int save(CommandContext context) { - Optional> rawMap = getMap(context); + Optional> rawMap = getMap(context); if (rawMap.isEmpty()) return 0; - int mapId = rawMap.get() - .getLeft(); - MapState mapState = rawMap.get() - .getRight(); + var mapId = rawMap.get().getLeft(); + MapState mapState = rawMap.get().getRight(); assert client.player != null; File mapFile = getNewFile(mapId); try { - Objects.requireNonNull( - ((MapTextureAccessor) (((MapRendererAccessor) client.gameRenderer.getMapRenderer()).invokeGetMapTexture( - mapId, mapState))).getTexture().getImage()).writeTo(mapFile); + client.gameRenderer.getMapRenderer().getMapTexture(mapId.id(), mapState).texture.getImage().writeTo(mapFile); } catch (IOException e) { e.printStackTrace(); } @@ -53,12 +49,10 @@ private static int save(CommandContext context) { } private static int info(CommandContext context) { - Optional> rawMap = getMap(context); + Optional> rawMap = getMap(context); if (rawMap.isEmpty()) return 0; - int mapId = rawMap.get() - .getLeft(); - MapState mapState = rawMap.get() - .getRight(); + var mapId = rawMap.get().getLeft(); + MapState mapState = rawMap.get().getRight(); MutableText out = Text.empty() // Id @@ -86,23 +80,22 @@ private static int info(CommandContext context) { return 0; } - static Optional> getMap(CommandContext context) { + static Optional> getMap(CommandContext context) { assert client.player != null; ItemStack itemStack = client.player.getInventory().getMainHandStack(); - if (!itemStack.isOf(Items.FILLED_MAP) && - Objects.requireNonNull(client.crosshairTarget).getType() == HitResult.Type.ENTITY && - ((EntityHitResult) client.crosshairTarget).getEntity() instanceof ItemFrameEntity itemFrame) - itemStack = itemFrame.getHeldItemStack(); + if (!itemStack.isOf(Items.FILLED_MAP) && Objects.requireNonNull(client.crosshairTarget).getType() == HitResult.Type.ENTITY && + ((EntityHitResult) client.crosshairTarget).getEntity() instanceof ItemFrameEntity itemFrame) itemStack = itemFrame.getHeldItemStack(); - if (!itemStack.isOf(Items.FILLED_MAP)) { +// if (!itemStack.isOf(Items.FILLED_MAP)) { + if (!(itemStack.getItem() instanceof FilledMapItem filledMapItem)) { context.getSource().sendError(Text.of("You must be holding or looking at a map!")); return Optional.empty(); } - Integer mapId = FilledMapItem.getMapId(itemStack); - MapState mapState = FilledMapItem.getMapState(mapId, client.world); + var mapId = itemStack.get(DataComponentTypes.MAP_ID); + var mapState = FilledMapItem.getMapState(mapId, client.world); if (mapId == null) { context.getSource().sendError(Text.of("Map ID is null?")); return Optional.empty(); @@ -111,11 +104,10 @@ static Optional> getMap(CommandContext(mapId, mapState)); } - static File getNewFile(int id) { + static File getNewFile(MapIdComponent id) { int i = 1; while (true) { - File file = new File(new File(client.runDirectory, "screenshots"), - String.format("map_%d%s.png", id, (i++ == 1 ? "" : "_" + i))); + File file = new File(new File(client.runDirectory, "screenshots"), String.format("map_%d%s.png", id.id(), (i++ == 1 ? "" : "_" + i))); if (!file.exists()) return file; } } diff --git a/src/main/java/com/connorcode/sigmautils/config/ConfigGui2.java b/src/main/java/com/connorcode/sigmautils/config/ConfigGui2.java index 0750dea..7321d3e 100644 --- a/src/main/java/com/connorcode/sigmautils/config/ConfigGui2.java +++ b/src/main/java/com/connorcode/sigmautils/config/ConfigGui2.java @@ -43,7 +43,7 @@ protected void init() { @Override public void render(DrawContext context, int mouseX, int mouseY, float delta) { - renderBackgroundTexture(context); + renderDarkening(context); super.render(context, mouseX, mouseY, delta); context.fill(22, 0, width, height, 0x00000017); } diff --git a/src/main/java/com/connorcode/sigmautils/mixin/MapRendererAccessor.java b/src/main/java/com/connorcode/sigmautils/mixin/MapRendererAccessor.java deleted file mode 100644 index 76f9641..0000000 --- a/src/main/java/com/connorcode/sigmautils/mixin/MapRendererAccessor.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.connorcode.sigmautils.mixin; - -import net.minecraft.client.render.MapRenderer; -import net.minecraft.item.map.MapState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Invoker; - -@Mixin(MapRenderer.class) -public interface MapRendererAccessor { - @Invoker - MapRenderer.MapTexture invokeGetMapTexture(int id, MapState state); -} diff --git a/src/main/java/com/connorcode/sigmautils/mixin/MapTextureAccessor.java b/src/main/java/com/connorcode/sigmautils/mixin/MapTextureAccessor.java deleted file mode 100644 index 69810a1..0000000 --- a/src/main/java/com/connorcode/sigmautils/mixin/MapTextureAccessor.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.connorcode.sigmautils.mixin; - -import net.minecraft.client.render.MapRenderer; -import net.minecraft.client.texture.NativeImageBackedTexture; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(MapRenderer.MapTexture.class) -public interface MapTextureAccessor { - @Accessor - NativeImageBackedTexture getTexture(); -} diff --git a/src/main/java/com/connorcode/sigmautils/modules/hud/EffectHud.java b/src/main/java/com/connorcode/sigmautils/modules/hud/EffectHud.java index f475ebb..31a7171 100644 --- a/src/main/java/com/connorcode/sigmautils/modules/hud/EffectHud.java +++ b/src/main/java/com/connorcode/sigmautils/modules/hud/EffectHud.java @@ -5,10 +5,12 @@ import com.connorcode.sigmautils.module.ModuleInfo; import net.minecraft.entity.effect.StatusEffect; import net.minecraft.entity.effect.StatusEffectInstance; -import net.minecraft.registry.Registries; -import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.entry.RegistryEntry; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; import static com.connorcode.sigmautils.SigmaUtils.client; @@ -23,17 +25,10 @@ public EffectHud() { public List lines() { List out = new ArrayList<>(); String color = this.getTextColor(); - Map effectMap = Objects.requireNonNull(client.player) - .getActiveStatusEffects(); + Map, StatusEffectInstance> effectMap = Objects.requireNonNull(client.player).getActiveStatusEffects(); - for (Map.Entry i : effectMap.entrySet()) { - Optional> effectKey = Registries.STATUS_EFFECT.getKey(i.getKey()); - if (effectKey.isEmpty()) continue; - - out.add(String.format("§r%sEffect: §f%s %d %ds", color, effectKey.get() - .getValue(), i.getValue() - .getAmplifier() + 1, i.getValue() - .getDuration() / 20)); + for (var i : effectMap.entrySet()) { + out.add(String.format("§r%sEffect: §f%s %d %ds", color, i.getKey().value(), i.getValue().getAmplifier() + 1, i.getValue().getDuration() / 20)); } return out; diff --git a/src/main/java/com/connorcode/sigmautils/modules/rendering/MapBorder.java b/src/main/java/com/connorcode/sigmautils/modules/rendering/MapBorder.java index 9d287f8..fa87ce4 100644 --- a/src/main/java/com/connorcode/sigmautils/modules/rendering/MapBorder.java +++ b/src/main/java/com/connorcode/sigmautils/modules/rendering/MapBorder.java @@ -37,30 +37,30 @@ void onRender(WorldRender.PostWorldRenderEvent event) { var d = c | 0x80 << 24; for (var y = minY; y <= maxY; y += step.value()) { - layer.vertex(matrices, boxX, y, boxZ).color(c).next(); - layer.vertex(matrices, boxX - 128, y, boxZ).color(d).next(); - layer.vertex(matrices, boxX - 128, y, boxZ).color(c).next(); - layer.vertex(matrices, boxX - 128, y, boxZ - 128).color(d).next(); - layer.vertex(matrices, boxX - 128, y, boxZ - 128).color(c).next(); - layer.vertex(matrices, boxX, y, boxZ - 128).color(d).next(); - layer.vertex(matrices, boxX, y, boxZ - 128).color(c).next(); - layer.vertex(matrices, boxX, y, boxZ).color(d).next(); + layer.vertex(matrices, boxX, y, boxZ).color(c); + layer.vertex(matrices, boxX - 128, y, boxZ).color(d); + layer.vertex(matrices, boxX - 128, y, boxZ).color(c); + layer.vertex(matrices, boxX - 128, y, boxZ - 128).color(d); + layer.vertex(matrices, boxX - 128, y, boxZ - 128).color(c); + layer.vertex(matrices, boxX, y, boxZ - 128).color(d); + layer.vertex(matrices, boxX, y, boxZ - 128).color(c); + layer.vertex(matrices, boxX, y, boxZ).color(d); } - layer.vertex(matrices, boxX, maxY, boxZ).color(c).next(); - layer.vertex(matrices, boxX - 128, minY, boxZ).color(c).next(); - layer.vertex(matrices, boxX - 128, minY, boxZ).color(c).next(); - layer.vertex(matrices, boxX - 128, maxY, boxZ).color(d).next(); + layer.vertex(matrices, boxX, maxY, boxZ).color(c); + layer.vertex(matrices, boxX - 128, minY, boxZ).color(c); + layer.vertex(matrices, boxX - 128, minY, boxZ).color(c); + layer.vertex(matrices, boxX - 128, maxY, boxZ).color(d); - layer.vertex(matrices, boxX - 128, maxY, boxZ).color(c).next(); - layer.vertex(matrices, boxX, minY, boxZ - 128).color(c).next(); - layer.vertex(matrices, boxX, minY, boxZ - 128).color(c).next(); - layer.vertex(matrices, boxX, maxY, boxZ - 128).color(d).next(); + layer.vertex(matrices, boxX - 128, maxY, boxZ).color(c); + layer.vertex(matrices, boxX, minY, boxZ - 128).color(c); + layer.vertex(matrices, boxX, minY, boxZ - 128).color(c); + layer.vertex(matrices, boxX, maxY, boxZ - 128).color(d); - layer.vertex(matrices, boxX, maxY, boxZ - 128).color(c).next(); - layer.vertex(matrices, boxX - 128, minY, boxZ - 128).color(c).next(); - layer.vertex(matrices, boxX - 128, minY, boxZ - 128).color(c).next(); - layer.vertex(matrices, boxX - 128, maxY, boxZ - 128).color(d).next(); + layer.vertex(matrices, boxX, maxY, boxZ - 128).color(c); + layer.vertex(matrices, boxX - 128, minY, boxZ - 128).color(c); + layer.vertex(matrices, boxX - 128, minY, boxZ - 128).color(c); + layer.vertex(matrices, boxX - 128, maxY, boxZ - 128).color(d); immediate.draw(); } diff --git a/src/main/java/com/connorcode/sigmautils/modules/server/AutoTradeCycle.java b/src/main/java/com/connorcode/sigmautils/modules/server/AutoTradeCycle.java index 1971fd4..b84b943 100644 --- a/src/main/java/com/connorcode/sigmautils/modules/server/AutoTradeCycle.java +++ b/src/main/java/com/connorcode/sigmautils/modules/server/AutoTradeCycle.java @@ -16,12 +16,9 @@ import com.connorcode.sigmautils.module.ModuleInfo; import net.minecraft.client.sound.PositionedSoundInstance; import net.minecraft.enchantment.Enchantment; -import net.minecraft.enchantment.SoulSpeedEnchantment; -import net.minecraft.enchantment.SwiftSneakEnchantment; import net.minecraft.entity.passive.VillagerEntity; import net.minecraft.item.EnchantedBookItem; import net.minecraft.item.Item; -import net.minecraft.item.Items; import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket; import net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket; import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket; @@ -148,8 +145,7 @@ void onPacketReceive_SetTradeOffers(PacketReceiveEvent packet) { return; } case EnchantedBook -> { - if (i.getSellItem().getItem() != Items.ENCHANTED_BOOK) continue; - var data = EnchantedBookItem.getEnchantmentNbt(i.getSellItem()); + if (!(i.getSellItem().getItem() instanceof EnchantedBookItem data)) continue; var settingEnchantment = Registries.ENCHANTMENT.getId(this.enchantment.value()); for (int j = 0; j < data.size(); j++) { var enchantment = new Identifier(data.getCompound(j).getString("id")); diff --git a/src/main/java/com/connorcode/sigmautils/modules/server/BadlionTimers.java b/src/main/java/com/connorcode/sigmautils/modules/server/BadlionTimers.java index 9c8366e..26efd89 100644 --- a/src/main/java/com/connorcode/sigmautils/modules/server/BadlionTimers.java +++ b/src/main/java/com/connorcode/sigmautils/modules/server/BadlionTimers.java @@ -21,12 +21,10 @@ @ModuleInfo(description = "Shows badlion timers in the HUD", documentation = "The Badlion client has a feature where a server can define countdown timers that will be displayed on the HUD ([image](https://user-images.githubusercontent.com/50306817/215306367-3b2b640c-898e-401b-8ee2-c97e7879e4c8.png)). This module intercepts the timer packets and renders the timers in the SigmaUtils HUD.") public class BadlionTimers extends HudModule { - private static final Identifier BADLION_TIMER = new Identifier("badlion", "timers"); - private static final EnumSetting timeFormat = - new EnumSetting<>(BadlionTimers.class, "Time Format", Util.TimeFormat.class).value(Util.TimeFormat.HMS) - .description( - "The format of the time played. (HMS = Hours:Minutes:Seconds) (BestFit = 5 seconds, 3 hours") - .build(); + private static final Identifier BADLION_TIMER = Identifier.of("badlion", "timers"); + private static final EnumSetting timeFormat = new EnumSetting<>(BadlionTimers.class, "Time Format", Util.TimeFormat.class).value(Util.TimeFormat.HMS) + .description("The format of the time played. (HMS = Hours:Minutes:Seconds) (BestFit = 5 seconds, 3 hours") + .build(); private static final List timers = new ArrayList<>(); private static long lastTick = 0; diff --git a/src/main/java/com/connorcode/sigmautils/modules/server/BridgeAnalysis.java b/src/main/java/com/connorcode/sigmautils/modules/server/BridgeAnalysis.java index 8cd27ab..b88b292 100644 --- a/src/main/java/com/connorcode/sigmautils/modules/server/BridgeAnalysis.java +++ b/src/main/java/com/connorcode/sigmautils/modules/server/BridgeAnalysis.java @@ -85,7 +85,7 @@ public void init() { void onPacketReceive_TitleS2CPacket(PacketReceiveEvent packet) { if (!this.enabled || !(packet.get() instanceof TitleS2CPacket title)) return; var regex = Pattern.compile(endRegex.value()); - if (!regex.matcher(title.getTitle().getString()).matches()) return; + if (!regex.matcher(title.text().getString()).matches()) return; info("Downloading Wool"); download(); } diff --git a/src/main/java/com/connorcode/sigmautils/modules/server/VictoryMute.java b/src/main/java/com/connorcode/sigmautils/modules/server/VictoryMute.java index ca5b970..9a9e702 100644 --- a/src/main/java/com/connorcode/sigmautils/modules/server/VictoryMute.java +++ b/src/main/java/com/connorcode/sigmautils/modules/server/VictoryMute.java @@ -60,7 +60,7 @@ void onPacketReceive(PacketReceiveEvent packet) { // just ignore the following todo // TODO: Let settings convert to different types (callback on builder) var regex = Pattern.compile(victoryRegex.value()); - muted = regex.matcher(title.getTitle().getString()).matches(); + muted = regex.matcher(title.text().getString()).matches(); } if (packet.get() instanceof GameJoinS2CPacket) muted = false; diff --git a/src/main/resources/sigma_utils.accesswidener b/src/main/resources/sigma_utils.accesswidener index 7da5f5b..59dfed8 100644 --- a/src/main/resources/sigma_utils.accesswidener +++ b/src/main/resources/sigma_utils.accesswidener @@ -1,26 +1,30 @@ accessWidener v1 named # for future reference # https://fabricmc.net/wiki/tutorial:accesswideners -accessible class net/minecraft/client/render/MapRenderer$MapTexture + +## Misc ## accessible method net/minecraft/client/font/TextRenderer tweakTransparency (I)I -accessible field net/minecraft/network/NetworkState packetHandlers Ljava/util/Map; -accessible class net/minecraft/network/NetworkState$InternalPacketHandler -accessible field net/minecraft/network/NetworkState$PacketHandler backingHandler Lnet/minecraft/network/NetworkState$InternalPacketHandler; -accessible field net/minecraft/network/NetworkState$InternalPacketHandler packetIds Lit/unimi/dsi/fastutil/objects/Object2IntMap; accessible method net/minecraft/entity/Entity getFlag (I)Z accessible method net/minecraft/client/gui/screen/option/OptionsScreen createButton (Lnet/minecraft/text/Text;Ljava/util/function/Supplier;)Lnet/minecraft/client/gui/widget/ButtonWidget; + +## Gui Stuff ## +accessible field net/minecraft/client/gui/screen/Screen drawables Ljava/util/List; +extendable method net/minecraft/client/gui/widget/ClickableWidget render (Lnet/minecraft/client/gui/DrawContext;IIF)V + +## Network Stuff ## + +## Map Command ## +accessible class net/minecraft/client/render/MapRenderer$MapTexture +accessible method net/minecraft/client/render/MapRenderer getMapTexture (Lnet/minecraft/component/type/MapIdComponent;Lnet/minecraft/item/map/MapState;)Lnet/minecraft/client/render/MapRenderer$MapTexture; +accessible field net/minecraft/client/render/MapRenderer$MapTexture texture Lnet/minecraft/client/texture/NativeImageBackedTexture; + +## BridgeAnalisys ## accessible field net/minecraft/client/world/ClientChunkManager chunks Lnet/minecraft/client/world/ClientChunkManager$ClientChunkMap; accessible field net/minecraft/client/world/ClientChunkManager$ClientChunkMap chunks Ljava/util/concurrent/atomic/AtomicReferenceArray; -accessible method net/minecraft/client/network/ClientPlayerInteractionManager sendSequencedPacket (Lnet/minecraft/client/world/ClientWorld;Lnet/minecraft/client/network/SequencedPacketCreator;)V accessible field net/minecraft/world/chunk/PalettedContainer data Lnet/minecraft/world/chunk/PalettedContainer$Data; accessible field net/minecraft/world/chunk/PalettedContainer paletteProvider Lnet/minecraft/world/chunk/PalettedContainer$PaletteProvider; accessible field net/minecraft/world/chunk/PalettedContainer$Data storage Lnet/minecraft/util/collection/PaletteStorage; accessible field net/minecraft/world/chunk/PalettedContainer$PaletteProvider edgeBits I -accessible field net/minecraft/client/gui/screen/Screen drawables Ljava/util/List; -extendable method net/minecraft/client/gui/widget/ClickableWidget render (Lnet/minecraft/client/gui/DrawContext;IIF)V -accessible method net/minecraft/client/gui/widget/CheckboxWidget (IILnet/minecraft/text/Text;Lnet/minecraft/client/font/TextRenderer;ZLnet/minecraft/client/gui/widget/CheckboxWidget$Callback;)V - -## BridgeAnalisys ## accessible field net/minecraft/client/world/ClientChunkManager$ClientChunkMap diameter I accessible field net/minecraft/client/world/ClientChunkManager$ClientChunkMap radius I accessible field net/minecraft/client/world/ClientChunkManager$ClientChunkMap centerChunkX I From d0541debfe08c2ca8555fff0d5da8f8261654926 Mon Sep 17 00:00:00 2001 From: Connor Slade Date: Thu, 27 Jun 2024 16:39:50 -0400 Subject: [PATCH 03/17] Fail to fix custom payload handling --- .../misc/CancelledUnknownPacket.java | 23 ------------- .../ClientCommonNetworkHandlerMixin.java | 29 ++++++++++++++++ .../mixin/ClientPlayNetworkHandlerMixin.java | 25 -------------- .../mixin/CustomPayloadS2CPacketMixin.java | 33 ++----------------- src/main/resources/sigma-utils.mixins.json | 4 +-- 5 files changed, 33 insertions(+), 81 deletions(-) delete mode 100644 src/main/java/com/connorcode/sigmautils/misc/CancelledUnknownPacket.java create mode 100644 src/main/java/com/connorcode/sigmautils/mixin/ClientCommonNetworkHandlerMixin.java delete mode 100644 src/main/java/com/connorcode/sigmautils/mixin/ClientPlayNetworkHandlerMixin.java diff --git a/src/main/java/com/connorcode/sigmautils/misc/CancelledUnknownPacket.java b/src/main/java/com/connorcode/sigmautils/misc/CancelledUnknownPacket.java deleted file mode 100644 index 120a765..0000000 --- a/src/main/java/com/connorcode/sigmautils/misc/CancelledUnknownPacket.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.connorcode.sigmautils.misc; - -import net.minecraft.network.PacketByteBuf; -import net.minecraft.network.packet.CustomPayload; -import net.minecraft.util.Identifier; - -public class CancelledUnknownPacket implements CustomPayload { - Identifier id; - - public CancelledUnknownPacket(Identifier id) { - this.id = id; - } - - @Override - public void write(PacketByteBuf buf) { - - } - - @Override - public Identifier id() { - return this.id; - } -} diff --git a/src/main/java/com/connorcode/sigmautils/mixin/ClientCommonNetworkHandlerMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/ClientCommonNetworkHandlerMixin.java new file mode 100644 index 0000000..6cc2597 --- /dev/null +++ b/src/main/java/com/connorcode/sigmautils/mixin/ClientCommonNetworkHandlerMixin.java @@ -0,0 +1,29 @@ +package com.connorcode.sigmautils.mixin; + +import net.minecraft.client.network.ClientCommonNetworkHandler; +import net.minecraft.network.packet.s2c.common.CustomPayloadS2CPacket; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; + +@Mixin(ClientCommonNetworkHandler.class) +public class ClientCommonNetworkHandlerMixin { + @Inject(method = "onCustomPayload", at = @At("HEAD")) + void onCustomPayload(CustomPayloadS2CPacket packet) { +// var buf = packet.getPayload(); +// var event = new UnknownPacketEvent(buf, packet.payload().getId().id()); + System.out.println("CUSTOM PAYLOAD:" + packet.payload().getClass().getSimpleName()); + } +} + + +// @Inject(method = "readPayload", at = @At("HEAD"), cancellable = true) +// private static void onReadPayload(Identifier id, PacketByteBuf buf, CallbackInfoReturnable cir) { +// if (ID_TO_READER.containsKey(id)) return; +// +// var event = new UnknownPacketEvent(buf, id); +// SigmaUtils.eventBus.post(event); +// +// if (event.isCancelled()) cir.setReturnValue(new CancelledUnknownPacket(id)); +// else cir.setReturnValue(readUnknownPayload(id, buf)); +// } \ No newline at end of file diff --git a/src/main/java/com/connorcode/sigmautils/mixin/ClientPlayNetworkHandlerMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/ClientPlayNetworkHandlerMixin.java deleted file mode 100644 index 31ae1dc..0000000 --- a/src/main/java/com/connorcode/sigmautils/mixin/ClientPlayNetworkHandlerMixin.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.connorcode.sigmautils.mixin; - -import com.connorcode.sigmautils.SigmaUtils; -import com.connorcode.sigmautils.event.misc.GameLifecycle; -import com.connorcode.sigmautils.misc.CancelledUnknownPacket; -import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.network.packet.CustomPayload; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(ClientPlayNetworkHandler.class) -public class ClientPlayNetworkHandlerMixin { - @Inject(method = "onCustomPayload", at = @At("HEAD"), cancellable = true) - void onCustomPayload(CustomPayload payload, CallbackInfo ci) { - if (payload instanceof CancelledUnknownPacket) ci.cancel(); - } - - @Inject(method = "clearWorld", at = @At("HEAD")) - void onClearWorld(CallbackInfo ci) { - var event = new GameLifecycle.WorldCloseEvent(); - SigmaUtils.eventBus.post(event); - } -} diff --git a/src/main/java/com/connorcode/sigmautils/mixin/CustomPayloadS2CPacketMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/CustomPayloadS2CPacketMixin.java index 82f1ab0..a4f2620 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/CustomPayloadS2CPacketMixin.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/CustomPayloadS2CPacketMixin.java @@ -1,41 +1,14 @@ package com.connorcode.sigmautils.mixin; -import com.connorcode.sigmautils.SigmaUtils; -import com.connorcode.sigmautils.event.network.UnknownPacketEvent; -import com.connorcode.sigmautils.misc.CancelledUnknownPacket; -import net.minecraft.network.PacketByteBuf; -import net.minecraft.network.packet.CustomPayload; -import net.minecraft.network.packet.UnknownCustomPayload; import net.minecraft.network.packet.s2c.common.CustomPayloadS2CPacket; -import net.minecraft.util.Identifier; -import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import java.util.Map; @Mixin(CustomPayloadS2CPacket.class) -public abstract class CustomPayloadS2CPacketMixin { - @Shadow - @Final - private static Map> ID_TO_READER; - - @Shadow - private static UnknownCustomPayload readUnknownPayload(Identifier id, PacketByteBuf buf) { - return null; - } - - @Inject(method = "readPayload", at = @At("HEAD"), cancellable = true) - private static void onReadPayload(Identifier id, PacketByteBuf buf, CallbackInfoReturnable cir) { - if (ID_TO_READER.containsKey(id)) return; - - var event = new UnknownPacketEvent(buf, id); - SigmaUtils.eventBus.post(event); +public class CustomPayloadS2CPacketMixin { + @Inject(method = "apply", at = @At("HEAD")) + void onApply() { - if (event.isCancelled()) cir.setReturnValue(new CancelledUnknownPacket(id)); - else cir.setReturnValue(readUnknownPayload(id, buf)); } } diff --git a/src/main/resources/sigma-utils.mixins.json b/src/main/resources/sigma-utils.mixins.json index 2d38d46..4fc2b89 100644 --- a/src/main/resources/sigma-utils.mixins.json +++ b/src/main/resources/sigma-utils.mixins.json @@ -14,10 +14,10 @@ "CameraMixin", "ChatHudMixin", "ChatScreenMixin", + "ClientCommonNetworkHandlerMixin", "ClientConnectionMixin", "ClientPlayerEntityMixin", "ClientPlayerInteractionManagerMixin", - "ClientPlayNetworkHandlerMixin", "ClientWorldAccessor", "ClientWorldMixin", "ClientWorldPropertiesMixin", @@ -38,8 +38,6 @@ "LightmapTextureManagerMixin", "LivingEntityRendererMixin", "LogoDrawerMixin", - "MapRendererAccessor", - "MapTextureAccessor", "MinecraftClientAccessor", "MinecraftClientMixin", "MouseMixin", From aa04fd8061ba5ca4233a0d32b86ab28c973771db Mon Sep 17 00:00:00 2001 From: Connor Slade Date: Thu, 27 Jun 2024 23:18:11 -0400 Subject: [PATCH 04/17] it compiles... --- .../connorcode/sigmautils/commands/Map.java | 2 +- .../config/settings/DynamicListSetting.java | 10 +- .../settings/DynamicSelectorSetting.java | 10 +- .../sigmautils/misc/Components.java | 49 +---- .../sigmautils/misc/util/NetworkUtils.java | 12 +- .../sigmautils/mixin/CameraMixin.java | 33 ++- .../sigmautils/mixin/ChatHudMixin.java | 30 +-- .../ClientCommonNetworkHandlerMixin.java | 3 +- .../mixin/ClientPlayerEntityMixin.java | 4 +- .../mixin/CustomPayloadS2CPacketMixin.java | 10 +- .../sigmautils/mixin/EntityRendererMixin.java | 39 ++-- .../mixin/EntryListWidgetMixin.java | 20 -- .../sigmautils/mixin/InGameHudAccessor.java | 14 -- .../sigmautils/mixin/InGameHudMixin.java | 192 +++++++++--------- .../mixin/InventoryScreenMixin.java | 90 ++++---- .../mixin/LivingEntityRendererMixin.java | 14 -- .../mixin/MinecraftClientAccessor.java | 20 -- .../mixin/MinecraftClientMixin.java | 3 +- .../sigmautils/mixin/OptionsScreenMixin.java | 30 +-- .../mixin/RenderTickCounterAccessor.java | 13 -- .../sigmautils/mixin/ScreenAccessor.java | 3 - .../sigmautils/mixin/ScreenMixin.java | 26 --- .../sigmautils/mixin/WorldRendererMixin.java | 144 ++++++------- .../modmenu/DescriptionListWidgetMixin.java | 22 -- .../modules/_interface/RandomBackground.java | 86 -------- .../sigmautils/modules/hud/FpsHud.java | 6 +- .../sigmautils/modules/hud/Hud.java | 6 +- .../sigmautils/modules/misc/TickSpeed.java | 5 +- .../modules/server/AutoTradeCycle.java | 36 ++-- src/main/resources/fabric.mod.json | 2 +- src/main/resources/modules/modules.json | 1 - src/main/resources/sigma-utils.mixins.json | 8 +- src/main/resources/sigma_utils.accesswidener | 2 + 33 files changed, 293 insertions(+), 652 deletions(-) delete mode 100644 src/main/java/com/connorcode/sigmautils/mixin/EntryListWidgetMixin.java delete mode 100644 src/main/java/com/connorcode/sigmautils/mixin/InGameHudAccessor.java delete mode 100644 src/main/java/com/connorcode/sigmautils/mixin/MinecraftClientAccessor.java delete mode 100644 src/main/java/com/connorcode/sigmautils/mixin/RenderTickCounterAccessor.java delete mode 100644 src/main/java/com/connorcode/sigmautils/mixin/ScreenMixin.java delete mode 100644 src/main/java/com/connorcode/sigmautils/mixin/modmenu/DescriptionListWidgetMixin.java delete mode 100644 src/main/java/com/connorcode/sigmautils/modules/_interface/RandomBackground.java diff --git a/src/main/java/com/connorcode/sigmautils/commands/Map.java b/src/main/java/com/connorcode/sigmautils/commands/Map.java index ca78c24..40dbb34 100644 --- a/src/main/java/com/connorcode/sigmautils/commands/Map.java +++ b/src/main/java/com/connorcode/sigmautils/commands/Map.java @@ -36,7 +36,7 @@ private static int save(CommandContext context) { File mapFile = getNewFile(mapId); try { - client.gameRenderer.getMapRenderer().getMapTexture(mapId.id(), mapState).texture.getImage().writeTo(mapFile); + client.gameRenderer.getMapRenderer().getMapTexture(mapId, mapState).texture.getImage().writeTo(mapFile); } catch (IOException e) { e.printStackTrace(); } diff --git a/src/main/java/com/connorcode/sigmautils/config/settings/DynamicListSetting.java b/src/main/java/com/connorcode/sigmautils/config/settings/DynamicListSetting.java index a6ef985..2769a80 100644 --- a/src/main/java/com/connorcode/sigmautils/config/settings/DynamicListSetting.java +++ b/src/main/java/com/connorcode/sigmautils/config/settings/DynamicListSetting.java @@ -146,10 +146,8 @@ protected ResourceAddScreen(Screen _super, ResourceManager renderer) { @Override protected void init() { - this.searchField = - new TextFieldWidget(SigmaUtils.client.textRenderer, 0, 10, entryWidth / 2, 20, this.searchField, - Text.empty()); - focusOn(this.searchField); + this.searchField = new TextFieldWidget(SigmaUtils.client.textRenderer, 0, 10, entryWidth / 2, 20, this.searchField, Text.empty()); + setFocused(this.searchField); searchField.setX(width / 2 - searchField.getWidth() / 2); var y = padding * 6 + 30 - (int) this.scroll; var x = 20 + padding + startX(); @@ -157,9 +155,7 @@ protected void init() { var search = searchField.getText(); var res = renderer.getAllResources(); count = res.size(); - for (var i : res - .stream() - .filter(r -> search.isEmpty() || search(r, search)) + for (var i : res.stream().filter(r -> search.isEmpty() || search(r, search)) .toList()) { if (y < -entryHeight - padding) { y += entryHeight + padding; diff --git a/src/main/java/com/connorcode/sigmautils/config/settings/DynamicSelectorSetting.java b/src/main/java/com/connorcode/sigmautils/config/settings/DynamicSelectorSetting.java index 267aa4f..6f3571f 100644 --- a/src/main/java/com/connorcode/sigmautils/config/settings/DynamicSelectorSetting.java +++ b/src/main/java/com/connorcode/sigmautils/config/settings/DynamicSelectorSetting.java @@ -140,10 +140,8 @@ protected ResourceSelectScreen(Screen _super, ResourceManager renderer) { @Override protected void init() { - this.searchField = - new TextFieldWidget(SigmaUtils.client.textRenderer, 0, 10, entryWidth / 2, 20, this.searchField, - Text.empty()); - focusOn(this.searchField); + this.searchField = new TextFieldWidget(SigmaUtils.client.textRenderer, 0, 10, entryWidth / 2, 20, this.searchField, Text.empty()); + setFocused(this.searchField); searchField.setX(width / 2 - searchField.getWidth() / 2); var y = padding * 6 + 30 - (int) this.scroll; var x = 20 + padding + startX(); @@ -151,9 +149,7 @@ protected void init() { var search = searchField.getText(); var res = renderer.getAllResources(); count = res.size(); - for (var i : res - .stream() - .filter(r -> search.isEmpty() || search(r, search)) + for (var i : res.stream().filter(r -> search.isEmpty() || search(r, search)) .toList()) { if (y < -entryHeight - padding) { y += entryHeight + padding; diff --git a/src/main/java/com/connorcode/sigmautils/misc/Components.java b/src/main/java/com/connorcode/sigmautils/misc/Components.java index 8cf89de..96446c2 100644 --- a/src/main/java/com/connorcode/sigmautils/misc/Components.java +++ b/src/main/java/com/connorcode/sigmautils/misc/Components.java @@ -6,7 +6,6 @@ import com.connorcode.sigmautils.misc.util.Util; import com.connorcode.sigmautils.mixin.ScreenAccessor; import com.connorcode.sigmautils.module.Module; -import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.Drawable; import net.minecraft.client.gui.Element; @@ -15,7 +14,6 @@ import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; import net.minecraft.client.gui.tooltip.Tooltip; import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.gui.widget.CheckboxWidget; import net.minecraft.client.gui.widget.SliderWidget; import net.minecraft.text.Text; import net.minecraft.util.math.MathHelper; @@ -183,52 +181,11 @@ protected Text tooltip() { @Override public void render(DrawContext drawContext, int mouseX, int mouseY, float delta) { super.render(drawContext, mouseX, mouseY, delta); - if (!this.hovered) - return; + if (!this.hovered) return; Text tooltip = this.tooltip(); - if (tooltip == null) - return; - - drawContext.drawOrderedTooltip(client.textRenderer, client.textRenderer.wrapLines(tooltip, 200), mouseX, - mouseY); - } - } - - public static class EventCheckbox extends CheckboxWidget { - PressAction onPress; - TooltipSupplier tooltipSupplier; - - public EventCheckbox(int x, int y, int width, int height, Text message, boolean checked, TextRenderer renderer, PressAction onPress, TooltipSupplier tooltipSupplier) { - super(x, y, message, renderer, checked, Callback.EMPTY); - this.width = width; - this.height = height; - this.onPress = onPress; - this.tooltipSupplier = tooltipSupplier; - } - - @Override - public void onPress() { - super.onPress(); - this.onPress.onPress(this); - } - - public void renderTooltip(DrawContext drawContext, int mouseX, int mouseY) { - tooltipSupplier.onTooltip(this, drawContext, mouseX, mouseY); - } - - @Override - public void renderWidget(DrawContext drawContext, int mouseX, int mouseY, float delta) { - super.renderWidget(drawContext, mouseX, mouseY, delta); - if (this.isSelected()) - this.renderTooltip(drawContext, mouseX, mouseY); - } - - public interface PressAction { - void onPress(EventCheckbox button); - } + if (tooltip == null) return; - public interface TooltipSupplier { - void onTooltip(EventCheckbox button, DrawContext drawContext, int mouseX, int mouseY); + drawContext.drawOrderedTooltip(client.textRenderer, client.textRenderer.wrapLines(tooltip, 200), mouseX, mouseY); } } } diff --git a/src/main/java/com/connorcode/sigmautils/misc/util/NetworkUtils.java b/src/main/java/com/connorcode/sigmautils/misc/util/NetworkUtils.java index 3c7b755..f2ad64f 100644 --- a/src/main/java/com/connorcode/sigmautils/misc/util/NetworkUtils.java +++ b/src/main/java/com/connorcode/sigmautils/misc/util/NetworkUtils.java @@ -6,14 +6,11 @@ import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.MappingResolver; -import net.minecraft.network.NetworkPhase; import net.minecraft.network.NetworkSide; import net.minecraft.network.packet.Packet; import org.jetbrains.annotations.Nullable; -import java.util.Arrays; import java.util.HashMap; -import java.util.Objects; import java.util.UUID; import static com.connorcode.sigmautils.SigmaUtils.client; @@ -26,10 +23,11 @@ public class NetworkUtils { public static Object2IntOpenHashMap>> getPackets(NetworkSide side) { var packets = new Object2IntOpenHashMap>>(); - Arrays.stream(NetworkPhase.values()) - .map(state -> state.packetHandlers.get(side)) - .filter(Objects::nonNull) - .forEach(handler -> packets.putAll(handler.backingHandler.packetIds)); + // TODO: Fix +// Arrays.stream(NetworkPhase.values()) +// .map(state -> state.packetHandlers.get(side)) +// .filter(Objects::nonNull) +// .forEach(handler -> packets.putAll(handler.backingHandler.packetIds)); return packets; } diff --git a/src/main/java/com/connorcode/sigmautils/mixin/CameraMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/CameraMixin.java index 9184078..3540141 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/CameraMixin.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/CameraMixin.java @@ -1,28 +1,21 @@ package com.connorcode.sigmautils.mixin; -import com.connorcode.sigmautils.config.Config; -import com.connorcode.sigmautils.modules.misc.CameraClip; -import com.connorcode.sigmautils.modules.misc.CameraDistance; import net.minecraft.client.render.Camera; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyVariable; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(Camera.class) public class CameraMixin { - @ModifyVariable(method = "clipToSpace", at = @At("HEAD"), argsOnly = true) - double clipToSpace(double desiredCameraDistance) { - if (!Config.getEnabled(CameraDistance.class)) - return desiredCameraDistance; - return CameraDistance.getDistance(); - } - - @Inject(method = "clipToSpace", at = @At("HEAD"), cancellable = true) - void onClipToSpace(double desiredCameraDistance, CallbackInfoReturnable cir) { - if (!Config.getEnabled(CameraClip.class)) - return; - cir.setReturnValue(desiredCameraDistance); - } +// @ModifyVariable(method = "clipToSpace", at = @At("HEAD"), argsOnly = true) +// double clipToSpace(double desiredCameraDistance) { +// if (!Config.getEnabled(CameraDistance.class)) +// return desiredCameraDistance; +// return CameraDistance.getDistance(); +// } +// +// @Inject(method = "clipToSpace", at = @At("HEAD"), cancellable = true) +// void onClipToSpace(double desiredCameraDistance, CallbackInfoReturnable cir) { +// if (!Config.getEnabled(CameraClip.class)) +// return; +// cir.setReturnValue(desiredCameraDistance); +// } } diff --git a/src/main/java/com/connorcode/sigmautils/mixin/ChatHudMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/ChatHudMixin.java index 38b0d7e..3ff8be0 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/ChatHudMixin.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/ChatHudMixin.java @@ -1,31 +1,23 @@ package com.connorcode.sigmautils.mixin; -import com.connorcode.sigmautils.config.Config; -import com.connorcode.sigmautils.modules._interface.NoChatFade; -import com.connorcode.sigmautils.modules.chat.NoMessageHiding; import net.minecraft.client.gui.hud.ChatHud; -import net.minecraft.network.message.MessageSignatureData; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(ChatHud.class) public abstract class ChatHudMixin { @Shadow protected abstract boolean isChatFocused(); - @Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/ChatHud;isChatFocused()Z")) - boolean isChatFocused(ChatHud instance) { - if (Config.getEnabled(NoChatFade.class)) - return true; - return isChatFocused(); - } - - @Inject(method = "removeMessage", at = @At("HEAD"), cancellable = true) - void onHideMessage(MessageSignatureData signature, CallbackInfo ci) { - if (Config.getEnabled(NoMessageHiding.class)) ci.cancel(); - } +// @Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/ChatHud;isChatFocused()Z")) +// boolean isChatFocused(ChatHud instance) { +// if (Config.getEnabled(NoChatFade.class)) +// return true; +// return isChatFocused(); +// } +// +// @Inject(method = "removeMessage", at = @At("HEAD"), cancellable = true) +// void onHideMessage(MessageSignatureData signature, CallbackInfo ci) { +// if (Config.getEnabled(NoMessageHiding.class)) ci.cancel(); +// } } diff --git a/src/main/java/com/connorcode/sigmautils/mixin/ClientCommonNetworkHandlerMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/ClientCommonNetworkHandlerMixin.java index 6cc2597..3b7c62b 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/ClientCommonNetworkHandlerMixin.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/ClientCommonNetworkHandlerMixin.java @@ -5,11 +5,12 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(ClientCommonNetworkHandler.class) public class ClientCommonNetworkHandlerMixin { @Inject(method = "onCustomPayload", at = @At("HEAD")) - void onCustomPayload(CustomPayloadS2CPacket packet) { + void onCustomPayload(CustomPayloadS2CPacket packet, CallbackInfo ci) { // var buf = packet.getPayload(); // var event = new UnknownPacketEvent(buf, packet.payload().getId().id()); System.out.println("CUSTOM PAYLOAD:" + packet.payload().getClass().getSimpleName()); diff --git a/src/main/java/com/connorcode/sigmautils/mixin/ClientPlayerEntityMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/ClientPlayerEntityMixin.java index 9dca42c..b40c57f 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/ClientPlayerEntityMixin.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/ClientPlayerEntityMixin.java @@ -39,13 +39,13 @@ public void onRequestRespawn(CallbackInfo ci) { PrintDeathCords.lastDeath = null; } - @Redirect(method = "updateNausea", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;closeHandledScreen()V")) + @Redirect(method = "tickNausea", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;closeHandledScreen()V")) void onCloseHandledScreen(ClientPlayerEntity instance) { if (!Config.getEnabled(PortalInventory.class)) instance.closeHandledScreen(); } - @Redirect(method = "updateNausea", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;setScreen(Lnet/minecraft/client/gui/screen/Screen;)V")) + @Redirect(method = "tickNausea", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;setScreen(Lnet/minecraft/client/gui/screen/Screen;)V")) void onSetScreen(MinecraftClient instance, Screen screen) { if (!Config.getEnabled(PortalInventory.class)) instance.setScreen(screen); diff --git a/src/main/java/com/connorcode/sigmautils/mixin/CustomPayloadS2CPacketMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/CustomPayloadS2CPacketMixin.java index a4f2620..e8d98c6 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/CustomPayloadS2CPacketMixin.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/CustomPayloadS2CPacketMixin.java @@ -2,13 +2,11 @@ import net.minecraft.network.packet.s2c.common.CustomPayloadS2CPacket; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; @Mixin(CustomPayloadS2CPacket.class) public class CustomPayloadS2CPacketMixin { - @Inject(method = "apply", at = @At("HEAD")) - void onApply() { - - } +// @Inject(method = "apply", at = @At("HEAD")) +// void onApply() { +// +// } } diff --git a/src/main/java/com/connorcode/sigmautils/mixin/EntityRendererMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/EntityRendererMixin.java index d497375..fa4f245 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/EntityRendererMixin.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/EntityRendererMixin.java @@ -1,34 +1,23 @@ package com.connorcode.sigmautils.mixin; -import com.connorcode.sigmautils.config.Config; -import com.connorcode.sigmautils.modules.rendering.Deadmau5Ears; -import com.connorcode.sigmautils.modules.rendering.Titles; -import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.entity.EntityRenderer; -import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.Entity; -import net.minecraft.entity.passive.AbstractHorseEntity; -import net.minecraft.entity.passive.TameableEntity; -import net.minecraft.text.Text; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(EntityRenderer.class) public class EntityRendererMixin { - @Redirect(method = "renderLabelIfPresent", at = @At(value = "INVOKE", target = "Ljava/lang/String;equals(Ljava/lang/Object;)Z")) - private boolean isDeadmau5(String stringA, Object stringB) { - if (Config.getEnabled(Deadmau5Ears.class)) - return true; - return stringA.equals(stringB); - } - - @Inject(method = "renderLabelIfPresent", at = @At("HEAD"), cancellable = true) - private void renderLabelIfPresent(T entity, Text text, MatrixStack matrices, VertexConsumerProvider vertexConsumers, - int light, CallbackInfo ci) { - if (Titles.tamableOwner.value() && (entity instanceof TameableEntity || entity instanceof AbstractHorseEntity)) - ci.cancel(); - } + // TODO: fix +// @Redirect(method = "renderLabelIfPresent", at = @At(value = "INVOKE", target = "Ljava/lang/String;equals(Ljava/lang/Object;)Z")) +// private boolean isDeadmau5(String stringA, Object stringB) { +// if (Config.getEnabled(Deadmau5Ears.class)) +// return true; +// return stringA.equals(stringB); +// } +// +// @Inject(method = "renderLabelIfPresent", at = @At("HEAD"), cancellable = true) +// private void renderLabelIfPresent(T entity, Text text, MatrixStack matrices, VertexConsumerProvider vertexConsumers, +// int light, CallbackInfo ci) { +// if (Titles.tamableOwner.value() && (entity instanceof TameableEntity || entity instanceof AbstractHorseEntity)) +// ci.cancel(); +// } } diff --git a/src/main/java/com/connorcode/sigmautils/mixin/EntryListWidgetMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/EntryListWidgetMixin.java deleted file mode 100644 index b7941af..0000000 --- a/src/main/java/com/connorcode/sigmautils/mixin/EntryListWidgetMixin.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.connorcode.sigmautils.mixin; - -import com.connorcode.sigmautils.config.Config; -import com.connorcode.sigmautils.modules._interface.RandomBackground; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.widget.EntryListWidget; -import net.minecraft.util.Identifier; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - - -@Mixin(EntryListWidget.class) -public class EntryListWidgetMixin { - @Redirect(method = "renderWidget", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawTexture(Lnet/minecraft/util/Identifier;IIFFIIII)V")) - private void setShaderTexture(DrawContext instance, Identifier texture, int x, int y, float u, float v, int width, int height, int textureWidth, int textureHeight) { - if (Config.getEnabled(RandomBackground.class)) texture = RandomBackground.getTexture(); - instance.drawTexture(texture, x, y, u, v, width, height, textureWidth, textureHeight); - } -} diff --git a/src/main/java/com/connorcode/sigmautils/mixin/InGameHudAccessor.java b/src/main/java/com/connorcode/sigmautils/mixin/InGameHudAccessor.java deleted file mode 100644 index 0dd5a45..0000000 --- a/src/main/java/com/connorcode/sigmautils/mixin/InGameHudAccessor.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.connorcode.sigmautils.mixin; - -import net.minecraft.client.gui.hud.InGameHud; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(InGameHud.class) -public interface InGameHudAccessor { - @Accessor - int getScaledWidth(); - - @Accessor - int getScaledHeight(); -} diff --git a/src/main/java/com/connorcode/sigmautils/mixin/InGameHudMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/InGameHudMixin.java index 0d07514..a26770f 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/InGameHudMixin.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/InGameHudMixin.java @@ -2,17 +2,14 @@ import com.connorcode.sigmautils.config.Config; import com.connorcode.sigmautils.misc.util.WorldUtils; -import com.connorcode.sigmautils.modules._interface.ChatPosition; import com.connorcode.sigmautils.modules._interface.HotbarPosition; import com.connorcode.sigmautils.modules._interface.NoScoreboardValue; -import com.connorcode.sigmautils.modules.hud.Hud; import com.connorcode.sigmautils.modules.misc.BlockDistance; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.hud.ChatHud; import net.minecraft.client.gui.hud.InGameHud; -import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.client.render.RenderTickCounter; import net.minecraft.scoreboard.ScoreboardEntry; import net.minecraft.scoreboard.number.NumberFormat; import net.minecraft.text.MutableText; @@ -22,7 +19,9 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.*; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.Objects; @@ -33,49 +32,46 @@ public abstract class InGameHudMixin { @Final private MinecraftClient client; - @Shadow - private int scaledWidth; - - @Shadow - private int scaledHeight; - @Shadow public abstract TextRenderer getTextRenderer(); @Inject(method = "renderCrosshair", at = @At("TAIL")) - void onRenderCrosshair(DrawContext ctx, CallbackInfo ci) { + void onRenderCrosshair(DrawContext ctx, RenderTickCounter renderTickCounter, CallbackInfo ci) { if (!Config.getEnabled(BlockDistance.class)) return; client.getProfiler().push("SigmaUtils::BlockDistance"); - HitResult hitResult = - WorldUtils.raycast(Objects.requireNonNull(client.getCameraEntity()), BlockDistance.maxDistance.value(), - client.getTickDelta()); + var tickDelta = renderTickCounter.getTickDelta(true); + var hitResult = WorldUtils.raycast(Objects.requireNonNull(client.getCameraEntity()), BlockDistance.maxDistance.value(), tickDelta); if (Objects.requireNonNull(hitResult).getType() == HitResult.Type.MISS) return; - var distance = Objects.requireNonNull(hitResult) - .getPos() - .distanceTo(Objects.requireNonNull(client.player).getPos()); + var distance = Objects.requireNonNull(hitResult).getPos().distanceTo(Objects.requireNonNull(client.player).getPos()); - String text = String.format("§f[%d]", (int) distance); + var text = String.format("§f[%d]", (int) distance); + var window = client.getWindow(); ctx.drawText(client.textRenderer, - Text.of(text).asOrderedText(), scaledWidth / 2 - client.textRenderer.getWidth(text) / 2, - scaledHeight / 2 + client.textRenderer.fontHeight, 0, true); + Text.of(text).asOrderedText(), + window.getScaledWidth() / 2 - client.textRenderer.getWidth(text) / 2, + window.getScaledHeight() / 2 + client.textRenderer.fontHeight, + 0, + true); client.getProfiler().pop(); } - @Inject(method = "render", at = @At("TAIL")) - void onRender(DrawContext drawContext, float tickDelta, CallbackInfo ci) { - if (client.options.hudHidden || !Config.getEnabled(Hud.class)) - return; - Hud.renderHud(drawContext); - } + // TODO:fix +// @Inject(method = "render", at = @At("TAIL")) +// void onRender(DrawContext drawContext, RenderTickCounter renderTickCounter, float tickDelta, CallbackInfo ci) { +// if (client.options.hudHidden || !Config.getEnabled(Hud.class)) +// return; +// Hud.renderHud(drawContext); +// } - @Redirect(method = "renderScoreboardSidebar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/font/TextRenderer;getWidth(Ljava/lang/String;)I")) - int onGetWidth(TextRenderer instance, String text) { - if (Config.getEnabled(NoScoreboardValue.class)) - return 0; - return instance.getWidth(text); - } + // TODO: fix this also +// @Redirect(method = "renderScoreboardSidebar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/font/TextRenderer;getWidth(Ljava/lang/String;)I")) +// int onGetWidth(TextRenderer instance, String text) { +// if (Config.getEnabled(NoScoreboardValue.class)) +// return 0; +// return instance.getWidth(text); +// } // @Redirect(method = "renderScoreboardSidebar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawText(Lnet/minecraft/client/font/TextRenderer;Ljava/lang/String;IIIZ)I")) @@ -91,75 +87,77 @@ MutableText onToString(ScoreboardEntry instance, NumberFormat format) { return instance.formatted(format); } - @Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/ChatHud;render(Lnet/minecraft/client/gui/DrawContext;III)V")) - void onRenderChat(ChatHud instance, DrawContext context, int currentTick, int mouseX, int mouseY) { - MatrixStack matrices = context.getMatrices(); - matrices.push(); - if (Config.getEnabled(ChatPosition.class)) - matrices.translate(0, -ChatPosition.yPosition.intValue() * client.textRenderer.fontHeight, 0); - instance.render(context, currentTick, mouseX, mouseY); - matrices.pop(); - } + // TODO: fix this +// @Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/ChatHud;render(Lnet/minecraft/client/gui/DrawContext;IIIZ)V")) +// void onRenderChat(ChatHud instance, DrawContext context, int currentTick, int mouseX, int mouseY, boolean focused) { +// MatrixStack matrices = context.getMatrices(); +// matrices.push(); +// if (Config.getEnabled(ChatPosition.class)) +// matrices.translate(0, -ChatPosition.yPosition.intValue() * client.textRenderer.fontHeight, 0); +// instance.render(context, currentTick, mouseX, mouseY, focused); +// matrices.pop(); +// } @Unique int getHotbarPos() { return Config.getEnabled(HotbarPosition.class) ? HotbarPosition.yPosition.intValue() : 0; } - // Modified from https://github.com/yurisuika/Raise - @ModifyArg(method = "renderHotbar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawGuiTexture(Lnet/minecraft/util/Identifier;IIII)V"), index = 2) - private int modifyHotbar(int value) { - return value - getHotbarPos(); - } - -// @ModifyArg(method = "renderHotbar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawGuiTexture(Lnet/minecraft/util/Identifier;IIII)V", ordinal = 1), index = 2) -// private int modifySelectorHeight(int value) { -// return value + 2; + // todo: fix +// // Modified from https://github.com/yurisuika/Raise +// @ModifyArg(method = "renderHotbar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawGuiTexture(Lnet/minecraft/util/Identifier;IIII)V"), index = 2) +// private int modifyHotbar(int value) { +// return value - getHotbarPos(); // } - - @ModifyArg(method = "renderHotbar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/InGameHud;renderHotbarItem(Lnet/minecraft/client/gui/DrawContext;IIFLnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/item/ItemStack;I)V"), index = 2) - private int modifyItem(int value) { - return value - getHotbarPos(); - } - - @ModifyVariable(method = "renderMountJumpBar", at = @At(value = "STORE"), ordinal = 1) - private int modifyJumpBar(int value) { - return value - getHotbarPos(); - } - - @ModifyArg(method = "renderExperienceBar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawGuiTexture(Lnet/minecraft/util/Identifier;IIII)V"), index = 2) - private int modifyExperienceBarBackground(int value) { - return value - getHotbarPos(); - } - - @ModifyArg(method = "renderExperienceBar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawGuiTexture(Lnet/minecraft/util/Identifier;IIIIIIII)V"), index = 6) - private int modifyExperienceBar(int value) { - return value - getHotbarPos(); - } - - @ModifyArg(method = "renderExperienceBar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawText(Lnet/minecraft/client/font/TextRenderer;Ljava/lang/String;IIIZ)I"), index = 3) - private int modifyXpText(int value) { - return value - getHotbarPos(); - } - - @ModifyVariable(method = "renderHeldItemTooltip", at = @At(value = "STORE"), ordinal = 2) - private int modifyHeldItemTooltip(int value) { - return value - getHotbarPos(); - } - - @ModifyVariable(method = "renderStatusBars", at = @At(value = "STORE"), ordinal = 5) - private int modifyStatusBars(int value) { - return value - getHotbarPos(); - } - - @ModifyVariable(method = "renderMountHealth", at = @At(value = "STORE"), ordinal = 2) - private int modifyMountHealth(int value) { - return value - getHotbarPos(); - } - - @ModifyArg(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/math/MatrixStack;translate(FFF)V", ordinal = 0), index = 1) - private float modifyActionbar(float value) { - return value - getHotbarPos(); - } - // End +// +//// @ModifyArg(method = "renderHotbar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawGuiTexture(Lnet/minecraft/util/Identifier;IIII)V", ordinal = 1), index = 2) +//// private int modifySelectorHeight(int value) { +//// return value + 2; +//// } +// +// @ModifyArg(method = "renderHotbar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/InGameHud;renderHotbarItem(Lnet/minecraft/client/gui/DrawContext;IIFLnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/item/ItemStack;I)V"), index = 2) +// private int modifyItem(int value) { +// return value - getHotbarPos(); +// } +// +// @ModifyVariable(method = "renderMountJumpBar", at = @At(value = "STORE"), ordinal = 1) +// private int modifyJumpBar(int value) { +// return value - getHotbarPos(); +// } +// +// @ModifyArg(method = "renderExperienceBar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawGuiTexture(Lnet/minecraft/util/Identifier;IIII)V"), index = 2) +// private int modifyExperienceBarBackground(int value) { +// return value - getHotbarPos(); +// } +// +// @ModifyArg(method = "renderExperienceBar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawGuiTexture(Lnet/minecraft/util/Identifier;IIIIIIII)V"), index = 6) +// private int modifyExperienceBar(int value) { +// return value - getHotbarPos(); +// } +// +// @ModifyArg(method = "renderExperienceBar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawText(Lnet/minecraft/client/font/TextRenderer;Ljava/lang/String;IIIZ)I"), index = 3) +// private int modifyXpText(int value) { +// return value - getHotbarPos(); +// } +// +// @ModifyVariable(method = "renderHeldItemTooltip", at = @At(value = "STORE"), ordinal = 2) +// private int modifyHeldItemTooltip(int value) { +// return value - getHotbarPos(); +// } +// +// @ModifyVariable(method = "renderStatusBars", at = @At(value = "STORE"), ordinal = 5) +// private int modifyStatusBars(int value) { +// return value - getHotbarPos(); +// } +// +// @ModifyVariable(method = "renderMountHealth", at = @At(value = "STORE"), ordinal = 2) +// private int modifyMountHealth(int value) { +// return value - getHotbarPos(); +// } +// +// @ModifyArg(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/math/MatrixStack;translate(FFF)V", ordinal = 0), index = 1) +// private float modifyActionbar(float value) { +// return value - getHotbarPos(); +// } +// // End } diff --git a/src/main/java/com/connorcode/sigmautils/mixin/InventoryScreenMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/InventoryScreenMixin.java index 38204e6..5ed672d 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/InventoryScreenMixin.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/InventoryScreenMixin.java @@ -1,68 +1,54 @@ package com.connorcode.sigmautils.mixin; -import com.connorcode.sigmautils.SigmaUtils; -import com.connorcode.sigmautils.modules._interface.UiTweaks; -import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.ingame.AbstractInventoryScreen; import net.minecraft.client.gui.screen.ingame.InventoryScreen; import net.minecraft.client.gui.screen.recipebook.RecipeBookProvider; -import net.minecraft.client.render.entity.EntityRenderDispatcher; -import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.screen.PlayerScreenHandler; import net.minecraft.text.Text; -import org.joml.Quaternionf; -import org.joml.Vector3f; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @Mixin(InventoryScreen.class) -public abstract class InventoryScreenMixin extends AbstractInventoryScreen - implements RecipeBookProvider { +public abstract class InventoryScreenMixin extends AbstractInventoryScreen implements RecipeBookProvider { public InventoryScreenMixin(PlayerScreenHandler screenHandler, PlayerInventory playerInventory, Text text) { super(screenHandler, playerInventory, text); } - @Redirect(method = "drawEntity(Lnet/minecraft/client/gui/DrawContext;IIIIIFFFLnet/minecraft/entity/LivingEntity;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;enableScissor(IIII)V")) - private static void onEnableScissor(DrawContext instance, int x1, int y1, int x2, int y2) { - if (!UiTweaks.unMaskedDoll()) instance.enableScissor(x1, y1, x2, y2); - } - - @Redirect(method = "drawEntity(Lnet/minecraft/client/gui/DrawContext;IIIIIFFFLnet/minecraft/entity/LivingEntity;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;disableScissor()V")) - private static void onDisableScissor(DrawContext instance) { - if (!UiTweaks.unMaskedDoll()) instance.disableScissor(); - } - - @Inject(method = "drawEntity(Lnet/minecraft/client/gui/DrawContext;FFILorg/joml/Vector3f;Lorg/joml/Quaternionf;Lorg/joml/Quaternionf;Lnet/minecraft/entity/LivingEntity;)V", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;runAsFancy(Ljava/lang/Runnable;)V"), locals = LocalCapture.CAPTURE_FAILHARD) - private static void onDrawEntity(DrawContext context, float x, float y, int size, Vector3f vector3f, - Quaternionf quaternionf, Quaternionf quaternionf2, LivingEntity entity, - CallbackInfo ci, EntityRenderDispatcher entityRenderDispatcher) { - if (!UiTweaks.fastDoll()) return; - var ca = ((MinecraftClientAccessor) SigmaUtils.client); - var tickDelta = SigmaUtils.client.isPaused() ? ca.getPausedTickDelta() : ca.getRenderTickCounter().tickDelta; - - float h = entity.prevBodyYaw; - float i = entity.prevYaw; - float j = entity.prevPitch; - float k = entity.prevHeadYaw; - entity.prevBodyYaw = entity.bodyYaw; - entity.prevYaw = entity.getYaw(); - entity.prevPitch = entity.getPitch(); - entity.prevHeadYaw = entity.headYaw; - entityRenderDispatcher.render(entity, 0.0, 0.0, 0.0, 0.0F, tickDelta, context.getMatrices(), - context.getVertexConsumers(), 0xF000F0); - entity.prevBodyYaw = h; - entity.prevYaw = i; - entity.prevPitch = j; - entity.prevHeadYaw = k; - } - - @Redirect(method = "drawEntity(Lnet/minecraft/client/gui/DrawContext;FFILorg/joml/Vector3f;Lorg/joml/Quaternionf;Lorg/joml/Quaternionf;Lnet/minecraft/entity/LivingEntity;)V", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;runAsFancy(Ljava/lang/Runnable;)V")) - private static void onRender(Runnable runnable) { - if (!UiTweaks.fastDoll()) runnable.run(); - } +// @Redirect(method = "drawEntity(Lnet/minecraft/client/gui/DrawContext;IIIIIFFFLnet/minecraft/entity/LivingEntity;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;enableScissor(IIII)V")) +// private static void onEnableScissor(DrawContext instance, int x1, int y1, int x2, int y2) { +// if (!UiTweaks.unMaskedDoll()) instance.enableScissor(x1, y1, x2, y2); +// } +// +// @Redirect(method = "drawEntity(Lnet/minecraft/client/gui/DrawContext;IIIIIFFFLnet/minecraft/entity/LivingEntity;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;disableScissor()V")) +// private static void onDisableScissor(DrawContext instance) { +// if (!UiTweaks.unMaskedDoll()) instance.disableScissor(); +// } +// +// @Inject(method = "drawEntity(Lnet/minecraft/client/gui/DrawContext;FFILorg/joml/Vector3f;Lorg/joml/Quaternionf;Lorg/joml/Quaternionf;Lnet/minecraft/entity/LivingEntity;)V", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;runAsFancy(Ljava/lang/Runnable;)V"), locals = LocalCapture.CAPTURE_FAILHARD) +// private static void onDrawEntity(DrawContext context, float x, float y, int size, Vector3f vector3f, +// Quaternionf quaternionf, Quaternionf quaternionf2, LivingEntity entity, +// CallbackInfo ci, EntityRenderDispatcher entityRenderDispatcher) { +// if (!UiTweaks.fastDoll()) return; +// var tickDelta = SigmaUtils.client.getRenderTickCounter().getTickDelta(true); +// +// float h = entity.prevBodyYaw; +// float i = entity.prevYaw; +// float j = entity.prevPitch; +// float k = entity.prevHeadYaw; +// entity.prevBodyYaw = entity.bodyYaw; +// entity.prevYaw = entity.getYaw(); +// entity.prevPitch = entity.getPitch(); +// entity.prevHeadYaw = entity.headYaw; +// entityRenderDispatcher.render(entity, 0.0, 0.0, 0.0, 0.0F, tickDelta, context.getMatrices(), +// context.getVertexConsumers(), 0xF000F0); +// entity.prevBodyYaw = h; +// entity.prevYaw = i; +// entity.prevPitch = j; +// entity.prevHeadYaw = k; +// } +// +// @Redirect(method = "drawEntity(Lnet/minecraft/client/gui/DrawContext;FFILorg/joml/Vector3f;Lorg/joml/Quaternionf;Lorg/joml/Quaternionf;Lnet/minecraft/entity/LivingEntity;)V", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;runAsFancy(Ljava/lang/Runnable;)V")) +// private static void onRender(Runnable runnable) { +// if (!UiTweaks.fastDoll()) runnable.run(); +// } } diff --git a/src/main/java/com/connorcode/sigmautils/mixin/LivingEntityRendererMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/LivingEntityRendererMixin.java index 3f8b04b..794e132 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/LivingEntityRendererMixin.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/LivingEntityRendererMixin.java @@ -2,16 +2,12 @@ import com.connorcode.sigmautils.config.Config; import com.connorcode.sigmautils.modules.rendering.FlippedEntities; -import com.connorcode.sigmautils.modules.rendering.ShowInvisibleEntities; -import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.entity.LivingEntityRenderer; import net.minecraft.client.render.entity.model.EntityModel; -import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.LivingEntity; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(LivingEntityRenderer.class) @@ -21,14 +17,4 @@ private static void shouldFlipUpsideDown(LivingEntity entity, CallbackInfoReturn if (Config.getEnabled(FlippedEntities.class) && FlippedEntities.isFlipped(entity)) cir.setReturnValue(true); } - - @Redirect(method = "render(Lnet/minecraft/entity/LivingEntity;FFLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/entity/model/EntityModel;render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumer;IIFFFF)V")) - void onModelRender(M instance, MatrixStack matrixStack, VertexConsumer vertexConsumer, int light, int overlay, - float red, float green, float blue, float alpha, T livingEntity) { - // TODO: make work with mobs - if (Config.getEnabled(ShowInvisibleEntities.class) && ShowInvisibleEntities.isInvisible(livingEntity) && - livingEntity.getFlag(5)) - alpha = (float) ShowInvisibleEntities.opacity.value(); - instance.render(matrixStack, vertexConsumer, light, overlay, red, green, blue, alpha); - } } diff --git a/src/main/java/com/connorcode/sigmautils/mixin/MinecraftClientAccessor.java b/src/main/java/com/connorcode/sigmautils/mixin/MinecraftClientAccessor.java deleted file mode 100644 index c765a34..0000000 --- a/src/main/java/com/connorcode/sigmautils/mixin/MinecraftClientAccessor.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.connorcode.sigmautils.mixin; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.RenderTickCounter; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(MinecraftClient.class) -public interface MinecraftClientAccessor { - @Accessor - static int getCurrentFps() { - throw new RuntimeException(); - } - - @Accessor - float getPausedTickDelta(); - - @Accessor - RenderTickCounter getRenderTickCounter(); -} \ No newline at end of file diff --git a/src/main/java/com/connorcode/sigmautils/mixin/MinecraftClientMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/MinecraftClientMixin.java index 957148a..d36f22f 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/MinecraftClientMixin.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/MinecraftClientMixin.java @@ -92,8 +92,7 @@ void onGetStackInHand(CallbackInfo ci) { // Handle Item frames if (crosshairTarget.getType() == HitResult.Type.ENTITY && ((EntityHitResult) crosshairTarget).getEntity() instanceof ItemFrameEntity itemFrameEntity) { - BlockPos behindBlockPos = itemFrameEntity.getDecorationBlockPos() - .offset(itemFrameEntity.getHorizontalFacing().getOpposite()); + BlockPos behindBlockPos = itemFrameEntity.getBlockPos().offset(itemFrameEntity.getHorizontalFacing().getOpposite()); crosshairTarget = new BlockHitResult(crosshairTarget.getPos(), itemFrameEntity.getHorizontalFacing(), behindBlockPos, diff --git a/src/main/java/com/connorcode/sigmautils/mixin/OptionsScreenMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/OptionsScreenMixin.java index b21d8db..f7a724b 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/OptionsScreenMixin.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/OptionsScreenMixin.java @@ -1,18 +1,10 @@ package com.connorcode.sigmautils.mixin; -import com.connorcode.sigmautils.config.Config; -import com.connorcode.sigmautils.modules._interface.UiTweaks; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.option.OptionsScreen; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.gui.widget.GridWidget; import net.minecraft.text.Text; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @Mixin(OptionsScreen.class) public class OptionsScreenMixin extends Screen { @@ -20,15 +12,15 @@ protected OptionsScreenMixin(Text title) { super(title); } - @Inject(method = "init", at = @At("TAIL"), locals = LocalCapture.CAPTURE_FAILHARD) - void onButtonRender(CallbackInfo ci, GridWidget gridWidget, GridWidget.Adder adder) { - if (!Config.getEnabled(UiTweaks.class) || !UiTweaks.audioMuteButton.value()) return; - - var x = this.width / 2 + 160; - var y = this.height / 6 + 42; - addDrawableChild(ButtonWidget.builder(Text.of(UiTweaks.muted ? "U" : "M"), button -> { - UiTweaks.muted ^= true; - button.setMessage(Text.of(UiTweaks.muted ? "U" : "M")); - }).position(x, y).size(20, 20).build()); - } +// @Inject(method = "init", at = @At("TAIL"), locals = LocalCapture.CAPTURE_FAILHARD) +// void onButtonRender(CallbackInfo ci, GridWidget gridWidget, GridWidget.Adder adder) { +// if (!Config.getEnabled(UiTweaks.class) || !UiTweaks.audioMuteButton.value()) return; +// +// var x = this.width / 2 + 160; +// var y = this.height / 6 + 42; +// addDrawableChild(ButtonWidget.builder(Text.of(UiTweaks.muted ? "U" : "M"), button -> { +// UiTweaks.muted ^= true; +// button.setMessage(Text.of(UiTweaks.muted ? "U" : "M")); +// }).position(x, y).size(20, 20).build()); +// } } diff --git a/src/main/java/com/connorcode/sigmautils/mixin/RenderTickCounterAccessor.java b/src/main/java/com/connorcode/sigmautils/mixin/RenderTickCounterAccessor.java deleted file mode 100644 index 36b738f..0000000 --- a/src/main/java/com/connorcode/sigmautils/mixin/RenderTickCounterAccessor.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.connorcode.sigmautils.mixin; - -import net.minecraft.client.render.RenderTickCounter; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Mutable; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(RenderTickCounter.class) -public interface RenderTickCounterAccessor { - @Accessor("tickTime") - @Mutable - void tickTime(float tickTime); -} diff --git a/src/main/java/com/connorcode/sigmautils/mixin/ScreenAccessor.java b/src/main/java/com/connorcode/sigmautils/mixin/ScreenAccessor.java index 897db9a..2d5bd09 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/ScreenAccessor.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/ScreenAccessor.java @@ -31,7 +31,4 @@ public interface ScreenAccessor { @Invoker void invokeClearAndInit(); - -// @Invoker -// void invokeRenderOrderedTooltip(MatrixStack matrices, List sigma_utils, int mouseX, int mouseY); } diff --git a/src/main/java/com/connorcode/sigmautils/mixin/ScreenMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/ScreenMixin.java deleted file mode 100644 index 2843479..0000000 --- a/src/main/java/com/connorcode/sigmautils/mixin/ScreenMixin.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.connorcode.sigmautils.mixin; - -import com.connorcode.sigmautils.config.Config; -import com.connorcode.sigmautils.modules._interface.RandomBackground; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.util.Identifier; -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(Screen.class) -public class ScreenMixin { - @Shadow - @Nullable - protected MinecraftClient client; - - @Redirect(method = "renderBackgroundTexture", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawTexture(Lnet/minecraft/util/Identifier;IIIFFIIII)V")) - private void setShaderTexture(DrawContext instance, Identifier texture, int x, int y, int z, float u, float v, int width, int height, int textureWidth, int textureHeight) { - if (Config.getEnabled(RandomBackground.class)) texture = RandomBackground.getTexture(); - instance.drawTexture(texture, x, y, u, v, width, height, textureWidth, textureHeight); - } -} diff --git a/src/main/java/com/connorcode/sigmautils/mixin/WorldRendererMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/WorldRendererMixin.java index c5c10e0..73a8443 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/WorldRendererMixin.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/WorldRendererMixin.java @@ -1,95 +1,67 @@ package com.connorcode.sigmautils.mixin; -import com.connorcode.sigmautils.SigmaUtils; -import com.connorcode.sigmautils.config.Config; -import com.connorcode.sigmautils.event.render.EntityRender; -import com.connorcode.sigmautils.event.render.WorldBorderRender; -import com.connorcode.sigmautils.event.render.WorldRender; -import com.connorcode.sigmautils.modules.misc.NoGlobalSounds; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gl.VertexBuffer; -import net.minecraft.client.render.Camera; -import net.minecraft.client.render.GameRenderer; -import net.minecraft.client.render.LightmapTextureManager; import net.minecraft.client.render.WorldRenderer; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.entity.Entity; -import net.minecraft.sound.SoundCategory; -import net.minecraft.sound.SoundEvent; -import net.minecraft.util.math.BlockPos; -import org.jetbrains.annotations.Nullable; -import org.joml.Matrix4f; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.util.Objects; - -import static net.minecraft.sound.SoundEvents.*; @Mixin(WorldRenderer.class) public abstract class WorldRendererMixin { - int color; - @Shadow - @Nullable - private ClientWorld world; - - @Shadow - @Nullable - private VertexBuffer lightSkyBuffer; - - @Inject(method = "processGlobalEvent", at = @At("HEAD")) - void onProcessGlobalEvent(int eventId, BlockPos pos, int data, CallbackInfo ci) { - if (!Config.getEnabled(NoGlobalSounds.class)) return; - SoundEvent sound = switch (eventId) { - case 1023 -> ENTITY_WITHER_SPAWN; - case 1038 -> BLOCK_END_PORTAL_SPAWN; - case 1028 -> ENTITY_ENDER_DRAGON_DEATH; - default -> null; - }; - - if (sound == null || NoGlobalSounds.disabled(eventId)) - return; - Objects.requireNonNull(world).playSoundAtBlockCenter(pos, sound, SoundCategory.HOSTILE, 1.0F, 1.0F, false); - } - - @Inject(method = "renderWorldBorder", at = @At("HEAD"), cancellable = true) - void onRenderWorldBorder(Camera camera, CallbackInfo ci) { - var event = new WorldBorderRender(camera); - SigmaUtils.eventBus.post(event); - if (event.isCancelled()) ci.cancel(); - } - - @Inject(method = "render", at = @At("HEAD"), cancellable = true) - void onRender(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f positionMatrix, CallbackInfo ci) { - var event = new WorldRender.PreWorldRenderEvent(matrices, tickDelta, limitTime, renderBlockOutline, camera, gameRenderer, lightmapTextureManager, positionMatrix); - SigmaUtils.eventBus.post(event); - if (event.isCancelled()) ci.cancel(); - } - - @Inject(method = "render", at = @At("RETURN"), cancellable = true) - void onPostRender(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f positionMatrix, CallbackInfo ci) { - var event = new WorldRender.PostWorldRenderEvent(matrices, tickDelta, limitTime, renderBlockOutline, camera, gameRenderer, lightmapTextureManager, positionMatrix); - SigmaUtils.eventBus.post(event); - if (event.isCancelled()) ci.cancel(); - } - - @Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;hasOutline(Lnet/minecraft/entity/Entity;)Z")) - boolean onHasOutline(MinecraftClient instance, Entity entity) { - var event = - new EntityRender.EntityHighlightEvent(entity, instance.hasOutline(entity), entity.getTeamColorValue()); - SigmaUtils.eventBus.post(event); - this.color = event.getColor(); - return event.hasOutline(); - } - - @Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;getTeamColorValue()I")) - int onGetTeamColorValue(Entity instance) { - return this.color; - } +// int color; +// @Shadow +// @Nullable +// private ClientWorld world; +// +// @Shadow +// @Nullable +// private VertexBuffer lightSkyBuffer; +// +// @Inject(method = "processGlobalEvent", at = @At("HEAD")) +// void onProcessGlobalEvent(int eventId, BlockPos pos, int data, CallbackInfo ci) { +// if (!Config.getEnabled(NoGlobalSounds.class)) return; +// SoundEvent sound = switch (eventId) { +// case 1023 -> ENTITY_WITHER_SPAWN; +// case 1038 -> BLOCK_END_PORTAL_SPAWN; +// case 1028 -> ENTITY_ENDER_DRAGON_DEATH; +// default -> null; +// }; +// +// if (sound == null || NoGlobalSounds.disabled(eventId)) +// return; +// Objects.requireNonNull(world).playSoundAtBlockCenter(pos, sound, SoundCategory.HOSTILE, 1.0F, 1.0F, false); +// } +// +// @Inject(method = "renderWorldBorder", at = @At("HEAD"), cancellable = true) +// void onRenderWorldBorder(Camera camera, CallbackInfo ci) { +// var event = new WorldBorderRender(camera); +// SigmaUtils.eventBus.post(event); +// if (event.isCancelled()) ci.cancel(); +// } +// +// @Inject(method = "render", at = @At("HEAD"), cancellable = true) +// void onRender(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f positionMatrix, CallbackInfo ci) { +// var event = new WorldRender.PreWorldRenderEvent(matrices, tickDelta, limitTime, renderBlockOutline, camera, gameRenderer, lightmapTextureManager, positionMatrix); +// SigmaUtils.eventBus.post(event); +// if (event.isCancelled()) ci.cancel(); +// } +// +// @Inject(method = "render", at = @At("RETURN"), cancellable = true) +// void onPostRender(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f positionMatrix, CallbackInfo ci) { +// var event = new WorldRender.PostWorldRenderEvent(matrices, tickDelta, limitTime, renderBlockOutline, camera, gameRenderer, lightmapTextureManager, positionMatrix); +// SigmaUtils.eventBus.post(event); +// if (event.isCancelled()) ci.cancel(); +// } +// +// @Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;hasOutline(Lnet/minecraft/entity/Entity;)Z")) +// boolean onHasOutline(MinecraftClient instance, Entity entity) { +// var event = +// new EntityRender.EntityHighlightEvent(entity, instance.hasOutline(entity), entity.getTeamColorValue()); +// SigmaUtils.eventBus.post(event); +// this.color = event.getColor(); +// return event.hasOutline(); +// } +// +// @Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;getTeamColorValue()I")) +// int onGetTeamColorValue(Entity instance) { +// return this.color; +// } } diff --git a/src/main/java/com/connorcode/sigmautils/mixin/modmenu/DescriptionListWidgetMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/modmenu/DescriptionListWidgetMixin.java deleted file mode 100644 index 602421a..0000000 --- a/src/main/java/com/connorcode/sigmautils/mixin/modmenu/DescriptionListWidgetMixin.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.connorcode.sigmautils.mixin.modmenu; - -import com.connorcode.sigmautils.config.Config; -import com.connorcode.sigmautils.modules._interface.RandomBackground; -import com.mojang.blaze3d.systems.RenderSystem; -import com.terraformersmc.modmenu.gui.widget.DescriptionListWidget; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.Screen; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(value = DescriptionListWidget.class) -public class DescriptionListWidgetMixin { - @Inject(method = "renderList", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;setShaderTexture(ILnet/minecraft/util/Identifier;)V", shift = At.Shift.AFTER)) - private void render(DrawContext DrawContext, int mouseX, int mouseY, float delta, CallbackInfo ci) { - var id = Config.getEnabled(RandomBackground.class) ? - RandomBackground.getTexture() : Screen.OPTIONS_BACKGROUND_TEXTURE; - RenderSystem.setShaderTexture(0, id); - } -} diff --git a/src/main/java/com/connorcode/sigmautils/modules/_interface/RandomBackground.java b/src/main/java/com/connorcode/sigmautils/modules/_interface/RandomBackground.java deleted file mode 100644 index cb3ba90..0000000 --- a/src/main/java/com/connorcode/sigmautils/modules/_interface/RandomBackground.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.connorcode.sigmautils.modules._interface; - -import com.connorcode.sigmautils.SigmaUtils; -import com.connorcode.sigmautils.config.settings.DynamicListSetting; -import com.connorcode.sigmautils.config.settings.EnumSetting; -import com.connorcode.sigmautils.config.settings.list.SimpleList; -import com.connorcode.sigmautils.misc.Components; -import com.connorcode.sigmautils.misc.util.Util; -import com.connorcode.sigmautils.module.Module; -import com.connorcode.sigmautils.module.ModuleInfo; -import net.minecraft.block.Block; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.registry.Registries; -import net.minecraft.util.Identifier; - -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.util.List; -import java.util.Objects; -import java.util.Random; - -import static com.connorcode.sigmautils.SigmaUtils.client; -import static net.minecraft.client.gui.screen.Screen.OPTIONS_BACKGROUND_TEXTURE; - - -@ModuleInfo(description = "Uses random textures for the background tessellation", - documentation = "It will change every time you open a new screen.") -public class RandomBackground extends Module { - static final List validBackgrounds = new BufferedReader(new InputStreamReader(Objects.requireNonNull( - SigmaUtils.class.getClassLoader().getResourceAsStream("assets/sigma-utils/background_blocks.txt")))).lines() - .toList(); - static EnumSetting filterType = Util.filterSetting(RandomBackground.class) - .description("Whether to blacklist or whitelist background textures.") - .value(Util.FilterType.Blacklist) - .build(); - static DynamicListSetting textures = - new DynamicListSetting<>(RandomBackground.class, "Textures", BlockList::new).description("Possible background textures.").build(); - static String asset; - static int screenHash = -1; - - public static Identifier getTexture() { - int currentScreenHash = Objects.requireNonNull(Objects.requireNonNull(client).currentScreen).hashCode(); - - if (screenHash != currentScreenHash || asset == null) { - screenHash = currentScreenHash; - - List valid = switch (filterType.value()) { - case Whitelist -> textures.value().stream().map(block -> Registries.BLOCK.getId(block).getPath()).toList(); - case Blacklist -> validBackgrounds.stream().filter(s -> !textures.value().contains(Registries.BLOCK.get(Identifier.tryParse("minecraft:" + s)))).toList(); - }; - - if (valid.isEmpty()) return OPTIONS_BACKGROUND_TEXTURE; - var assetIndex = new Random().nextInt(valid.size()); - asset = valid.get(assetIndex); - } - - return Identifier.tryParse("textures/block/" + asset + ".png"); - } - - static class BlockList extends SimpleList { - - public BlockList(DynamicListSetting setting) { - super(setting, Registries.BLOCK); - } - - @Override - public String getDisplay(Block value) { - return value.getName().getString(); - } - - @Override - public boolean renderSelector(Block resource, Screen screen, int x, int y) { - var rawId = Registries.BLOCK.getId(resource).getPath(); - var id = Identifier.tryParse("textures/block/" + rawId + ".png"); - if (!RandomBackground.validBackgrounds.contains(rawId) || this.setting.value().contains(resource)) return false; - Util.addDrawable(screen, new Components.DrawableElement() { - @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - context.drawTexture(id, x - 1, y + 2, 0, 0.0F, 0.0F, 16, 16, 16, 16); - } - }); - return super.renderSelector(resource, screen, x + 16, y); - } - } -} diff --git a/src/main/java/com/connorcode/sigmautils/modules/hud/FpsHud.java b/src/main/java/com/connorcode/sigmautils/modules/hud/FpsHud.java index 763c30b..8080941 100644 --- a/src/main/java/com/connorcode/sigmautils/modules/hud/FpsHud.java +++ b/src/main/java/com/connorcode/sigmautils/modules/hud/FpsHud.java @@ -1,10 +1,11 @@ package com.connorcode.sigmautils.modules.hud; import com.connorcode.sigmautils.misc.TextStyle; -import com.connorcode.sigmautils.mixin.MinecraftClientAccessor; import com.connorcode.sigmautils.module.HudModule; import com.connorcode.sigmautils.module.ModuleInfo; +import static com.connorcode.sigmautils.SigmaUtils.client; + @ModuleInfo(description = "Shows the current FPS in the HUD") public class FpsHud extends HudModule { public FpsHud() { @@ -14,7 +15,6 @@ public FpsHud() { } public String line() { - return String.format("§r%sFps: §f%d", this.getTextColor(), - MinecraftClientAccessor.getCurrentFps()); + return String.format("§r%sFps: §f%d", this.getTextColor(), client.getCurrentFps()); } } diff --git a/src/main/java/com/connorcode/sigmautils/modules/hud/Hud.java b/src/main/java/com/connorcode/sigmautils/modules/hud/Hud.java index 543b274..81e1e12 100644 --- a/src/main/java/com/connorcode/sigmautils/modules/hud/Hud.java +++ b/src/main/java/com/connorcode/sigmautils/modules/hud/Hud.java @@ -3,7 +3,6 @@ import com.connorcode.sigmautils.config.settings.BoolSetting; import com.connorcode.sigmautils.config.settings.EnumSetting; import com.connorcode.sigmautils.misc.Components; -import com.connorcode.sigmautils.mixin.InGameHudAccessor; import com.connorcode.sigmautils.module.HudModule; import com.connorcode.sigmautils.module.Module; import com.connorcode.sigmautils.module.ModuleInfo; @@ -62,12 +61,11 @@ public static List getHud(int scaledHeight, int scaledWidth) { public static void renderHud(DrawContext ctx) { if (client.getDebugHud().shouldShowDebugHud() && hideF3.value()) return; - InGameHudAccessor hudAccessor = (InGameHudAccessor) client.inGameHud; int padding = getPadding(); client.getProfiler().push("SigmaUtils::Hud"); - getHud(hudAccessor.getScaledHeight(), hudAccessor.getScaledWidth()).forEach( - hudStack -> hudStack.render(ctx, padding)); + var window = client.getWindow(); + getHud(window.getScaledHeight(), window.getScaledWidth()).forEach(hudStack -> hudStack.render(ctx, padding)); client.getProfiler().pop(); } diff --git a/src/main/java/com/connorcode/sigmautils/modules/misc/TickSpeed.java b/src/main/java/com/connorcode/sigmautils/modules/misc/TickSpeed.java index b435959..030554e 100644 --- a/src/main/java/com/connorcode/sigmautils/modules/misc/TickSpeed.java +++ b/src/main/java/com/connorcode/sigmautils/modules/misc/TickSpeed.java @@ -3,8 +3,6 @@ import com.connorcode.sigmautils.config.settings.NumberSetting; import com.connorcode.sigmautils.misc.Components; import com.connorcode.sigmautils.misc.util.Util; -import com.connorcode.sigmautils.mixin.MinecraftClientAccessor; -import com.connorcode.sigmautils.mixin.RenderTickCounterAccessor; import com.connorcode.sigmautils.module.Module; import com.connorcode.sigmautils.module.ModuleInfo; import net.minecraft.client.MinecraftClient; @@ -12,7 +10,6 @@ import net.minecraft.text.Text; import net.minecraft.util.math.MathHelper; -import static com.connorcode.sigmautils.SigmaUtils.client; import static com.connorcode.sigmautils.modules.meta.Padding.getPadding; @ModuleInfo(description = "Sets the clients tick speed in MSPT") @@ -27,7 +24,7 @@ Text getSliderTitle() { } void setTickSpeed(long mspt) { - ((RenderTickCounterAccessor) ((MinecraftClientAccessor) client).getRenderTickCounter()).tickTime(mspt); + // TODO } void setTickSpeedFromPercent(double percent) { diff --git a/src/main/java/com/connorcode/sigmautils/modules/server/AutoTradeCycle.java b/src/main/java/com/connorcode/sigmautils/modules/server/AutoTradeCycle.java index b84b943..d352564 100644 --- a/src/main/java/com/connorcode/sigmautils/modules/server/AutoTradeCycle.java +++ b/src/main/java/com/connorcode/sigmautils/modules/server/AutoTradeCycle.java @@ -10,24 +10,25 @@ import com.connorcode.sigmautils.event.misc.GameLifecycle; import com.connorcode.sigmautils.event.network.PacketReceiveEvent; import com.connorcode.sigmautils.event.render.EntityRender; -import com.connorcode.sigmautils.mixin.ScreenAccessor; import com.connorcode.sigmautils.module.DocumentedEnum; import com.connorcode.sigmautils.module.Module; import com.connorcode.sigmautils.module.ModuleInfo; import net.minecraft.client.sound.PositionedSoundInstance; import net.minecraft.enchantment.Enchantment; +import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.passive.VillagerEntity; -import net.minecraft.item.EnchantedBookItem; import net.minecraft.item.Item; +import net.minecraft.item.Items; import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket; import net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket; import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket; import net.minecraft.network.packet.s2c.play.EntityTrackerUpdateS2CPacket; import net.minecraft.network.packet.s2c.play.SetTradeOffersS2CPacket; import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryKeys; import net.minecraft.sound.SoundEvents; import net.minecraft.util.Hand; -import net.minecraft.util.Identifier; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; @@ -145,14 +146,14 @@ void onPacketReceive_SetTradeOffers(PacketReceiveEvent packet) { return; } case EnchantedBook -> { - if (!(i.getSellItem().getItem() instanceof EnchantedBookItem data)) continue; - var settingEnchantment = Registries.ENCHANTMENT.getId(this.enchantment.value()); - for (int j = 0; j < data.size(); j++) { - var enchantment = new Identifier(data.getCompound(j).getString("id")); - var enchantmentLev = data.getCompound(j).getInt("lvl"); - if (verbose.value()) info("%s %s", enchantment, enchantmentLev); - if (!enchantment.equals(settingEnchantment) || enchantmentLev < enchantmentLevel.intValue()) - continue; + if (i.getSellItem().getItem() != Items.ENCHANTED_BOOK) continue; + var enchantments = EnchantmentHelper.getEnchantments(i.getSellItem()); + + for (var enchantment : enchantments.getEnchantments()) { + var level = enchantments.getLevel(enchantment); + if (verbose.value()) info("%s %s", enchantment, level); + + if (!enchantment.value().equals(this.enchantment.value()) || level < this.enchantmentLevel.intValue()) continue; info("FOUND ENCHANTMENT"); onFind(); return; @@ -217,23 +218,24 @@ public String type() { } } + class EnchantmentList extends SimpleSelector { public EnchantmentList(DynamicSelectorSetting setting) { - super(setting, Registries.ENCHANTMENT); + super(setting, (Registry) Registries.REGISTRIES.get(RegistryKeys.ENCHANTMENT.getRegistry())); } @Override protected boolean filter(Enchantment resource) { - return !(resource instanceof SwiftSneakEnchantment) && !(resource instanceof SoulSpeedEnchantment); + // TODO: fix +// return !(resource instanceof SwiftSneakEnchantment) && !(resource instanceof SoulSpeedEnchantment); + return false; } @Override public String getDisplay(Enchantment resource) { if (resource == null) return "None"; - var val = resource.getName(1).getString(); - if (val.endsWith(" I")) val = val.substring(0, val.length() - 2); - return val; + return resource.toString(); } @Override @@ -245,7 +247,7 @@ public void onChange(@Nullable Enchantment resource) { AutoTradeCycle.this.enchantmentLevel.min(resource.getMinLevel()) .max(resource.getMaxLevel()) .value(resource.getMaxLevel()); - if (client.currentScreen != null) ((ScreenAccessor) client.currentScreen).invokeClearAndInit(); + if (client.currentScreen != null) client.currentScreen.clearAndInit(); } @Override diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 3ad2b90..c534675 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -30,7 +30,7 @@ "depends": { "fabricloader": ">=0.14.22", "fabric": "*", - "minecraft": "1.20.4" + "minecraft": "1.21" }, "custom": { "modmenu": { diff --git a/src/main/resources/modules/modules.json b/src/main/resources/modules/modules.json index 1351cc9..ff2c601 100644 --- a/src/main/resources/modules/modules.json +++ b/src/main/resources/modules/modules.json @@ -12,7 +12,6 @@ "_interface.NoChatFade", "_interface.NoScoreboardValue", "_interface.PortalInventory", - "_interface.RandomBackground", "_interface.SeeThruLoading", "_interface.SignClickThrough", "_interface.SplashRefresh", diff --git a/src/main/resources/sigma-utils.mixins.json b/src/main/resources/sigma-utils.mixins.json index 4fc2b89..ef30c4b 100644 --- a/src/main/resources/sigma-utils.mixins.json +++ b/src/main/resources/sigma-utils.mixins.json @@ -29,16 +29,13 @@ "EntityMixin", "EntityRenderDispatcherMixin", "EntityRendererMixin", - "EntryListWidgetMixin", "GameMenuScreenMixin", "GameRendererMixin", - "InGameHudAccessor", "InGameHudMixin", "InventoryScreenMixin", "LightmapTextureManagerMixin", "LivingEntityRendererMixin", "LogoDrawerMixin", - "MinecraftClientAccessor", "MinecraftClientMixin", "MouseMixin", "MultiplayerScreenMixin", @@ -48,9 +45,7 @@ "ProfileKeysMixin", "ProgressScreenMixin", "RecipeBookWidgetMixin", - "RenderTickCounterAccessor", "ScreenAccessor", - "ScreenMixin", "SimpleOptionAccessor", "SoundSystemMixin", "SplashTextResourceSupplierMixin", @@ -60,8 +55,7 @@ "WorldMixin", "WorldRendererMixin", "YggdrasilAuthenticationServiceAccessor", - "YggdrasilUserApiServiceMixin", - "modmenu.DescriptionListWidgetMixin" + "YggdrasilUserApiServiceMixin" ], "injectors": { "defaultRequire": 1 diff --git a/src/main/resources/sigma_utils.accesswidener b/src/main/resources/sigma_utils.accesswidener index 59dfed8..2b19001 100644 --- a/src/main/resources/sigma_utils.accesswidener +++ b/src/main/resources/sigma_utils.accesswidener @@ -10,8 +10,10 @@ accessible method net/minecraft/client/gui/screen/option/OptionsScreen createBut ## Gui Stuff ## accessible field net/minecraft/client/gui/screen/Screen drawables Ljava/util/List; extendable method net/minecraft/client/gui/widget/ClickableWidget render (Lnet/minecraft/client/gui/DrawContext;IIF)V +accessible method net/minecraft/client/gui/screen/Screen clearAndInit ()V ## Network Stuff ## +accessible method net/minecraft/client/network/ClientPlayerInteractionManager sendSequencedPacket (Lnet/minecraft/client/world/ClientWorld;Lnet/minecraft/client/network/SequencedPacketCreator;)V ## Map Command ## accessible class net/minecraft/client/render/MapRenderer$MapTexture From c5b0d809c4fb80c29bd98f741b54807f3f66a4a7 Mon Sep 17 00:00:00 2001 From: Connor Slade Date: Fri, 28 Jun 2024 01:25:12 -0400 Subject: [PATCH 05/17] Update CI JDK version --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a08c1bb..47865c4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,7 +5,7 @@ jobs: build: strategy: matrix: - java: [ 17 ] + java: [ 21 ] os: [ ubuntu-latest, windows-latest ] runs-on: ${{ matrix.os }} steps: From 749aba863d61d5d880353e775c13557c061bff49 Mon Sep 17 00:00:00 2001 From: Connor Slade Date: Fri, 28 Jun 2024 01:37:50 -0400 Subject: [PATCH 06/17] Add TODO list so many things (sob emoji) --- todo.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 todo.txt diff --git a/todo.txt b/todo.txt new file mode 100644 index 0000000..576693f --- /dev/null +++ b/todo.txt @@ -0,0 +1,11 @@ +- fix ShowInvisableEntites opacity property +- fix packet stuff (NetworkUtils) +- test auto trade cycle + +- fix fast doll stuff (InventoryScreenMixin) +- fix world render mixin (WorldRenderMixin) +- fix OptionsScreenMixin +- fix ChatHudMixin +- fix CameraMixin +- fix InGameHudMixin +- fix EntityRendererMixin \ No newline at end of file From 84f7fdc80620060b379a935ed963b28b3fd6d241 Mon Sep 17 00:00:00 2001 From: Connor Slade Date: Fri, 28 Jun 2024 14:17:43 -0400 Subject: [PATCH 07/17] Fix mixins --- .../sigmautils/event/render/WorldRender.java | 41 ++--- .../sigmautils/mixin/CameraMixin.java | 31 ++-- .../sigmautils/mixin/ChatHudMixin.java | 31 ++-- .../sigmautils/mixin/EntityRendererMixin.java | 37 ++-- .../sigmautils/mixin/InGameHudMixin.java | 174 ++++++++---------- .../mixin/InventoryScreenMixin.java | 83 +++++---- .../sigmautils/mixin/OptionsScreenMixin.java | 30 +-- .../sigmautils/mixin/WorldRendererMixin.java | 145 +++++++++------ .../modules/misc/CameraDistance.java | 4 +- .../sigmautils/modules/rendering/Titles.java | 10 +- todo.txt | 12 +- 11 files changed, 319 insertions(+), 279 deletions(-) diff --git a/src/main/java/com/connorcode/sigmautils/event/render/WorldRender.java b/src/main/java/com/connorcode/sigmautils/event/render/WorldRender.java index 5e10874..62d5765 100644 --- a/src/main/java/com/connorcode/sigmautils/event/render/WorldRender.java +++ b/src/main/java/com/connorcode/sigmautils/event/render/WorldRender.java @@ -4,56 +4,43 @@ import net.minecraft.client.render.Camera; import net.minecraft.client.render.GameRenderer; import net.minecraft.client.render.LightmapTextureManager; -import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.client.render.RenderTickCounter; import org.joml.Matrix4f; public class WorldRender { public static class PostWorldRenderEvent extends WorldRenderEvent { - public PostWorldRenderEvent(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, - LightmapTextureManager lightmapTextureManager, Matrix4f positionMatrix) { - super(matrices, tickDelta, limitTime, renderBlockOutline, camera, gameRenderer, lightmapTextureManager, positionMatrix); + public PostWorldRenderEvent(RenderTickCounter renderTickCounter, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f positionMatrix, Matrix4f projectionMatrix) { + super(renderTickCounter, renderBlockOutline, camera, gameRenderer, lightmapTextureManager, positionMatrix, projectionMatrix); } } public static class PreWorldRenderEvent extends WorldRenderEvent { - public PreWorldRenderEvent(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, - LightmapTextureManager lightmapTextureManager, Matrix4f positionMatrix) { - super(matrices, tickDelta, limitTime, renderBlockOutline, camera, gameRenderer, lightmapTextureManager, positionMatrix); + public PreWorldRenderEvent(RenderTickCounter renderTickCounter, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f positionMatrix, Matrix4f projectionMatrix) { + super(renderTickCounter, renderBlockOutline, camera, gameRenderer, lightmapTextureManager, positionMatrix, projectionMatrix); } } public static abstract class WorldRenderEvent extends Cancellable { - MatrixStack matrices; - float tickDelta; - long limitTime; + RenderTickCounter renderTickCounter; boolean renderBlockOutline; Camera camera; GameRenderer gameRenderer; LightmapTextureManager lightmapTextureManager; Matrix4f positionMatrix; + Matrix4f projectionMatrix; - public WorldRenderEvent(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, - LightmapTextureManager lightmapTextureManager, Matrix4f positionMatrix) { - this.matrices = matrices; - this.tickDelta = tickDelta; - this.limitTime = limitTime; + public WorldRenderEvent(RenderTickCounter renderTickCounter, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f positionMatrix, Matrix4f projectionMatrix) { + this.renderTickCounter = renderTickCounter; this.renderBlockOutline = renderBlockOutline; this.camera = camera; this.gameRenderer = gameRenderer; this.lightmapTextureManager = lightmapTextureManager; this.positionMatrix = positionMatrix; + this.projectionMatrix = projectionMatrix; } - public MatrixStack getMatrices() { - return matrices; - } - - public float getTickDelta() { - return tickDelta; - } - - public long getLimitTime() { - return limitTime; + public RenderTickCounter getRenderTickCounter() { + return renderTickCounter; } public boolean isRenderBlockOutline() { @@ -75,5 +62,9 @@ public LightmapTextureManager getLightmapTextureManager() { public Matrix4f getPositionMatrix() { return positionMatrix; } + + public Matrix4f getProjectionMatrix() { + return projectionMatrix; + } } } diff --git a/src/main/java/com/connorcode/sigmautils/mixin/CameraMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/CameraMixin.java index 3540141..09f6169 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/CameraMixin.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/CameraMixin.java @@ -1,21 +1,26 @@ package com.connorcode.sigmautils.mixin; +import com.connorcode.sigmautils.config.Config; +import com.connorcode.sigmautils.modules.misc.CameraClip; +import com.connorcode.sigmautils.modules.misc.CameraDistance; import net.minecraft.client.render.Camera; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyVariable; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(Camera.class) public class CameraMixin { -// @ModifyVariable(method = "clipToSpace", at = @At("HEAD"), argsOnly = true) -// double clipToSpace(double desiredCameraDistance) { -// if (!Config.getEnabled(CameraDistance.class)) -// return desiredCameraDistance; -// return CameraDistance.getDistance(); -// } -// -// @Inject(method = "clipToSpace", at = @At("HEAD"), cancellable = true) -// void onClipToSpace(double desiredCameraDistance, CallbackInfoReturnable cir) { -// if (!Config.getEnabled(CameraClip.class)) -// return; -// cir.setReturnValue(desiredCameraDistance); -// } + @ModifyVariable(method = "clipToSpace", at = @At("HEAD"), argsOnly = true) + float clipToSpace(float desiredCameraDistance) { + if (!Config.getEnabled(CameraDistance.class)) return desiredCameraDistance; + return CameraDistance.getDistance(); + } + + @Inject(method = "clipToSpace", at = @At("HEAD"), cancellable = true) + void onClipToSpace(float desiredCameraDistance, CallbackInfoReturnable cir) { + if (!Config.getEnabled(CameraClip.class)) return; + cir.setReturnValue(desiredCameraDistance); + } } diff --git a/src/main/java/com/connorcode/sigmautils/mixin/ChatHudMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/ChatHudMixin.java index 3ff8be0..1bf1369 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/ChatHudMixin.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/ChatHudMixin.java @@ -1,23 +1,26 @@ package com.connorcode.sigmautils.mixin; +import com.connorcode.sigmautils.config.Config; +import com.connorcode.sigmautils.modules._interface.NoChatFade; +import com.connorcode.sigmautils.modules.chat.NoMessageHiding; import net.minecraft.client.gui.hud.ChatHud; +import net.minecraft.network.message.MessageSignatureData; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyVariable; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(ChatHud.class) public abstract class ChatHudMixin { - @Shadow - protected abstract boolean isChatFocused(); + @ModifyVariable(method = "render", at = @At("HEAD"), argsOnly = true) + boolean isFocused(boolean focused) { + if (Config.getEnabled(NoChatFade.class)) return true; + return focused; + } -// @Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/ChatHud;isChatFocused()Z")) -// boolean isChatFocused(ChatHud instance) { -// if (Config.getEnabled(NoChatFade.class)) -// return true; -// return isChatFocused(); -// } -// -// @Inject(method = "removeMessage", at = @At("HEAD"), cancellable = true) -// void onHideMessage(MessageSignatureData signature, CallbackInfo ci) { -// if (Config.getEnabled(NoMessageHiding.class)) ci.cancel(); -// } + @Inject(method = "removeMessage", at = @At("HEAD"), cancellable = true) + void onHideMessage(MessageSignatureData signature, CallbackInfo ci) { + if (Config.getEnabled(NoMessageHiding.class)) ci.cancel(); + } } diff --git a/src/main/java/com/connorcode/sigmautils/mixin/EntityRendererMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/EntityRendererMixin.java index fa4f245..5b3a265 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/EntityRendererMixin.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/EntityRendererMixin.java @@ -1,23 +1,32 @@ package com.connorcode.sigmautils.mixin; +import com.connorcode.sigmautils.config.Config; +import com.connorcode.sigmautils.modules.rendering.Deadmau5Ears; +import com.connorcode.sigmautils.modules.rendering.Titles; +import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.entity.EntityRenderer; +import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.Entity; +import net.minecraft.entity.passive.AbstractHorseEntity; +import net.minecraft.entity.passive.TameableEntity; +import net.minecraft.text.Text; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(EntityRenderer.class) public class EntityRendererMixin { - // TODO: fix -// @Redirect(method = "renderLabelIfPresent", at = @At(value = "INVOKE", target = "Ljava/lang/String;equals(Ljava/lang/Object;)Z")) -// private boolean isDeadmau5(String stringA, Object stringB) { -// if (Config.getEnabled(Deadmau5Ears.class)) -// return true; -// return stringA.equals(stringB); -// } -// -// @Inject(method = "renderLabelIfPresent", at = @At("HEAD"), cancellable = true) -// private void renderLabelIfPresent(T entity, Text text, MatrixStack matrices, VertexConsumerProvider vertexConsumers, -// int light, CallbackInfo ci) { -// if (Titles.tamableOwner.value() && (entity instanceof TameableEntity || entity instanceof AbstractHorseEntity)) -// ci.cancel(); -// } + @Redirect(method = "renderLabelIfPresent", at = @At(value = "INVOKE", target = "Ljava/lang/String;equals(Ljava/lang/Object;)Z")) + private boolean isDeadmau5(String stringA, Object stringB) { + if (Config.getEnabled(Deadmau5Ears.class)) return true; + return stringA.equals(stringB); + } + + @Inject(method = "renderLabelIfPresent", at = @At("HEAD"), cancellable = true) + private void renderLabelIfPresent(T entity, Text text, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, float tickDelta, CallbackInfo ci) { + if (Titles.tamableOwner.value() && (entity instanceof TameableEntity || entity instanceof AbstractHorseEntity)) + ci.cancel(); + } } diff --git a/src/main/java/com/connorcode/sigmautils/mixin/InGameHudMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/InGameHudMixin.java index a26770f..c536a54 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/InGameHudMixin.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/InGameHudMixin.java @@ -2,14 +2,18 @@ import com.connorcode.sigmautils.config.Config; import com.connorcode.sigmautils.misc.util.WorldUtils; +import com.connorcode.sigmautils.modules._interface.ChatPosition; import com.connorcode.sigmautils.modules._interface.HotbarPosition; import com.connorcode.sigmautils.modules._interface.NoScoreboardValue; +import com.connorcode.sigmautils.modules.hud.Hud; import com.connorcode.sigmautils.modules.misc.BlockDistance; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.hud.ChatHud; import net.minecraft.client.gui.hud.InGameHud; import net.minecraft.client.render.RenderTickCounter; +import net.minecraft.client.util.math.MatrixStack; import net.minecraft.scoreboard.ScoreboardEntry; import net.minecraft.scoreboard.number.NumberFormat; import net.minecraft.text.MutableText; @@ -19,9 +23,7 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.*; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.Objects; @@ -57,107 +59,91 @@ void onRenderCrosshair(DrawContext ctx, RenderTickCounter renderTickCounter, Cal client.getProfiler().pop(); } - // TODO:fix -// @Inject(method = "render", at = @At("TAIL")) -// void onRender(DrawContext drawContext, RenderTickCounter renderTickCounter, float tickDelta, CallbackInfo ci) { -// if (client.options.hudHidden || !Config.getEnabled(Hud.class)) -// return; -// Hud.renderHud(drawContext); -// } - - // TODO: fix this also -// @Redirect(method = "renderScoreboardSidebar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/font/TextRenderer;getWidth(Ljava/lang/String;)I")) -// int onGetWidth(TextRenderer instance, String text) { -// if (Config.getEnabled(NoScoreboardValue.class)) -// return 0; -// return instance.getWidth(text); -// } - - - // @Redirect(method = "renderScoreboardSidebar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawText(Lnet/minecraft/client/font/TextRenderer;Ljava/lang/String;IIIZ)I")) -// int onDraw(DrawContext instance, TextRenderer textRenderer, String text, int x, int y, int color, boolean shadow) { -// if (Config.getEnabled(NoScoreboardValue.class)) -// return 0; -// return instance.drawText(textRenderer, text, x, y, color, shadow); -// } -// + + @Inject(method = "render", at = @At("TAIL")) + void onRender(DrawContext context, RenderTickCounter tickCounter, CallbackInfo ci) { + if (client.options.hudHidden || !Config.getEnabled(Hud.class)) return; + Hud.renderHud(context); + } + + + @Redirect(method = "renderScoreboardSidebar(Lnet/minecraft/client/gui/DrawContext;Lnet/minecraft/scoreboard/ScoreboardObjective;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/font/TextRenderer;getWidth(Ljava/lang/String;)I")) + int onGetWidth(TextRenderer instance, String text) { + if (Config.getEnabled(NoScoreboardValue.class)) return 0; + return instance.getWidth(text); + } + + @Redirect(method = "method_55439(Lnet/minecraft/scoreboard/Scoreboard;Lnet/minecraft/scoreboard/number/NumberFormat;Lnet/minecraft/scoreboard/ScoreboardEntry;)Lnet/minecraft/client/gui/hud/InGameHud$SidebarEntry;", at = @At(value = "INVOKE", target = "Lnet/minecraft/scoreboard/ScoreboardEntry;formatted(Lnet/minecraft/scoreboard/number/NumberFormat;)Lnet/minecraft/text/MutableText;")) MutableText onToString(ScoreboardEntry instance, NumberFormat format) { if (Config.getEnabled(NoScoreboardValue.class)) return Text.empty(); return instance.formatted(format); } - // TODO: fix this -// @Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/ChatHud;render(Lnet/minecraft/client/gui/DrawContext;IIIZ)V")) -// void onRenderChat(ChatHud instance, DrawContext context, int currentTick, int mouseX, int mouseY, boolean focused) { -// MatrixStack matrices = context.getMatrices(); -// matrices.push(); -// if (Config.getEnabled(ChatPosition.class)) -// matrices.translate(0, -ChatPosition.yPosition.intValue() * client.textRenderer.fontHeight, 0); -// instance.render(context, currentTick, mouseX, mouseY, focused); -// matrices.pop(); -// } + @Redirect(method = "renderChat", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/ChatHud;render(Lnet/minecraft/client/gui/DrawContext;IIIZ)V")) + void onRenderChat(ChatHud instance, DrawContext context, int currentTick, int mouseX, int mouseY, boolean focused) { + MatrixStack matrices = context.getMatrices(); + matrices.push(); + if (Config.getEnabled(ChatPosition.class)) + matrices.translate(0, -ChatPosition.yPosition.intValue() * client.textRenderer.fontHeight, 0); + instance.render(context, currentTick, mouseX, mouseY, focused); + matrices.pop(); + } @Unique int getHotbarPos() { return Config.getEnabled(HotbarPosition.class) ? HotbarPosition.yPosition.intValue() : 0; } - // todo: fix -// // Modified from https://github.com/yurisuika/Raise -// @ModifyArg(method = "renderHotbar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawGuiTexture(Lnet/minecraft/util/Identifier;IIII)V"), index = 2) -// private int modifyHotbar(int value) { -// return value - getHotbarPos(); -// } -// -//// @ModifyArg(method = "renderHotbar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawGuiTexture(Lnet/minecraft/util/Identifier;IIII)V", ordinal = 1), index = 2) -//// private int modifySelectorHeight(int value) { -//// return value + 2; -//// } -// -// @ModifyArg(method = "renderHotbar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/InGameHud;renderHotbarItem(Lnet/minecraft/client/gui/DrawContext;IIFLnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/item/ItemStack;I)V"), index = 2) -// private int modifyItem(int value) { -// return value - getHotbarPos(); -// } -// -// @ModifyVariable(method = "renderMountJumpBar", at = @At(value = "STORE"), ordinal = 1) -// private int modifyJumpBar(int value) { -// return value - getHotbarPos(); -// } -// -// @ModifyArg(method = "renderExperienceBar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawGuiTexture(Lnet/minecraft/util/Identifier;IIII)V"), index = 2) -// private int modifyExperienceBarBackground(int value) { -// return value - getHotbarPos(); -// } -// -// @ModifyArg(method = "renderExperienceBar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawGuiTexture(Lnet/minecraft/util/Identifier;IIIIIIII)V"), index = 6) -// private int modifyExperienceBar(int value) { -// return value - getHotbarPos(); -// } -// -// @ModifyArg(method = "renderExperienceBar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawText(Lnet/minecraft/client/font/TextRenderer;Ljava/lang/String;IIIZ)I"), index = 3) -// private int modifyXpText(int value) { -// return value - getHotbarPos(); -// } -// -// @ModifyVariable(method = "renderHeldItemTooltip", at = @At(value = "STORE"), ordinal = 2) -// private int modifyHeldItemTooltip(int value) { -// return value - getHotbarPos(); -// } -// -// @ModifyVariable(method = "renderStatusBars", at = @At(value = "STORE"), ordinal = 5) -// private int modifyStatusBars(int value) { -// return value - getHotbarPos(); -// } -// -// @ModifyVariable(method = "renderMountHealth", at = @At(value = "STORE"), ordinal = 2) -// private int modifyMountHealth(int value) { -// return value - getHotbarPos(); -// } -// -// @ModifyArg(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/math/MatrixStack;translate(FFF)V", ordinal = 0), index = 1) -// private float modifyActionbar(float value) { -// return value - getHotbarPos(); -// } -// // End + // Modified from https://github.com/yurisuika/Raise + @ModifyArg(method = "renderHotbar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawGuiTexture(Lnet/minecraft/util/Identifier;IIII)V"), index = 2) + private int modifyHotbar(int value) { + return value - getHotbarPos(); + } + + @ModifyArg(method = "renderHotbar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/InGameHud;renderHotbarItem(Lnet/minecraft/client/gui/DrawContext;IILnet/minecraft/client/render/RenderTickCounter;Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/item/ItemStack;I)V"), index = 2) + private int modifyItem(int value) { + return value - getHotbarPos(); + } + + @ModifyVariable(method = "renderMountJumpBar", at = @At(value = "STORE"), ordinal = 1) + private int modifyJumpBar(int value) { + return value - getHotbarPos(); + } + + @ModifyArg(method = "renderExperienceBar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawGuiTexture(Lnet/minecraft/util/Identifier;IIII)V"), index = 2) + private int modifyExperienceBarBackground(int value) { + return value - getHotbarPos(); + } + + @ModifyArg(method = "renderExperienceBar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawGuiTexture(Lnet/minecraft/util/Identifier;IIIIIIII)V"), index = 6) + private int modifyExperienceBar(int value) { + return value - getHotbarPos(); + } + + @ModifyArg(method = "renderExperienceLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawText(Lnet/minecraft/client/font/TextRenderer;Ljava/lang/String;IIIZ)I"), index = 3) + private int modifyXpText(int value) { + return value - getHotbarPos(); + } + + @ModifyVariable(method = "renderHeldItemTooltip", at = @At(value = "STORE"), ordinal = 2) + private int modifyHeldItemTooltip(int value) { + return value - getHotbarPos(); + } + + @ModifyVariable(method = "renderStatusBars", at = @At(value = "STORE"), ordinal = 5) + private int modifyStatusBars(int value) { + return value - getHotbarPos(); + } + + @ModifyVariable(method = "renderMountHealth", at = @At(value = "STORE"), ordinal = 2) + private int modifyMountHealth(int value) { + return value - getHotbarPos(); + } + + @ModifyArg(method = "renderHotbar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/math/MatrixStack;translate(FFF)V", ordinal = 0), index = 1) + private float modifyActionbar(float value) { + return value - getHotbarPos(); + } + // End } diff --git a/src/main/java/com/connorcode/sigmautils/mixin/InventoryScreenMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/InventoryScreenMixin.java index 5ed672d..cb333f6 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/InventoryScreenMixin.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/InventoryScreenMixin.java @@ -1,12 +1,24 @@ package com.connorcode.sigmautils.mixin; +import com.connorcode.sigmautils.SigmaUtils; +import com.connorcode.sigmautils.modules._interface.UiTweaks; +import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.ingame.AbstractInventoryScreen; import net.minecraft.client.gui.screen.ingame.InventoryScreen; import net.minecraft.client.gui.screen.recipebook.RecipeBookProvider; +import net.minecraft.client.render.entity.EntityRenderDispatcher; +import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.screen.PlayerScreenHandler; import net.minecraft.text.Text; +import org.joml.Quaternionf; +import org.joml.Vector3f; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @Mixin(InventoryScreen.class) public abstract class InventoryScreenMixin extends AbstractInventoryScreen implements RecipeBookProvider { @@ -14,41 +26,38 @@ public InventoryScreenMixin(PlayerScreenHandler screenHandler, PlayerInventory p super(screenHandler, playerInventory, text); } -// @Redirect(method = "drawEntity(Lnet/minecraft/client/gui/DrawContext;IIIIIFFFLnet/minecraft/entity/LivingEntity;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;enableScissor(IIII)V")) -// private static void onEnableScissor(DrawContext instance, int x1, int y1, int x2, int y2) { -// if (!UiTweaks.unMaskedDoll()) instance.enableScissor(x1, y1, x2, y2); -// } -// -// @Redirect(method = "drawEntity(Lnet/minecraft/client/gui/DrawContext;IIIIIFFFLnet/minecraft/entity/LivingEntity;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;disableScissor()V")) -// private static void onDisableScissor(DrawContext instance) { -// if (!UiTweaks.unMaskedDoll()) instance.disableScissor(); -// } -// -// @Inject(method = "drawEntity(Lnet/minecraft/client/gui/DrawContext;FFILorg/joml/Vector3f;Lorg/joml/Quaternionf;Lorg/joml/Quaternionf;Lnet/minecraft/entity/LivingEntity;)V", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;runAsFancy(Ljava/lang/Runnable;)V"), locals = LocalCapture.CAPTURE_FAILHARD) -// private static void onDrawEntity(DrawContext context, float x, float y, int size, Vector3f vector3f, -// Quaternionf quaternionf, Quaternionf quaternionf2, LivingEntity entity, -// CallbackInfo ci, EntityRenderDispatcher entityRenderDispatcher) { -// if (!UiTweaks.fastDoll()) return; -// var tickDelta = SigmaUtils.client.getRenderTickCounter().getTickDelta(true); -// -// float h = entity.prevBodyYaw; -// float i = entity.prevYaw; -// float j = entity.prevPitch; -// float k = entity.prevHeadYaw; -// entity.prevBodyYaw = entity.bodyYaw; -// entity.prevYaw = entity.getYaw(); -// entity.prevPitch = entity.getPitch(); -// entity.prevHeadYaw = entity.headYaw; -// entityRenderDispatcher.render(entity, 0.0, 0.0, 0.0, 0.0F, tickDelta, context.getMatrices(), -// context.getVertexConsumers(), 0xF000F0); -// entity.prevBodyYaw = h; -// entity.prevYaw = i; -// entity.prevPitch = j; -// entity.prevHeadYaw = k; -// } -// -// @Redirect(method = "drawEntity(Lnet/minecraft/client/gui/DrawContext;FFILorg/joml/Vector3f;Lorg/joml/Quaternionf;Lorg/joml/Quaternionf;Lnet/minecraft/entity/LivingEntity;)V", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;runAsFancy(Ljava/lang/Runnable;)V")) -// private static void onRender(Runnable runnable) { -// if (!UiTweaks.fastDoll()) runnable.run(); -// } + @Redirect(method = "drawEntity(Lnet/minecraft/client/gui/DrawContext;IIIIIFFFLnet/minecraft/entity/LivingEntity;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;enableScissor(IIII)V")) + private static void onEnableScissor(DrawContext instance, int x1, int y1, int x2, int y2) { + if (!UiTweaks.unMaskedDoll()) instance.enableScissor(x1, y1, x2, y2); + } + + @Redirect(method = "drawEntity(Lnet/minecraft/client/gui/DrawContext;IIIIIFFFLnet/minecraft/entity/LivingEntity;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;disableScissor()V")) + private static void onDisableScissor(DrawContext instance) { + if (!UiTweaks.unMaskedDoll()) instance.disableScissor(); + } + + @Inject(method = "drawEntity(Lnet/minecraft/client/gui/DrawContext;FFFLorg/joml/Vector3f;Lorg/joml/Quaternionf;Lorg/joml/Quaternionf;Lnet/minecraft/entity/LivingEntity;)V", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;runAsFancy(Ljava/lang/Runnable;)V"), locals = LocalCapture.CAPTURE_FAILHARD) + private static void onDrawEntity(DrawContext context, float x, float y, float size, Vector3f vector3f, Quaternionf quaternionf, Quaternionf quaternionf2, LivingEntity entity, CallbackInfo ci, EntityRenderDispatcher entityRenderDispatcher) { + if (!UiTweaks.fastDoll()) return; + var tickDelta = SigmaUtils.client.getRenderTickCounter().getTickDelta(true); + + float h = entity.prevBodyYaw; + float i = entity.prevYaw; + float j = entity.prevPitch; + float k = entity.prevHeadYaw; + entity.prevBodyYaw = entity.bodyYaw; + entity.prevYaw = entity.getYaw(); + entity.prevPitch = entity.getPitch(); + entity.prevHeadYaw = entity.headYaw; + entityRenderDispatcher.render(entity, 0.0, 0.0, 0.0, 0.0F, tickDelta, context.getMatrices(), context.getVertexConsumers(), 0xF000F0); + entity.prevBodyYaw = h; + entity.prevYaw = i; + entity.prevPitch = j; + entity.prevHeadYaw = k; + } + + @Redirect(method = "drawEntity(Lnet/minecraft/client/gui/DrawContext;FFFLorg/joml/Vector3f;Lorg/joml/Quaternionf;Lorg/joml/Quaternionf;Lnet/minecraft/entity/LivingEntity;)V", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;runAsFancy(Ljava/lang/Runnable;)V")) + private static void onRender(Runnable runnable) { + if (!UiTweaks.fastDoll()) runnable.run(); + } } diff --git a/src/main/java/com/connorcode/sigmautils/mixin/OptionsScreenMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/OptionsScreenMixin.java index f7a724b..2f56846 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/OptionsScreenMixin.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/OptionsScreenMixin.java @@ -1,10 +1,17 @@ package com.connorcode.sigmautils.mixin; +import com.connorcode.sigmautils.config.Config; +import com.connorcode.sigmautils.modules._interface.UiTweaks; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.option.OptionsScreen; +import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.text.Text; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @Mixin(OptionsScreen.class) public class OptionsScreenMixin extends Screen { @@ -12,15 +19,16 @@ protected OptionsScreenMixin(Text title) { super(title); } -// @Inject(method = "init", at = @At("TAIL"), locals = LocalCapture.CAPTURE_FAILHARD) -// void onButtonRender(CallbackInfo ci, GridWidget gridWidget, GridWidget.Adder adder) { -// if (!Config.getEnabled(UiTweaks.class) || !UiTweaks.audioMuteButton.value()) return; -// -// var x = this.width / 2 + 160; -// var y = this.height / 6 + 42; -// addDrawableChild(ButtonWidget.builder(Text.of(UiTweaks.muted ? "U" : "M"), button -> { -// UiTweaks.muted ^= true; -// button.setMessage(Text.of(UiTweaks.muted ? "U" : "M")); -// }).position(x, y).size(20, 20).build()); -// } + @Inject(method = "init", at = @At("TAIL"), locals = LocalCapture.CAPTURE_FAILHARD) + void onButtonRender(CallbackInfo ci) { + if (!Config.getEnabled(UiTweaks.class) || !UiTweaks.audioMuteButton.value()) return; + + // TODO: handle resizing of window + var x = this.width / 2 + 160; + var y = this.height / 6 + 42; + addDrawableChild(ButtonWidget.builder(Text.of(UiTweaks.muted ? "U" : "M"), button -> { + UiTweaks.muted ^= true; + button.setMessage(Text.of(UiTweaks.muted ? "U" : "M")); + }).position(x, y).size(20, 20).build()); + } } diff --git a/src/main/java/com/connorcode/sigmautils/mixin/WorldRendererMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/WorldRendererMixin.java index 73a8443..f146432 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/WorldRendererMixin.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/WorldRendererMixin.java @@ -1,67 +1,94 @@ package com.connorcode.sigmautils.mixin; -import net.minecraft.client.render.WorldRenderer; +import com.connorcode.sigmautils.SigmaUtils; +import com.connorcode.sigmautils.config.Config; +import com.connorcode.sigmautils.event.render.EntityRender; +import com.connorcode.sigmautils.event.render.WorldBorderRender; +import com.connorcode.sigmautils.event.render.WorldRender; +import com.connorcode.sigmautils.modules.misc.NoGlobalSounds; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gl.VertexBuffer; +import net.minecraft.client.render.*; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.entity.Entity; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvent; +import net.minecraft.util.math.BlockPos; +import org.jetbrains.annotations.Nullable; +import org.joml.Matrix4f; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +import java.util.Objects; + +import static net.minecraft.sound.SoundEvents.*; @Mixin(WorldRenderer.class) public abstract class WorldRendererMixin { -// int color; -// @Shadow -// @Nullable -// private ClientWorld world; -// -// @Shadow -// @Nullable -// private VertexBuffer lightSkyBuffer; -// -// @Inject(method = "processGlobalEvent", at = @At("HEAD")) -// void onProcessGlobalEvent(int eventId, BlockPos pos, int data, CallbackInfo ci) { -// if (!Config.getEnabled(NoGlobalSounds.class)) return; -// SoundEvent sound = switch (eventId) { -// case 1023 -> ENTITY_WITHER_SPAWN; -// case 1038 -> BLOCK_END_PORTAL_SPAWN; -// case 1028 -> ENTITY_ENDER_DRAGON_DEATH; -// default -> null; -// }; -// -// if (sound == null || NoGlobalSounds.disabled(eventId)) -// return; -// Objects.requireNonNull(world).playSoundAtBlockCenter(pos, sound, SoundCategory.HOSTILE, 1.0F, 1.0F, false); -// } -// -// @Inject(method = "renderWorldBorder", at = @At("HEAD"), cancellable = true) -// void onRenderWorldBorder(Camera camera, CallbackInfo ci) { -// var event = new WorldBorderRender(camera); -// SigmaUtils.eventBus.post(event); -// if (event.isCancelled()) ci.cancel(); -// } -// -// @Inject(method = "render", at = @At("HEAD"), cancellable = true) -// void onRender(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f positionMatrix, CallbackInfo ci) { -// var event = new WorldRender.PreWorldRenderEvent(matrices, tickDelta, limitTime, renderBlockOutline, camera, gameRenderer, lightmapTextureManager, positionMatrix); -// SigmaUtils.eventBus.post(event); -// if (event.isCancelled()) ci.cancel(); -// } -// -// @Inject(method = "render", at = @At("RETURN"), cancellable = true) -// void onPostRender(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f positionMatrix, CallbackInfo ci) { -// var event = new WorldRender.PostWorldRenderEvent(matrices, tickDelta, limitTime, renderBlockOutline, camera, gameRenderer, lightmapTextureManager, positionMatrix); -// SigmaUtils.eventBus.post(event); -// if (event.isCancelled()) ci.cancel(); -// } -// -// @Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;hasOutline(Lnet/minecraft/entity/Entity;)Z")) -// boolean onHasOutline(MinecraftClient instance, Entity entity) { -// var event = -// new EntityRender.EntityHighlightEvent(entity, instance.hasOutline(entity), entity.getTeamColorValue()); -// SigmaUtils.eventBus.post(event); -// this.color = event.getColor(); -// return event.hasOutline(); -// } -// -// @Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;getTeamColorValue()I")) -// int onGetTeamColorValue(Entity instance) { -// return this.color; -// } + int color; + + @Shadow + @Nullable + private ClientWorld world; + + @Shadow + @Nullable + private VertexBuffer lightSkyBuffer; + + @Shadow + private int ticks; + + @Inject(method = "processGlobalEvent", at = @At("HEAD")) + void onProcessGlobalEvent(int eventId, BlockPos pos, int data, CallbackInfo ci) { + if (!Config.getEnabled(NoGlobalSounds.class)) return; + SoundEvent sound = switch (eventId) { + case 1023 -> ENTITY_WITHER_SPAWN; + case 1038 -> BLOCK_END_PORTAL_SPAWN; + case 1028 -> ENTITY_ENDER_DRAGON_DEATH; + default -> null; + }; + + if (sound == null || NoGlobalSounds.disabled(eventId)) return; + Objects.requireNonNull(world).playSoundAtBlockCenter(pos, sound, SoundCategory.HOSTILE, 1.0F, 1.0F, false); + } + + @Inject(method = "renderWorldBorder", at = @At("HEAD"), cancellable = true) + void onRenderWorldBorder(Camera camera, CallbackInfo ci) { + var event = new WorldBorderRender(camera); + SigmaUtils.eventBus.post(event); + if (event.isCancelled()) ci.cancel(); + } + + @Inject(method = "render", at = @At("HEAD"), cancellable = true) + void onRender(RenderTickCounter tickCounter, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f positionMatrix, Matrix4f projectionMatrix, CallbackInfo ci) { + var event = new WorldRender.PreWorldRenderEvent(tickCounter, renderBlockOutline, camera, gameRenderer, lightmapTextureManager, positionMatrix, projectionMatrix); + SigmaUtils.eventBus.post(event); + if (event.isCancelled()) ci.cancel(); + } + + @Inject(method = "render", at = @At("RETURN"), cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD) + void onPostRender(RenderTickCounter tickCounter, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f positionMatrix, Matrix4f projectionMatrix, CallbackInfo ci) { + var event = new WorldRender.PostWorldRenderEvent(tickCounter, renderBlockOutline, camera, gameRenderer, lightmapTextureManager, positionMatrix, projectionMatrix); + SigmaUtils.eventBus.post(event); + if (event.isCancelled()) ci.cancel(); + } + + @Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;hasOutline(Lnet/minecraft/entity/Entity;)Z")) + boolean onHasOutline(MinecraftClient instance, Entity entity) { + var event = new EntityRender.EntityHighlightEvent(entity, instance.hasOutline(entity), entity.getTeamColorValue()); + SigmaUtils.eventBus.post(event); + this.color = event.getColor(); + return event.hasOutline(); + } + + @Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;getTeamColorValue()I")) + int onGetTeamColorValue(Entity instance) { + return this.color; + } } diff --git a/src/main/java/com/connorcode/sigmautils/modules/misc/CameraDistance.java b/src/main/java/com/connorcode/sigmautils/modules/misc/CameraDistance.java index 2b181e2..0fb8894 100644 --- a/src/main/java/com/connorcode/sigmautils/modules/misc/CameraDistance.java +++ b/src/main/java/com/connorcode/sigmautils/modules/misc/CameraDistance.java @@ -24,8 +24,8 @@ public class CameraDistance extends Module { public static BoolSetting scrollZoom = new BoolSetting(CameraDistance.class, "Scroll Zoom").description( "Makes the scroll wheal modify the distance when in F1 mode.").build(); - public static double getDistance() { - return distance.value() + Math.signum(distanceMod) * Math.pow(Math.abs(distanceMod), 1.2); + public static float getDistance() { + return (float) (distance.value() + Math.signum(distanceMod) * Math.pow(Math.abs(distanceMod), 1.2)); } @EventHandler diff --git a/src/main/java/com/connorcode/sigmautils/modules/rendering/Titles.java b/src/main/java/com/connorcode/sigmautils/modules/rendering/Titles.java index d365b2f..cbccd6c 100644 --- a/src/main/java/com/connorcode/sigmautils/modules/rendering/Titles.java +++ b/src/main/java/com/connorcode/sigmautils/modules/rendering/Titles.java @@ -35,7 +35,7 @@ public class Titles extends Module { .description("Shows the owner of a tamable entity") .category("Titles") .build(); - private static final NumberSetting scale = new NumberSetting(Titles.class, "Scale", 0.5, 5).value(2).build(); + private static final NumberSetting scale = new NumberSetting(Titles.class, "Scale", 0.5, 5).value(1).build(); private static final NumberSetting yOffset = new NumberSetting(Titles.class, "Y Offset", 0, 3).value(0.25) .description("Number of blocks to offset the text from the entity") .build(); @@ -78,6 +78,7 @@ public class Titles extends Module { @EventHandler void onPostWorldRender(WorldRender.PostWorldRenderEvent event) { + var tickDelta = event.getRenderTickCounter().getTickDelta(true); var itemTitles = new ArrayList(); assert client.world != null; @@ -116,7 +117,7 @@ void onPostWorldRender(WorldRender.PostWorldRenderEvent event) { var name = e.getCustomName(); if (name != null) lines.add(name); lines.add(Text.of(textColor.value().code() + "Owner: " + Util.uuidToName(owner).orElse(owner.toString()))); - WorldRenderUtils.renderLines(lines, entityPos(e, event.getTickDelta()).add(0, 1.5 + yOffset.value(), 0), scale.value(), false); + WorldRenderUtils.renderLines(lines, entityPos(e, tickDelta).add(0, 1.5 + yOffset.value(), 0), scale.value(), false); } } } @@ -126,12 +127,13 @@ void onPostWorldRender(WorldRender.PostWorldRenderEvent event) { if (itemCountdown.value()) text += timeFormat.value().format(i.toDespawn()); if (itemStackCount.value()) text += " ×" + i.count; - WorldRenderUtils.renderText(Text.of(text), entityPos(i.lastPos, i.pos, event.getTickDelta()).add(0, yOffset.value(), 0), scale.value(), false); + WorldRenderUtils.renderText(Text.of(text), entityPos(i.lastPos, i.pos, tickDelta).add(0, yOffset.value(), 0), scale.value(), false); } } void renderText(Text text, Entity pos, WorldRender.WorldRenderEvent event, double offset) { - WorldRenderUtils.renderText(text, entityPos(pos, event.getTickDelta()).add(0, offset + yOffset.value(), 0), scale.value(), false); + var tickDelta = event.getRenderTickCounter().getTickDelta(true); + WorldRenderUtils.renderText(text, entityPos(pos, tickDelta).add(0, offset + yOffset.value(), 0), scale.value(), false); } public enum TimeFormat { diff --git a/todo.txt b/todo.txt index 576693f..4a15b9e 100644 --- a/todo.txt +++ b/todo.txt @@ -2,10 +2,10 @@ - fix packet stuff (NetworkUtils) - test auto trade cycle -- fix fast doll stuff (InventoryScreenMixin) -- fix world render mixin (WorldRenderMixin) +x fix fast doll stuff (InventoryScreenMixin) +x fix world render mixin (WorldRenderMixin) - fix OptionsScreenMixin -- fix ChatHudMixin -- fix CameraMixin -- fix InGameHudMixin -- fix EntityRendererMixin \ No newline at end of file +x fix ChatHudMixin +x fix CameraMixin +x fix InGameHudMixin +x fix EntityRendererMixin \ No newline at end of file From 38eff3e305b84957947f1cb9681709688bee3c74 Mon Sep 17 00:00:00 2001 From: Connor Slade Date: Fri, 28 Jun 2024 16:38:00 -0400 Subject: [PATCH 08/17] Fix HUD mixins --- .../sigmautils/mixin/InGameHudMixin.java | 60 +++++-------------- todo.txt | 3 + 2 files changed, 17 insertions(+), 46 deletions(-) diff --git a/src/main/java/com/connorcode/sigmautils/mixin/InGameHudMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/InGameHudMixin.java index c536a54..452a2dc 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/InGameHudMixin.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/InGameHudMixin.java @@ -23,7 +23,10 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.*; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyArg; +import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.Objects; @@ -95,55 +98,20 @@ int getHotbarPos() { return Config.getEnabled(HotbarPosition.class) ? HotbarPosition.yPosition.intValue() : 0; } - // Modified from https://github.com/yurisuika/Raise - @ModifyArg(method = "renderHotbar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawGuiTexture(Lnet/minecraft/util/Identifier;IIII)V"), index = 2) - private int modifyHotbar(int value) { - return value - getHotbarPos(); + @Inject(method = "renderMainHud", at = @At("HEAD")) + void onRenderMainHudHead(DrawContext context, RenderTickCounter tickCounter, CallbackInfo ci) { + context.getMatrices().push(); + ; + context.getMatrices().translate(0, -getHotbarPos(), 0); } - @ModifyArg(method = "renderHotbar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/InGameHud;renderHotbarItem(Lnet/minecraft/client/gui/DrawContext;IILnet/minecraft/client/render/RenderTickCounter;Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/item/ItemStack;I)V"), index = 2) - private int modifyItem(int value) { - return value - getHotbarPos(); - } - - @ModifyVariable(method = "renderMountJumpBar", at = @At(value = "STORE"), ordinal = 1) - private int modifyJumpBar(int value) { - return value - getHotbarPos(); - } - - @ModifyArg(method = "renderExperienceBar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawGuiTexture(Lnet/minecraft/util/Identifier;IIII)V"), index = 2) - private int modifyExperienceBarBackground(int value) { - return value - getHotbarPos(); - } - - @ModifyArg(method = "renderExperienceBar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawGuiTexture(Lnet/minecraft/util/Identifier;IIIIIIII)V"), index = 6) - private int modifyExperienceBar(int value) { - return value - getHotbarPos(); + @Inject(method = "renderMainHud", at = @At("TAIL")) + void onRenderMainHudTail(DrawContext context, RenderTickCounter tickCounter, CallbackInfo ci) { + context.getMatrices().pop(); } @ModifyArg(method = "renderExperienceLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawText(Lnet/minecraft/client/font/TextRenderer;Ljava/lang/String;IIIZ)I"), index = 3) - private int modifyXpText(int value) { - return value - getHotbarPos(); - } - - @ModifyVariable(method = "renderHeldItemTooltip", at = @At(value = "STORE"), ordinal = 2) - private int modifyHeldItemTooltip(int value) { - return value - getHotbarPos(); - } - - @ModifyVariable(method = "renderStatusBars", at = @At(value = "STORE"), ordinal = 5) - private int modifyStatusBars(int value) { - return value - getHotbarPos(); - } - - @ModifyVariable(method = "renderMountHealth", at = @At(value = "STORE"), ordinal = 2) - private int modifyMountHealth(int value) { - return value - getHotbarPos(); - } - - @ModifyArg(method = "renderHotbar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/math/MatrixStack;translate(FFF)V", ordinal = 0), index = 1) - private float modifyActionbar(float value) { - return value - getHotbarPos(); + int onRenderExperienceLevelHead(int y) { + return y - getHotbarPos(); } - // End } diff --git a/todo.txt b/todo.txt index 4a15b9e..7e71328 100644 --- a/todo.txt +++ b/todo.txt @@ -1,6 +1,9 @@ - fix ShowInvisableEntites opacity property - fix packet stuff (NetworkUtils) - test auto trade cycle +- fix tick speed +- Update packet registry +- fix map border x fix fast doll stuff (InventoryScreenMixin) x fix world render mixin (WorldRenderMixin) From 6a08a0a13f59aa7b015e6ebb2a48434751cfcd00 Mon Sep 17 00:00:00 2001 From: Connor Slade Date: Fri, 28 Jun 2024 16:39:19 -0400 Subject: [PATCH 09/17] Update readme for Minecraft 1.21 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 090c3b1..7e9c7b9 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # SigmaUtils ![build](https://github.com/Basicprogrammer10/SigmaUtils/actions/workflows/build.yml/badge.svg) ![GitHub release (latest SemVer including pre-releases)](https://img.shields.io/github/v/release/Basicprogrammer10/SigmaUtils?include_prereleases) ![GitHub all releases](https://img.shields.io/github/downloads/Basicprogrammer10/SigmaUtils/total) -Requires: [Minecraft 1.20.4](https://minecraft.wiki/w/Java_Edition_1.20.4) [Fabric API](https://modrinth.com/mod/fabric-api/version/0.92.0+1.20.4) +Requires: [Minecraft 1.21](https://minecraft.wiki/w/Java_Edition_1.21) [Fabric API](https://modrinth.com/mod/fabric-api) -SigmaUtils is a utility mod for Minecraft 1.20.4. +SigmaUtils is a utility mod for Minecraft 1.21. It is made up of 'modules', which are discrete features that can be toggled and configured. By default, SigmaUtils changes nothing about the game, except adding a button to the title screen to open the config GUI. From b27c42c277cd820241c68dc73204474fd462a001 Mon Sep 17 00:00:00 2001 From: Connor Slade Date: Fri, 28 Jun 2024 18:40:22 -0400 Subject: [PATCH 10/17] Working auto trade cycle --- .../mixin/RenderTickCounter$DynamicMixin.java | 17 +++ .../modules/server/AutoTradeCycle.java | 112 ++++++++++-------- src/main/resources/sigma-utils.mixins.json | 1 + 3 files changed, 79 insertions(+), 51 deletions(-) create mode 100644 src/main/java/com/connorcode/sigmautils/mixin/RenderTickCounter$DynamicMixin.java diff --git a/src/main/java/com/connorcode/sigmautils/mixin/RenderTickCounter$DynamicMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/RenderTickCounter$DynamicMixin.java new file mode 100644 index 0000000..032e85f --- /dev/null +++ b/src/main/java/com/connorcode/sigmautils/mixin/RenderTickCounter$DynamicMixin.java @@ -0,0 +1,17 @@ +package com.connorcode.sigmautils.mixin; + +import com.connorcode.sigmautils.config.Config; +import com.connorcode.sigmautils.modules.misc.TickSpeed; +import net.minecraft.client.render.RenderTickCounter; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; + +@Mixin(RenderTickCounter.Dynamic.class) +public class RenderTickCounter$DynamicMixin { + @ModifyArg(method = "beginRenderTick(J)I", at = @At(value = "INVOKE", target = "Lit/unimi/dsi/fastutil/floats/FloatUnaryOperator;apply(F)F", remap = false)) + float onBeginRenderTick(float v) { + if (Config.getEnabled(TickSpeed.class)) return (float) TickSpeed.mspt.value(); + return v; + } +} diff --git a/src/main/java/com/connorcode/sigmautils/modules/server/AutoTradeCycle.java b/src/main/java/com/connorcode/sigmautils/modules/server/AutoTradeCycle.java index d352564..2c9e0a6 100644 --- a/src/main/java/com/connorcode/sigmautils/modules/server/AutoTradeCycle.java +++ b/src/main/java/com/connorcode/sigmautils/modules/server/AutoTradeCycle.java @@ -13,21 +13,24 @@ import com.connorcode.sigmautils.module.DocumentedEnum; import com.connorcode.sigmautils.module.Module; import com.connorcode.sigmautils.module.ModuleInfo; +import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.sound.PositionedSoundInstance; import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.enchantment.Enchantments; import net.minecraft.entity.passive.VillagerEntity; import net.minecraft.item.Item; import net.minecraft.item.Items; +import net.minecraft.nbt.NbtElement; import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket; import net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket; import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket; import net.minecraft.network.packet.s2c.play.EntityTrackerUpdateS2CPacket; import net.minecraft.network.packet.s2c.play.SetTradeOffersS2CPacket; import net.minecraft.registry.Registries; -import net.minecraft.registry.Registry; -import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.RegistryKey; import net.minecraft.sound.SoundEvents; +import net.minecraft.text.Text; import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; @@ -37,9 +40,11 @@ import org.jetbrains.annotations.Nullable; import java.util.HashSet; +import java.util.List; import java.util.Objects; import static com.connorcode.sigmautils.SigmaUtils.client; +import static com.connorcode.sigmautils.config.settings.list.SimpleSelector.selector; @ModuleInfo(description = "Automatically cycles a villager's trades until you get the desired trade. " + "To use put a few workstations in your offhand and the tool to break it in your main hand. Enable the module and place the workstation.", @@ -61,7 +66,7 @@ public class AutoTradeCycle extends Module { BoolSetting alertSound = new BoolSetting(AutoTradeCycle.class, "Alert Sound") .description("Play a sound when the trade is found.") .build(); - DynamicSelectorSetting enchantment = + DynamicSelectorSetting> enchantment = new DynamicSelectorSetting<>(AutoTradeCycle.class, "Enchantment", EnchantmentList::new) .description("The enchantments that will stop the cycling.") .category("Enchantment") @@ -131,6 +136,36 @@ void onPacketReceive_EntityTrackerUpdateS2CPacket(PacketReceiveEvent event) { } } + static String enchantName(RegistryKey resource) { + return Text.translatable(resource.getValue().toTranslationKey("enchantment")).getString(); + } + + @EventHandler(priority = Priority.LOW) + void onHighlightEvent(EntityRender.EntityHighlightEvent event) { + if (!enabled || event.getEntity() != villager) return; + event.setHasOutline(true); + event.setColor(0xFFFF00); + } + + void onFind() { + this.disable(); + if (this.alertSound.value()) + client.getSoundManager().play(PositionedSoundInstance.master(SoundEvents.BLOCK_BELL_RESONATE, 1f)); + } + + void breakBlock(BlockPos block) { + var network = Objects.requireNonNull(client.getNetworkHandler()); + network.sendPacket( + new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.START_DESTROY_BLOCK, block, Direction.UP)); + network.sendPacket( + new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.STOP_DESTROY_BLOCK, block, Direction.UP)); + } + + void fail(String format, Object... args) { + error(format, args); + this.disable(); + } + @EventHandler void onPacketReceive_SetTradeOffers(PacketReceiveEvent packet) { if (!enabled || client.player == null || @@ -151,9 +186,10 @@ void onPacketReceive_SetTradeOffers(PacketReceiveEvent packet) { for (var enchantment : enchantments.getEnchantments()) { var level = enchantments.getLevel(enchantment); - if (verbose.value()) info("%s %s", enchantment, level); + var key = enchantment.getKey().orElseThrow(); + if (verbose.value()) info("%s %s", enchantName(key), level); - if (!enchantment.value().equals(this.enchantment.value()) || level < this.enchantmentLevel.intValue()) continue; + if (key != this.enchantment.value() || level < this.enchantmentLevel.intValue()) continue; info("FOUND ENCHANTMENT"); onFind(); return; @@ -167,32 +203,6 @@ void onPacketReceive_SetTradeOffers(PacketReceiveEvent packet) { packet.cancel(); } - @EventHandler(priority = Priority.LOW) - void onHighlightEvent(EntityRender.EntityHighlightEvent event) { - if (!enabled || event.getEntity() != villager) return; - event.setHasOutline(true); - event.setColor(0xFFFF00); - } - - void onFind() { - this.disable(); - if (this.alertSound.value()) - client.getSoundManager().play(PositionedSoundInstance.master(SoundEvents.BLOCK_BELL_RESONATE, 1f)); - } - - void breakBlock(BlockPos block) { - var network = Objects.requireNonNull(client.getNetworkHandler()); - network.sendPacket( - new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.START_DESTROY_BLOCK, block, Direction.UP)); - network.sendPacket( - new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.STOP_DESTROY_BLOCK, block, Direction.UP)); - } - - void fail(String format, Object... args) { - error(format, args); - this.disable(); - } - enum TradeType { @DocumentedEnum("Looks for a specific enchantment on an enchanted book.") EnchantedBook, @@ -218,41 +228,41 @@ public String type() { } } + static class EnchantmentList implements DynamicSelectorSetting.ResourceManager> { + static final List> ENCHANTMENTS = List.of(Enchantments.PROTECTION, Enchantments.FIRE_PROTECTION, Enchantments.FEATHER_FALLING, Enchantments.BLAST_PROTECTION, Enchantments.PROJECTILE_PROTECTION, Enchantments.RESPIRATION, Enchantments.AQUA_AFFINITY, Enchantments.THORNS, Enchantments.DEPTH_STRIDER, Enchantments.FROST_WALKER, Enchantments.BINDING_CURSE, Enchantments.SOUL_SPEED, Enchantments.SWIFT_SNEAK, Enchantments.SHARPNESS, Enchantments.SMITE, Enchantments.BANE_OF_ARTHROPODS, Enchantments.KNOCKBACK, Enchantments.FIRE_ASPECT, Enchantments.LOOTING, Enchantments.SWEEPING_EDGE, Enchantments.EFFICIENCY, Enchantments.SILK_TOUCH, Enchantments.UNBREAKING, Enchantments.FORTUNE, Enchantments.POWER, Enchantments.PUNCH, Enchantments.FLAME, Enchantments.INFINITY, Enchantments.LUCK_OF_THE_SEA, Enchantments.LURE, Enchantments.LOYALTY, Enchantments.IMPALING, Enchantments.RIPTIDE, Enchantments.CHANNELING, Enchantments.MULTISHOT, Enchantments.QUICK_CHARGE, Enchantments.PIERCING, Enchantments.DENSITY, Enchantments.BREACH, Enchantments.WIND_BURST, Enchantments.MENDING, Enchantments.VANISHING_CURSE); - class EnchantmentList extends SimpleSelector { + DynamicSelectorSetting> setting; - public EnchantmentList(DynamicSelectorSetting setting) { - super(setting, (Registry) Registries.REGISTRIES.get(RegistryKeys.ENCHANTMENT.getRegistry())); + public EnchantmentList(DynamicSelectorSetting> setting) { + this.setting = setting; } @Override - protected boolean filter(Enchantment resource) { - // TODO: fix -// return !(resource instanceof SwiftSneakEnchantment) && !(resource instanceof SoulSpeedEnchantment); - return false; + public List> getAllResources() { + return ENCHANTMENTS; } @Override - public String getDisplay(Enchantment resource) { + public String getDisplay(@Nullable RegistryKey resource) { if (resource == null) return "None"; - return resource.toString(); + return enchantName(resource); } @Override - public void onChange(@Nullable Enchantment resource) { - if (resource == null) { - AutoTradeCycle.this.enchantmentLevel.min(1).max(1).value(1); - return; - } - AutoTradeCycle.this.enchantmentLevel.min(resource.getMinLevel()) - .max(resource.getMaxLevel()) - .value(resource.getMaxLevel()); - if (client.currentScreen != null) client.currentScreen.clearAndInit(); + public boolean renderSelector(RegistryKey resource, Screen screen, int x, int y) { + if (setting.value() == resource) return false; + selector(setting, resource, getDisplay(resource), screen, x, y, 0); + return true; } @Override - public String type() { - return "Enchantment"; + public NbtElement serialize(@Nullable RegistryKey resources) { + return null; + } + + @Override + public @Nullable RegistryKey deserialize(NbtElement nbt) { + return null; } } } diff --git a/src/main/resources/sigma-utils.mixins.json b/src/main/resources/sigma-utils.mixins.json index ef30c4b..b95c6f2 100644 --- a/src/main/resources/sigma-utils.mixins.json +++ b/src/main/resources/sigma-utils.mixins.json @@ -45,6 +45,7 @@ "ProfileKeysMixin", "ProgressScreenMixin", "RecipeBookWidgetMixin", + "RenderTickCounter$DynamicMixin", "ScreenAccessor", "SimpleOptionAccessor", "SoundSystemMixin", From b36f18e93d1941870555c7011d08f1dda15a8a05 Mon Sep 17 00:00:00 2001 From: Connor Slade Date: Fri, 28 Jun 2024 19:33:17 -0400 Subject: [PATCH 11/17] Working packet cancler --- .../connorcode/sigmautils/commands/Dump.java | 18 -- .../sigmautils/config/ConfigGui.java | 6 +- .../config/settings/list/PacketList.java | 59 +++--- .../sigmautils/misc/util/NetworkUtils.java | 45 +---- .../sigmautils/mixin/EntityMixin.java | 6 +- .../modules/misc/PacketCanceler.java | 18 +- .../rendering/ShowInvisibleEntities.java | 10 +- .../resources/assets/sigma-utils/packets.txt | 189 ------------------ todo.txt | 8 +- 9 files changed, 59 insertions(+), 300 deletions(-) delete mode 100644 src/main/resources/assets/sigma-utils/packets.txt diff --git a/src/main/java/com/connorcode/sigmautils/commands/Dump.java b/src/main/java/com/connorcode/sigmautils/commands/Dump.java index ee19a07..736aa01 100644 --- a/src/main/java/com/connorcode/sigmautils/commands/Dump.java +++ b/src/main/java/com/connorcode/sigmautils/commands/Dump.java @@ -3,7 +3,6 @@ import com.connorcode.sigmautils.SigmaUtils; import com.connorcode.sigmautils.config.Config; import com.connorcode.sigmautils.config.settings.*; -import com.connorcode.sigmautils.misc.util.NetworkUtils; import com.connorcode.sigmautils.module.Category; import com.connorcode.sigmautils.module.DocumentedEnum; import com.connorcode.sigmautils.module.Module; @@ -54,23 +53,6 @@ int execute(CommandContext context) throws IOExceptio var dumps = directory.resolve("dump").toFile(); dumps.mkdirs(); - if (resource.equals("packets")) { - StringBuilder out = new StringBuilder("# Generated with `/util dump packets` (only works in dev builds)\n"); - var mr = FabricLoader.getInstance().getMappingResolver(); - for (var i : NetworkUtils.getPackets() - .keySet() - .stream() - .sorted(Comparator.comparing(Class::getSimpleName)) - .toList()) - out.append(mr.unmapClassName("intermediary", i.getName())) - .append(" ") - .append(i.getSimpleName()) - .append("\n"); - Files.write(dumps.toPath().resolve("packets.txt"), out.toString().getBytes()); - context.getSource().sendFeedback(Text.of("Dumped packets to " + dumps.toPath().resolve("packets.txt"))); - return 0; - } - if (resource.equals("docs")) { var docs = directory.resolve("dump").resolve("docs").toFile(); docs.mkdirs(); diff --git a/src/main/java/com/connorcode/sigmautils/config/ConfigGui.java b/src/main/java/com/connorcode/sigmautils/config/ConfigGui.java index 9bd1877..6a06cae 100644 --- a/src/main/java/com/connorcode/sigmautils/config/ConfigGui.java +++ b/src/main/java/com/connorcode/sigmautils/config/ConfigGui.java @@ -64,15 +64,15 @@ protected void init() { } public void render(DrawContext drawContext, int mouseX, int mouseY, float delta) { - int padding = getPadding(); this.renderBackground(drawContext, mouseX, mouseY, delta); + int padding = getPadding(); + super.render(drawContext, mouseX, mouseY, delta); + for (int x = 0; x < Category.realValues().length; x++) drawContext.drawCenteredTextWithShadow(textRenderer, Text.of("§f§n§l" + Category.realValues()[x].toString()), 75 + padding + x * (150 + padding), padding, 0); - - super.render(drawContext, mouseX, mouseY, delta); } public void close() { diff --git a/src/main/java/com/connorcode/sigmautils/config/settings/list/PacketList.java b/src/main/java/com/connorcode/sigmautils/config/settings/list/PacketList.java index 8f8c162..e2fa777 100644 --- a/src/main/java/com/connorcode/sigmautils/config/settings/list/PacketList.java +++ b/src/main/java/com/connorcode/sigmautils/config/settings/list/PacketList.java @@ -3,23 +3,24 @@ import com.connorcode.sigmautils.config.settings.DynamicListSetting; import com.connorcode.sigmautils.misc.util.NetworkUtils; -import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import net.minecraft.client.gui.screen.Screen; import net.minecraft.nbt.NbtElement; -import net.minecraft.nbt.NbtIntArray; +import net.minecraft.nbt.NbtList; +import net.minecraft.nbt.NbtString; import net.minecraft.network.NetworkSide; import net.minecraft.network.packet.Packet; +import net.minecraft.network.packet.PacketType; +import net.minecraft.network.state.PlayStateFactories; +import net.minecraft.util.Identifier; import java.util.ArrayList; import java.util.List; -import java.util.Optional; -public class PacketList implements DynamicListSetting.ResourceManager>> { - DynamicListSetting>> setting; - Object2IntOpenHashMap>> packets = null; +public class PacketList implements DynamicListSetting.ResourceManager>> { + DynamicListSetting>> setting; NetworkSide side; - public PacketList(DynamicListSetting>> setting, NetworkSide side) { + public PacketList(DynamicListSetting>> setting, NetworkSide side) { this.setting = setting; this.side = side; } @@ -30,22 +31,24 @@ public int width() { } @Override - public List>> getAllResources() { - return getPackets().keySet().stream().toList(); + public List>> getAllResources() { + var out = new ArrayList>>(); + (side == NetworkSide.SERVERBOUND ? PlayStateFactories.C2S : PlayStateFactories.S2C).forEachPacketType(((type, protocolId) -> out.add(type))); + return out; } @Override - public String getDisplay(Class> resource) { - return Optional.ofNullable(NetworkUtils.getPacketName(resource)).orElse(resource.getName()); + public String getDisplay(PacketType> resource) { + return resource.id().toString(); } @Override - public void render(Class> resource, Screen data, int x, int y) { + public void render(PacketType> resource, Screen data, int x, int y) { SimpleList.render(setting, resource, getDisplay(resource), data, x, y, 0); } @Override - public boolean renderSelector(Class> resource, Screen data, int x, int y) { + public boolean renderSelector(PacketType> resource, Screen data, int x, int y) { if (setting.value().contains(resource)) return false; SimpleList.selector(setting, resource, getDisplay(resource), data, x, y, 0); @@ -53,29 +56,21 @@ public boolean renderSelector(Class> resource, Screen data, } @Override - public NbtElement serialize(List>> resources) { - var thisPackets = getPackets(); - var list = resources.stream().mapToInt(thisPackets::getInt).toArray(); - return new NbtIntArray(list); + public NbtElement serialize(List>> resources) { + var out = new NbtList(); + for (var resource : resources) + out.add(NbtString.of(resource.id().getPath())); + return out; } @Override - public List>> deserialize(NbtElement nbt) { - if (!(nbt instanceof NbtIntArray resourceList)) + public List>> deserialize(NbtElement nbt) { + if (!(nbt instanceof NbtList resourceList)) return null; - var list = resourceList.stream().map(e -> getPacket(e.intValue())).toList(); - return new ArrayList<>(list); - } - - Class> getPacket(int id) { - var thisPackets = getPackets(); - return thisPackets.keySet().stream().filter(e -> thisPackets.getInt(e) == id).findFirst().orElse(null); - } - - Object2IntOpenHashMap>> getPackets() { - if (packets == null) - this.packets = NetworkUtils.getPackets(side); - return packets; + var out = new ArrayList>>(); + for (var resource : resourceList) + out.add(NetworkUtils.getPacket(Identifier.of(resource.asString()))); + return new ArrayList<>(out); } @Override diff --git a/src/main/java/com/connorcode/sigmautils/misc/util/NetworkUtils.java b/src/main/java/com/connorcode/sigmautils/misc/util/NetworkUtils.java index f2ad64f..a54ad9d 100644 --- a/src/main/java/com/connorcode/sigmautils/misc/util/NetworkUtils.java +++ b/src/main/java/com/connorcode/sigmautils/misc/util/NetworkUtils.java @@ -3,12 +3,10 @@ import com.connorcode.sigmautils.misc.TextStyle; import com.mojang.authlib.exceptions.AuthenticationException; import com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService; -import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; -import net.fabricmc.loader.api.FabricLoader; -import net.fabricmc.loader.api.MappingResolver; -import net.minecraft.network.NetworkSide; import net.minecraft.network.packet.Packet; -import org.jetbrains.annotations.Nullable; +import net.minecraft.network.packet.PacketType; +import net.minecraft.network.state.PlayStateFactories; +import net.minecraft.util.Identifier; import java.util.HashMap; import java.util.UUID; @@ -16,42 +14,17 @@ import static com.connorcode.sigmautils.SigmaUtils.client; public class NetworkUtils { - static HashMap packetNames = new HashMap<>(); - static MappingResolver mappingResolver = FabricLoader.getInstance().getMappingResolver(); + static HashMap>> packetNames = new HashMap<>(); private static AuthStatus authStatus = AuthStatus.Unknown; private static long lastAuthStatusCheck = 0; - public static Object2IntOpenHashMap>> getPackets(NetworkSide side) { - var packets = new Object2IntOpenHashMap>>(); - // TODO: Fix -// Arrays.stream(NetworkPhase.values()) -// .map(state -> state.packetHandlers.get(side)) -// .filter(Objects::nonNull) -// .forEach(handler -> packets.putAll(handler.backingHandler.packetIds)); - return packets; + static { + PlayStateFactories.C2S.forEachPacketType((type, protocolId) -> packetNames.put(type.id(), type)); + PlayStateFactories.S2C.forEachPacketType((type, protocolId) -> packetNames.put(type.id(), type)); } - public static Object2IntOpenHashMap>> getPackets() { - var packets = new Object2IntOpenHashMap>>(); - packets.putAll(getPackets(NetworkSide.CLIENTBOUND)); - packets.putAll(getPackets(NetworkSide.SERVERBOUND)); - return packets; - } - - public static String getPacketName(Class> packet) { - return getPacketName(packet.getName()); - } - - @Nullable - public static String getPacketName(String bytecodeName) { - var intermediary = mappingResolver.unmapClassName("intermediary", bytecodeName); - if (packetNames.isEmpty()) - Util.loadResourceString("assets/sigma-utils/packets.txt") - .lines() - .filter(line -> !line.startsWith("#")) - .map(line -> line.split(" ")) - .forEach(parts -> packetNames.put(parts[0], parts[1])); - return packetNames.get(intermediary); + public static PacketType> getPacket(Identifier id) { + return packetNames.get(id); } public static synchronized AuthStatus getAuthStatus() { diff --git a/src/main/java/com/connorcode/sigmautils/mixin/EntityMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/EntityMixin.java index e5d3706..e20118c 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/EntityMixin.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/EntityMixin.java @@ -13,16 +13,14 @@ public class EntityMixin { @Inject(method = "isInvisible", at = @At("HEAD"), cancellable = true) void isInvisible(CallbackInfoReturnable cir) { - if (!Config.getEnabled(ShowInvisibleEntities.class) || - !ShowInvisibleEntities.isInvisible((Entity) (Object) this)) + if (!Config.getEnabled(ShowInvisibleEntities.class) || ShowInvisibleEntities.isVisible((Entity) (Object) this)) return; cir.setReturnValue(false); } @Inject(method = "isInvisibleTo", at = @At("HEAD"), cancellable = true) void isInvisibleTo(PlayerEntity player, CallbackInfoReturnable cir) { - if (!Config.getEnabled(ShowInvisibleEntities.class) || - !ShowInvisibleEntities.isInvisible((Entity) (Object) this)) + if (!Config.getEnabled(ShowInvisibleEntities.class) || ShowInvisibleEntities.isVisible((Entity) (Object) this)) return; cir.setReturnValue(false); } diff --git a/src/main/java/com/connorcode/sigmautils/modules/misc/PacketCanceler.java b/src/main/java/com/connorcode/sigmautils/modules/misc/PacketCanceler.java index 32ceffd..c494b6f 100644 --- a/src/main/java/com/connorcode/sigmautils/modules/misc/PacketCanceler.java +++ b/src/main/java/com/connorcode/sigmautils/modules/misc/PacketCanceler.java @@ -6,11 +6,11 @@ import com.connorcode.sigmautils.event.EventHandler; import com.connorcode.sigmautils.event.network.PacketReceiveEvent; import com.connorcode.sigmautils.event.network.PacketSendEvent; -import com.connorcode.sigmautils.misc.util.NetworkUtils; import com.connorcode.sigmautils.module.Module; import com.connorcode.sigmautils.module.ModuleInfo; import net.minecraft.network.NetworkSide; import net.minecraft.network.packet.Packet; +import net.minecraft.network.packet.PacketType; import net.minecraft.text.Text; import static com.connorcode.sigmautils.SigmaUtils.client; @@ -18,41 +18,41 @@ // Warning: When updating versions the packets may change and this won't be automatically updated, causing unexpected behaviour (gasp) @ModuleInfo(description = "Cancels the specified packets.") public class PacketCanceler extends Module { - DynamicListSetting>> clientPackets = + DynamicListSetting>> clientPackets = new DynamicListSetting<>(PacketCanceler.class, "Client Packets", PacketCanceler::getClientPacketManager).description("Packets to the client.").build(); - DynamicListSetting>> serverPackets = + DynamicListSetting>> serverPackets = new DynamicListSetting<>(PacketCanceler.class, "Server Packets", PacketCanceler::getServerPacketManager).description("Packets to the server.").build(); BoolSetting debug = new BoolSetting(PacketCanceler.class, "Debug") .description("Prints debug messages when a packet is canceled.") .build(); - static DynamicListSetting.ResourceManager>> getClientPacketManager(DynamicListSetting>> setting) { + static DynamicListSetting.ResourceManager>> getClientPacketManager(DynamicListSetting>> setting) { return new PacketList(setting, NetworkSide.CLIENTBOUND); } - static DynamicListSetting.ResourceManager>> getServerPacketManager(DynamicListSetting>> setting) { + static DynamicListSetting.ResourceManager>> getServerPacketManager(DynamicListSetting>> setting) { return new PacketList(setting, NetworkSide.SERVERBOUND); } @EventHandler void onPacketSend(PacketSendEvent packet) { - if (!enabled || !serverPackets.value().contains(packet.get().getClass())) return; + if (!enabled || !serverPackets.value().contains(packet.packet.getPacketId())) return; sendDebug(NetworkSide.SERVERBOUND, packet.get()); packet.cancel(); } @EventHandler void onPacketReceive(PacketReceiveEvent packet) { - if (!enabled || !clientPackets.value().contains(packet.get().getClass())) return; + if (!enabled || !clientPackets.value().contains(packet.packet.getPacketId())) return; sendDebug(NetworkSide.CLIENTBOUND, packet.get()); packet.cancel(); } void sendDebug(NetworkSide side, Packet packet) { if (client.player == null || !debug.value()) return; - client.player.sendMessage(Text.of(String.format("[SIGMAUTILS::PacketCancel] Cancelling %s packet %s", side, - NetworkUtils.getPacketName(packet.getClass().getName()))), false); + client.player.sendMessage(Text.of(String.format("[SIGMAUTILS::PacketCancel] Cancelling %s packet %s", side, packet.getPacketId() + .id().getPath())), false); } } diff --git a/src/main/java/com/connorcode/sigmautils/modules/rendering/ShowInvisibleEntities.java b/src/main/java/com/connorcode/sigmautils/modules/rendering/ShowInvisibleEntities.java index 31ac26e..5c1e724 100644 --- a/src/main/java/com/connorcode/sigmautils/modules/rendering/ShowInvisibleEntities.java +++ b/src/main/java/com/connorcode/sigmautils/modules/rendering/ShowInvisibleEntities.java @@ -3,7 +3,6 @@ import com.connorcode.sigmautils.config.settings.DynamicListSetting; import com.connorcode.sigmautils.config.settings.EnumSetting; -import com.connorcode.sigmautils.config.settings.NumberSetting; import com.connorcode.sigmautils.config.settings.list.EntityList; import com.connorcode.sigmautils.misc.util.Util; import com.connorcode.sigmautils.module.Module; @@ -13,16 +12,17 @@ @ModuleInfo(description = "Render all invisible entities") public class ShowInvisibleEntities extends Module { - public static NumberSetting opacity = new NumberSetting(ShowInvisibleEntities.class, "Opacity", 0, 1).value(0.25) - .description("Opacity of invisible entities.") - .build(); + // TODO: Show invis entities as translucent +// public static NumberSetting opacity = new NumberSetting(ShowInvisibleEntities.class, "Opacity", 0, 1).value(0.25) +// .description("Opacity of invisible entities.") +// .build(); static EnumSetting filterType = Util.filterSetting(ShowInvisibleEntities.class).build(); static DynamicListSetting> entities = new DynamicListSetting<>(ShowInvisibleEntities.class, "Entities", EntityList::new).description( "Entities show while invisible. Whitelisting an entities will make it not render flipped.") .build(); - public static boolean isInvisible(Entity entity) { + public static boolean isVisible(Entity entity) { var inList = entities.value().contains(entity.getType()); return filterType.value() == Util.FilterType.Whitelist == inList; } diff --git a/src/main/resources/assets/sigma-utils/packets.txt b/src/main/resources/assets/sigma-utils/packets.txt deleted file mode 100644 index 9a3dbc8..0000000 --- a/src/main/resources/assets/sigma-utils/packets.txt +++ /dev/null @@ -1,189 +0,0 @@ -# Generated with `/util dump packets` (only works in dev builds) -net.minecraft.class_8590 AcknowledgeChunksC2SPacket -net.minecraft.class_8591 AcknowledgeReconfigurationC2SPacket -net.minecraft.class_2859 AdvancementTabC2SPacket -net.minecraft.class_2779 AdvancementUpdateS2CPacket -net.minecraft.class_2620 BlockBreakingProgressS2CPacket -net.minecraft.class_2622 BlockEntityUpdateS2CPacket -net.minecraft.class_2623 BlockEventS2CPacket -net.minecraft.class_2626 BlockUpdateS2CPacket -net.minecraft.class_2836 BoatPaddleStateC2SPacket -net.minecraft.class_2820 BookUpdateC2SPacket -net.minecraft.class_2629 BossBarS2CPacket -net.minecraft.class_8037 BundleSplitterPacket -net.minecraft.class_2811 ButtonClickC2SPacket -net.minecraft.class_2797 ChatMessageC2SPacket -net.minecraft.class_7438 ChatMessageS2CPacket -net.minecraft.class_7597 ChatSuggestionsS2CPacket -net.minecraft.class_8212 ChunkBiomeDataS2CPacket -net.minecraft.class_2672 ChunkDataS2CPacket -net.minecraft.class_2637 ChunkDeltaUpdateS2CPacket -net.minecraft.class_4273 ChunkLoadDistanceS2CPacket -net.minecraft.class_4282 ChunkRenderDistanceCenterS2CPacket -net.minecraft.class_8738 ChunkSentS2CPacket -net.minecraft.class_5888 ClearTitleS2CPacket -net.minecraft.class_2813 ClickSlotC2SPacket -net.minecraft.class_2848 ClientCommandC2SPacket -net.minecraft.class_2803 ClientOptionsC2SPacket -net.minecraft.class_2799 ClientStatusC2SPacket -net.minecraft.class_2815 CloseHandledScreenC2SPacket -net.minecraft.class_2645 CloseScreenS2CPacket -net.minecraft.class_7472 CommandExecutionC2SPacket -net.minecraft.class_2639 CommandSuggestionsS2CPacket -net.minecraft.class_2641 CommandTreeS2CPacket -net.minecraft.class_6373 CommonPingS2CPacket -net.minecraft.class_6374 CommonPongC2SPacket -net.minecraft.class_2656 CooldownUpdateS2CPacket -net.minecraft.class_2695 CraftFailedResponseS2CPacket -net.minecraft.class_2840 CraftRequestC2SPacket -net.minecraft.class_2873 CreativeInventoryActionC2SPacket -net.minecraft.class_2817 CustomPayloadC2SPacket -net.minecraft.class_2658 CustomPayloadS2CPacket -net.minecraft.class_8043 DamageTiltS2CPacket -net.minecraft.class_5892 DeathMessageS2CPacket -net.minecraft.class_2632 DifficultyS2CPacket -net.minecraft.class_2661 DisconnectS2CPacket -net.minecraft.class_8734 DynamicRegistriesS2CPacket -net.minecraft.class_5890 EndCombatS2CPacket -net.minecraft.class_5891 EnterCombatS2CPacket -net.minecraft.class_8593 EnterConfigurationC2SPacket -net.minecraft.class_8588 EnterReconfigurationS2CPacket -net.minecraft.class_2716 EntitiesDestroyS2CPacket -net.minecraft.class_2616 EntityAnimationS2CPacket -net.minecraft.class_2740 EntityAttachS2CPacket -net.minecraft.class_2781 EntityAttributesS2CPacket -net.minecraft.class_8143 EntityDamageS2CPacket -net.minecraft.class_2744 EntityEquipmentUpdateS2CPacket -net.minecraft.class_2752 EntityPassengersSetS2CPacket -net.minecraft.class_2777 EntityPositionS2CPacket -net.minecraft.class_2726 EntitySetHeadYawS2CPacket -net.minecraft.class_2604 EntitySpawnS2CPacket -net.minecraft.class_2783 EntityStatusEffectS2CPacket -net.minecraft.class_2663 EntityStatusS2CPacket -net.minecraft.class_2739 EntityTrackerUpdateS2CPacket -net.minecraft.class_2743 EntityVelocityUpdateS2CPacket -net.minecraft.class_2748 ExperienceBarUpdateS2CPacket -net.minecraft.class_2606 ExperienceOrbSpawnS2CPacket -net.minecraft.class_2664 ExplosionS2CPacket -net.minecraft.class_7832 FeaturesS2CPacket -net.minecraft.class_2828$class_2830 Full -net.minecraft.class_2678 GameJoinS2CPacket -net.minecraft.class_7439 GameMessageS2CPacket -net.minecraft.class_2668 GameStateChangeS2CPacket -net.minecraft.class_2879 HandSwingC2SPacket -net.minecraft.class_2889 HandshakeC2SPacket -net.minecraft.class_2749 HealthUpdateS2CPacket -net.minecraft.class_2649 InventoryS2CPacket -net.minecraft.class_2775 ItemPickupAnimationS2CPacket -net.minecraft.class_5194 JigsawGeneratingC2SPacket -net.minecraft.class_2827 KeepAliveC2SPacket -net.minecraft.class_2670 KeepAliveS2CPacket -net.minecraft.class_2676 LightUpdateS2CPacket -net.minecraft.class_2907 LoginCompressionS2CPacket -net.minecraft.class_2909 LoginDisconnectS2CPacket -net.minecraft.class_2915 LoginHelloC2SPacket -net.minecraft.class_2905 LoginHelloS2CPacket -net.minecraft.class_2917 LoginKeyC2SPacket -net.minecraft.class_2899 LoginQueryRequestS2CPacket -net.minecraft.class_2913 LoginQueryResponseC2SPacket -net.minecraft.class_2901 LoginSuccessS2CPacket -net.minecraft.class_2828$class_2831 LookAndOnGround -net.minecraft.class_2707 LookAtS2CPacket -net.minecraft.class_2683 MapUpdateS2CPacket -net.minecraft.class_7640 MessageAcknowledgmentC2SPacket -net.minecraft.class_2684$class_2685 MoveRelative -net.minecraft.class_2774 NbtQueryResponseS2CPacket -net.minecraft.class_2828$class_5911 OnGroundOnly -net.minecraft.class_2648 OpenHorseScreenS2CPacket -net.minecraft.class_3944 OpenScreenS2CPacket -net.minecraft.class_3895 OpenWrittenBookS2CPacket -net.minecraft.class_5894 OverlayMessageS2CPacket -net.minecraft.class_2675 ParticleS2CPacket -net.minecraft.class_2838 PickFromInventoryC2SPacket -net.minecraft.class_2923 PingResultS2CPacket -net.minecraft.class_2765 PlaySoundFromEntityS2CPacket -net.minecraft.class_2767 PlaySoundS2CPacket -net.minecraft.class_2696 PlayerAbilitiesS2CPacket -net.minecraft.class_2846 PlayerActionC2SPacket -net.minecraft.class_4463 PlayerActionResponseS2CPacket -net.minecraft.class_2851 PlayerInputC2SPacket -net.minecraft.class_2885 PlayerInteractBlockC2SPacket -net.minecraft.class_2824 PlayerInteractEntityC2SPacket -net.minecraft.class_2886 PlayerInteractItemC2SPacket -net.minecraft.class_2772 PlayerListHeaderS2CPacket -net.minecraft.class_2703 PlayerListS2CPacket -net.minecraft.class_2708 PlayerPositionLookS2CPacket -net.minecraft.class_7828 PlayerRemoveS2CPacket -net.minecraft.class_2724 PlayerRespawnS2CPacket -net.minecraft.class_7861 PlayerSessionC2SPacket -net.minecraft.class_2759 PlayerSpawnPositionS2CPacket -net.minecraft.class_2828$class_2829 PositionAndOnGround -net.minecraft.class_7827 ProfilelessChatMessageS2CPacket -net.minecraft.class_2795 QueryBlockNbtC2SPacket -net.minecraft.class_2822 QueryEntityNbtC2SPacket -net.minecraft.class_2935 QueryPingC2SPacket -net.minecraft.class_2937 QueryRequestC2SPacket -net.minecraft.class_2924 QueryResponseS2CPacket -net.minecraft.class_8736 ReadyC2SPacket -net.minecraft.class_8733 ReadyS2CPacket -net.minecraft.class_2853 RecipeBookDataC2SPacket -net.minecraft.class_5427 RecipeCategoryOptionsC2SPacket -net.minecraft.class_2718 RemoveEntityStatusEffectS2CPacket -net.minecraft.class_7617 RemoveMessageS2CPacket -net.minecraft.class_2855 RenameItemC2SPacket -net.minecraft.class_2805 RequestCommandCompletionsC2SPacket -net.minecraft.class_9053 ResourcePackRemoveS2CPacket -net.minecraft.class_2720 ResourcePackSendS2CPacket -net.minecraft.class_2856 ResourcePackStatusC2SPacket -net.minecraft.class_2684$class_2687 Rotate -net.minecraft.class_2684$class_2686 RotateAndMoveRelative -net.minecraft.class_2736 ScoreboardDisplayS2CPacket -net.minecraft.class_2751 ScoreboardObjectiveUpdateS2CPacket -net.minecraft.class_9006 ScoreboardScoreResetS2CPacket -net.minecraft.class_2757 ScoreboardScoreUpdateS2CPacket -net.minecraft.class_2651 ScreenHandlerPropertyUpdateS2CPacket -net.minecraft.class_2653 ScreenHandlerSlotUpdateS2CPacket -net.minecraft.class_2729 SelectAdvancementTabS2CPacket -net.minecraft.class_2863 SelectMerchantTradeC2SPacket -net.minecraft.class_7495 ServerMetadataS2CPacket -net.minecraft.class_2734 SetCameraEntityS2CPacket -net.minecraft.class_3943 SetTradeOffersS2CPacket -net.minecraft.class_2693 SignEditorOpenS2CPacket -net.minecraft.class_6682 SimulationDistanceS2CPacket -net.minecraft.class_8875 SlotChangedStateC2SPacket -net.minecraft.class_2884 SpectatorTeleportC2SPacket -net.minecraft.class_8739 StartChunkSendS2CPacket -net.minecraft.class_2617 StatisticsS2CPacket -net.minecraft.class_2770 StopSoundS2CPacket -net.minecraft.class_5903 SubtitleS2CPacket -net.minecraft.class_2788 SynchronizeRecipesS2CPacket -net.minecraft.class_2790 SynchronizeTagsS2CPacket -net.minecraft.class_5900 TeamS2CPacket -net.minecraft.class_2793 TeleportConfirmC2SPacket -net.minecraft.class_8914 TickStepS2CPacket -net.minecraft.class_5905 TitleFadeS2CPacket -net.minecraft.class_5904 TitleS2CPacket -net.minecraft.class_2666 UnloadChunkS2CPacket -net.minecraft.class_2713 UnlockRecipesS2CPacket -net.minecraft.class_2866 UpdateBeaconC2SPacket -net.minecraft.class_2870 UpdateCommandBlockC2SPacket -net.minecraft.class_2871 UpdateCommandBlockMinecartC2SPacket -net.minecraft.class_4210 UpdateDifficultyC2SPacket -net.minecraft.class_4211 UpdateDifficultyLockC2SPacket -net.minecraft.class_3753 UpdateJigsawC2SPacket -net.minecraft.class_2842 UpdatePlayerAbilitiesC2SPacket -net.minecraft.class_2868 UpdateSelectedSlotC2SPacket -net.minecraft.class_2735 UpdateSelectedSlotS2CPacket -net.minecraft.class_2877 UpdateSignC2SPacket -net.minecraft.class_2875 UpdateStructureBlockC2SPacket -net.minecraft.class_8913 UpdateTickRateS2CPacket -net.minecraft.class_2833 VehicleMoveC2SPacket -net.minecraft.class_2692 VehicleMoveS2CPacket -net.minecraft.class_5895 WorldBorderCenterChangedS2CPacket -net.minecraft.class_5889 WorldBorderInitializeS2CPacket -net.minecraft.class_5896 WorldBorderInterpolateSizeS2CPacket -net.minecraft.class_5897 WorldBorderSizeChangedS2CPacket -net.minecraft.class_5899 WorldBorderWarningBlocksChangedS2CPacket -net.minecraft.class_5898 WorldBorderWarningTimeChangedS2CPacket -net.minecraft.class_2673 WorldEventS2CPacket -net.minecraft.class_2761 WorldTimeUpdateS2CPacket diff --git a/todo.txt b/todo.txt index 7e71328..f544fbc 100644 --- a/todo.txt +++ b/todo.txt @@ -1,8 +1,8 @@ - fix ShowInvisableEntites opacity property -- fix packet stuff (NetworkUtils) -- test auto trade cycle -- fix tick speed -- Update packet registry +x fix packet stuff (NetworkUtils) +x test auto trade cycle +x fix tick speed +x Update packet registry - fix map border x fix fast doll stuff (InventoryScreenMixin) From a2aa81ff84b429e340767006dc43dbf809f10cc0 Mon Sep 17 00:00:00 2001 From: Connor Slade Date: Fri, 28 Jun 2024 19:54:33 -0400 Subject: [PATCH 12/17] Bump version to 0.1.10 --- gradle.properties | 2 +- src/main/java/com/connorcode/sigmautils/SigmaUtils.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 92f9bde..8b03f48 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ minecraft_version=1.21 yarn_mappings=1.21+build.4 loader_version=0.15.11 # Mod Properties -mod_version=0.1.9-alpha +mod_version=0.1.10-alpha maven_group=com.connorcode archives_base_name=sigma-utils # Dependencies diff --git a/src/main/java/com/connorcode/sigmautils/SigmaUtils.java b/src/main/java/com/connorcode/sigmautils/SigmaUtils.java index 591a03c..ba4bbe0 100644 --- a/src/main/java/com/connorcode/sigmautils/SigmaUtils.java +++ b/src/main/java/com/connorcode/sigmautils/SigmaUtils.java @@ -28,7 +28,7 @@ @Environment(EnvType.CLIENT) public class SigmaUtils implements ClientModInitializer { - public static final String VERSION = "0.1.9-alpha"; + public static final String VERSION = "0.1.10-alpha"; public static final MinecraftClient client = MinecraftClient.getInstance(); public static final Logger logger = LogUtils.getLogger(); From 4e2d3d807c4e99fa5eeb91d718bb2369a4129808 Mon Sep 17 00:00:00 2001 From: Connor Slade Date: Fri, 28 Jun 2024 20:41:21 -0400 Subject: [PATCH 13/17] Working mute button positioning --- .../com/connorcode/sigmautils/SigmaUtils.java | 4 +- .../sigmautils/mixin/OptionsScreenMixin.java | 44 +++++++++++++++---- todo.txt | 14 ------ 3 files changed, 38 insertions(+), 24 deletions(-) delete mode 100644 todo.txt diff --git a/src/main/java/com/connorcode/sigmautils/SigmaUtils.java b/src/main/java/com/connorcode/sigmautils/SigmaUtils.java index ba4bbe0..2cf485e 100644 --- a/src/main/java/com/connorcode/sigmautils/SigmaUtils.java +++ b/src/main/java/com/connorcode/sigmautils/SigmaUtils.java @@ -89,4 +89,6 @@ void onClientStop(GameLifecycle.ClientStoppingEvent event) throws IOException { // TODO: Entiry selector custom type // TODO: Allow viewing / specifing resource pack uuids -// TODO Document Hid, Meta, and Misc packages \ No newline at end of file +// TODO Document Hid, Meta, and Misc packages +// TODO: fix map borders +// TODO: fix ShowInvisableEntites opacity property \ No newline at end of file diff --git a/src/main/java/com/connorcode/sigmautils/mixin/OptionsScreenMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/OptionsScreenMixin.java index 2f56846..3312373 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/OptionsScreenMixin.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/OptionsScreenMixin.java @@ -3,32 +3,58 @@ import com.connorcode.sigmautils.config.Config; import com.connorcode.sigmautils.modules._interface.UiTweaks; +import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.option.OptionsScreen; import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.gui.widget.Widget; import net.minecraft.text.Text; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @Mixin(OptionsScreen.class) public class OptionsScreenMixin extends Screen { + @Unique + ButtonWidget muteButton; + + @Unique + Widget soundButton; + + @Unique + void positionButton() { + muteButton.setX(soundButton.getX() + soundButton.getWidth() + 5); + muteButton.setY(soundButton.getY()); + } + protected OptionsScreenMixin(Text title) { super(title); } - @Inject(method = "init", at = @At("TAIL"), locals = LocalCapture.CAPTURE_FAILHARD) - void onButtonRender(CallbackInfo ci) { - if (!Config.getEnabled(UiTweaks.class) || !UiTweaks.audioMuteButton.value()) return; + @ModifyArg(method = "init", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/widget/GridWidget$Adder;add(Lnet/minecraft/client/gui/widget/Widget;)Lnet/minecraft/client/gui/widget/Widget;", ordinal = 1)) + T onAddSoundButton(T widget) { + if (!Config.getEnabled(UiTweaks.class) || !UiTweaks.audioMuteButton.value()) return widget; - // TODO: handle resizing of window - var x = this.width / 2 + 160; - var y = this.height / 6 + 42; - addDrawableChild(ButtonWidget.builder(Text.of(UiTweaks.muted ? "U" : "M"), button -> { + soundButton = widget; + muteButton = addDrawableChild(ButtonWidget.builder(Text.of(UiTweaks.muted ? "U" : "M"), button -> { UiTweaks.muted ^= true; button.setMessage(Text.of(UiTweaks.muted ? "U" : "M")); - }).position(x, y).size(20, 20).build()); + }).size(20, 20).build()); + + return widget; + } + + @Inject(method = "init", at = @At("TAIL")) + void onInitTail(CallbackInfo ci) { + positionButton(); + } + + @Override + public void resize(MinecraftClient client, int width, int height) { + super.resize(client, width, height); + positionButton(); } } diff --git a/todo.txt b/todo.txt deleted file mode 100644 index f544fbc..0000000 --- a/todo.txt +++ /dev/null @@ -1,14 +0,0 @@ -- fix ShowInvisableEntites opacity property -x fix packet stuff (NetworkUtils) -x test auto trade cycle -x fix tick speed -x Update packet registry -- fix map border - -x fix fast doll stuff (InventoryScreenMixin) -x fix world render mixin (WorldRenderMixin) -- fix OptionsScreenMixin -x fix ChatHudMixin -x fix CameraMixin -x fix InGameHudMixin -x fix EntityRendererMixin \ No newline at end of file From dc2beec399497578e48ebf1a9e4ec354d5b808aa Mon Sep 17 00:00:00 2001 From: Connor Slade Date: Fri, 28 Jun 2024 22:35:16 -0400 Subject: [PATCH 14/17] Fix map border --- .../com/connorcode/sigmautils/SigmaUtils.java | 2 -- .../sigmautils/modules/rendering/MapBorder.java | 17 ++++++++++------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/connorcode/sigmautils/SigmaUtils.java b/src/main/java/com/connorcode/sigmautils/SigmaUtils.java index 2cf485e..c424c47 100644 --- a/src/main/java/com/connorcode/sigmautils/SigmaUtils.java +++ b/src/main/java/com/connorcode/sigmautils/SigmaUtils.java @@ -88,7 +88,5 @@ void onClientStop(GameLifecycle.ClientStoppingEvent event) throws IOException { // TODO: camera no clip - disable culling // TODO: Entiry selector custom type // TODO: Allow viewing / specifing resource pack uuids - // TODO Document Hid, Meta, and Misc packages -// TODO: fix map borders // TODO: fix ShowInvisableEntites opacity property \ No newline at end of file diff --git a/src/main/java/com/connorcode/sigmautils/modules/rendering/MapBorder.java b/src/main/java/com/connorcode/sigmautils/modules/rendering/MapBorder.java index fa87ce4..48bb3f4 100644 --- a/src/main/java/com/connorcode/sigmautils/modules/rendering/MapBorder.java +++ b/src/main/java/com/connorcode/sigmautils/modules/rendering/MapBorder.java @@ -15,8 +15,10 @@ @ModuleInfo(description = "Renders a border around the current map section you are in. Useful for positioning map arts.") public class MapBorder extends Module { - EnumSetting color = new EnumSetting<>(MapBorder.class, "Color", TextStyle.Color.class).description("The color of the border.").value(TextStyle.Color.LightPurple).build(); - NumberSetting step = new NumberSetting(MapBorder.class, "Step", 1, 16).description("The step between each line.").value(16).build(); + EnumSetting color = new EnumSetting<>(MapBorder.class, "Color", TextStyle.Color.class).description("The color of the border.") + .value(TextStyle.Color.LightPurple).build(); + NumberSetting step = new NumberSetting(MapBorder.class, "Step", 1, 16).description("The step between each line.") + .value(16).build(); @EventHandler void onRender(WorldRender.PostWorldRenderEvent event) { @@ -24,19 +26,20 @@ void onRender(WorldRender.PostWorldRenderEvent event) { var minY = client.world.getBottomY(); var maxY = client.world.getTopY(); var pos = client.player.getPos(); - var x = (int) ((pos.x + 64) / 128); - var z = (int) ((pos.z + 64) / 128); + + var x = pos.x + 64 * (pos.x > 0 ? 1 : -1); + var z = pos.z + 64 * (pos.z > 0 ? 1 : -1); var immediate = client.getBufferBuilders().getEntityVertexConsumers(); var layer = immediate.getBuffer(RenderLayer.getDebugLineStrip(1f)); var matrices = getMatrices(Vec3d.ZERO).peek().getPositionMatrix(); - var boxX = x * 128 + 64; - var boxZ = z * 128 + 64; + var boxX = (int) (x / 128) * 128 + 64; + var boxZ = (int) (z / 128) * 128 + 64; var c = color.value().asHexColor() & 0xffffff; var d = c | 0x80 << 24; - for (var y = minY; y <= maxY; y += step.value()) { + for (var y = minY; y <= maxY; y += (int) step.value()) { layer.vertex(matrices, boxX, y, boxZ).color(c); layer.vertex(matrices, boxX - 128, y, boxZ).color(d); layer.vertex(matrices, boxX - 128, y, boxZ).color(c); From 6d41f7153bb97a66dcd1c7dd0d0fba74d98de39d Mon Sep 17 00:00:00 2001 From: Connor Slade Date: Fri, 28 Jun 2024 23:08:51 -0400 Subject: [PATCH 15/17] Final fixups --- .../connorcode/sigmautils/commands/Map.java | 27 +++---------------- .../sigmautils/misc/Components.java | 1 + .../sigmautils/mixin/EntityMixin.java | 10 +++---- .../mixin/MinecraftClientMixin.java | 12 +++------ .../modules/misc/CameraDistance.java | 1 + 5 files changed, 13 insertions(+), 38 deletions(-) diff --git a/src/main/java/com/connorcode/sigmautils/commands/Map.java b/src/main/java/com/connorcode/sigmautils/commands/Map.java index 40dbb34..bf763a7 100644 --- a/src/main/java/com/connorcode/sigmautils/commands/Map.java +++ b/src/main/java/com/connorcode/sigmautils/commands/Map.java @@ -12,7 +12,6 @@ import net.minecraft.item.Items; import net.minecraft.item.map.MapState; import net.minecraft.text.ClickEvent; -import net.minecraft.text.MutableText; import net.minecraft.text.Text; import net.minecraft.util.Formatting; import net.minecraft.util.Pair; @@ -41,7 +40,7 @@ private static int save(CommandContext context) { e.printStackTrace(); } - client.player.sendMessage(Text.literal(String.format("Σ] Saved Map #%d", mapId)) + client.player.sendMessage(Text.literal(String.format("[SigmaUtils::Map] Saved Map #%d", mapId.id())) .formatted(Formatting.UNDERLINE) .styled(style -> style.withClickEvent( new ClickEvent(ClickEvent.Action.OPEN_FILE, mapFile.getAbsolutePath())))); @@ -54,29 +53,9 @@ private static int info(CommandContext context) { var mapId = rawMap.get().getLeft(); MapState mapState = rawMap.get().getRight(); - MutableText out = Text.empty() - // Id - .append(Text.literal("\nΣ] Id: ") - .formatted(Formatting.BOLD)) - .append(Text.literal(String.valueOf(mapId)) - .formatted(Formatting.RESET)) - - // Scale - .append(Text.literal("\nΣ] Scale: ") - .formatted(Formatting.BOLD)) - .append(Text.literal(String.format("1:%d", (int) Math.pow(2, mapState.scale))) - .formatted(Formatting.RESET)) - - // Locked - .append(Text.literal("\nΣ] Locked: ") - .formatted(Formatting.BOLD)) - .append(Text.literal(String.valueOf(mapState.locked)) - .formatted(Formatting.RESET)); - - + var out = String.format("[SigmaUtils::Map] { ID: %d, Scale: 1:%d, Locked: %b }", mapId.id(), (int) Math.pow(2, mapState.scale), mapState.locked); context.getSource() - .getPlayer() - .sendMessage(out); + .getPlayer().sendMessage(Text.of(out)); return 0; } diff --git a/src/main/java/com/connorcode/sigmautils/misc/Components.java b/src/main/java/com/connorcode/sigmautils/misc/Components.java index 96446c2..dbc7495 100644 --- a/src/main/java/com/connorcode/sigmautils/misc/Components.java +++ b/src/main/java/com/connorcode/sigmautils/misc/Components.java @@ -29,6 +29,7 @@ public static void addToggleButton(Screen screen, Module module, int x, int y, i Util.addChild(screen, new MultiClickButton(x, y, width, 20, Text.of(String.format("%s█§r%s", module.enabled ? "§a" : "§c", mini ? "" : String.format(" %s", module.name))), button -> { + System.out.println(button.click); if (button.click == 1) { if (Config.moduleSettings.get(module.getClass()).size() <= 1) return; diff --git a/src/main/java/com/connorcode/sigmautils/mixin/EntityMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/EntityMixin.java index e20118c..5941532 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/EntityMixin.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/EntityMixin.java @@ -13,15 +13,13 @@ public class EntityMixin { @Inject(method = "isInvisible", at = @At("HEAD"), cancellable = true) void isInvisible(CallbackInfoReturnable cir) { - if (!Config.getEnabled(ShowInvisibleEntities.class) || ShowInvisibleEntities.isVisible((Entity) (Object) this)) - return; - cir.setReturnValue(false); + if (Config.getEnabled(ShowInvisibleEntities.class) && ShowInvisibleEntities.isVisible((Entity) (Object) this)) + cir.setReturnValue(false); } @Inject(method = "isInvisibleTo", at = @At("HEAD"), cancellable = true) void isInvisibleTo(PlayerEntity player, CallbackInfoReturnable cir) { - if (!Config.getEnabled(ShowInvisibleEntities.class) || ShowInvisibleEntities.isVisible((Entity) (Object) this)) - return; - cir.setReturnValue(false); + if (Config.getEnabled(ShowInvisibleEntities.class) && ShowInvisibleEntities.isVisible((Entity) (Object) this)) + cir.setReturnValue(false); } } diff --git a/src/main/java/com/connorcode/sigmautils/mixin/MinecraftClientMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/MinecraftClientMixin.java index d36f22f..da12d8c 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/MinecraftClientMixin.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/MinecraftClientMixin.java @@ -22,7 +22,6 @@ import net.minecraft.util.hit.HitResult; import net.minecraft.util.math.BlockPos; import org.jetbrains.annotations.Nullable; -import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -120,13 +119,10 @@ void onGetStackInHand(CallbackInfo ci) { // } // For no_pause - @Redirect(method = "render", at = @At(value = "FIELD", target = "Lnet/minecraft/client/MinecraftClient;paused:Z", opcode = Opcodes.GETFIELD)) - boolean isPaused(MinecraftClient instance) { - if (!Config.getEnabled(NoPause.class)) - return this.paused; - return this.isIntegratedServerRunning() && (this.currentScreen != null && this.currentScreen.shouldPause() || - this.overlay != null && this.overlay.pausesGame()) && !Objects.requireNonNull(this.server) - .isRemote(); + @Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;isIntegratedServerRunning()Z")) + boolean isIntegratedServerRunning(MinecraftClient instance) { + if (Config.getEnabled(NoPause.class)) return false; + else return instance.isIntegratedServerRunning(); } // For window_title diff --git a/src/main/java/com/connorcode/sigmautils/modules/misc/CameraDistance.java b/src/main/java/com/connorcode/sigmautils/modules/misc/CameraDistance.java index 0fb8894..9524279 100644 --- a/src/main/java/com/connorcode/sigmautils/modules/misc/CameraDistance.java +++ b/src/main/java/com/connorcode/sigmautils/modules/misc/CameraDistance.java @@ -49,6 +49,7 @@ public void drawInterface(MinecraftClient client, Screen screen, int x, int y) { @Override public void disable() { + super.disable(); distanceMod = 0; } } From 083c406f7cec994c0646a7b97b3db0c4fb90b5b9 Mon Sep 17 00:00:00 2001 From: Connor Slade Date: Fri, 28 Jun 2024 23:40:00 -0400 Subject: [PATCH 16/17] Add back RandomBackground --- .../sigmautils/mixin/ScreenMixin.java | 40 +++++++++ .../modules/_interface/RandomBackground.java | 83 +++++++++++++++++++ .../sigmautils/modules/misc/TickSpeed.java | 13 --- src/main/resources/modules/modules.json | 3 +- src/main/resources/sigma-utils.mixins.json | 1 + 5 files changed, 126 insertions(+), 14 deletions(-) create mode 100644 src/main/java/com/connorcode/sigmautils/mixin/ScreenMixin.java create mode 100644 src/main/java/com/connorcode/sigmautils/modules/_interface/RandomBackground.java diff --git a/src/main/java/com/connorcode/sigmautils/mixin/ScreenMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/ScreenMixin.java new file mode 100644 index 0000000..22f81a9 --- /dev/null +++ b/src/main/java/com/connorcode/sigmautils/mixin/ScreenMixin.java @@ -0,0 +1,40 @@ +package com.connorcode.sigmautils.mixin; + +import com.connorcode.sigmautils.config.Config; +import com.connorcode.sigmautils.modules._interface.RandomBackground; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.GameMenuScreen; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.advancement.AdvancementsScreen; +import net.minecraft.util.Identifier; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(Screen.class) +public abstract class ScreenMixin { + @Shadow + public int width; + @Shadow + public int height; + + @Shadow + public static void renderBackgroundTexture(DrawContext context, Identifier texture, int x, int y, float u, float v, int width, int height) { + throw new RuntimeException(); + } + + @Shadow + public abstract void renderInGameBackground(DrawContext context); + + @Inject(method = "renderBackground", at = @At("HEAD"), cancellable = true) + void onRenderBackground(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) { + if (!Config.getEnabled(RandomBackground.class) || (Screen) (Object) this instanceof GameMenuScreen || (Screen) (Object) this instanceof AdvancementsScreen) + return; + + renderBackgroundTexture(context, RandomBackground.getTexture(), 0, 0, 0, 0, this.width, this.height); + renderInGameBackground(context); + ci.cancel(); + } +} diff --git a/src/main/java/com/connorcode/sigmautils/modules/_interface/RandomBackground.java b/src/main/java/com/connorcode/sigmautils/modules/_interface/RandomBackground.java new file mode 100644 index 0000000..5ea9314 --- /dev/null +++ b/src/main/java/com/connorcode/sigmautils/modules/_interface/RandomBackground.java @@ -0,0 +1,83 @@ +package com.connorcode.sigmautils.modules._interface; + +import com.connorcode.sigmautils.SigmaUtils; +import com.connorcode.sigmautils.config.settings.DynamicListSetting; +import com.connorcode.sigmautils.config.settings.EnumSetting; +import com.connorcode.sigmautils.config.settings.list.SimpleList; +import com.connorcode.sigmautils.misc.Components; +import com.connorcode.sigmautils.misc.util.Util; +import com.connorcode.sigmautils.module.Module; +import com.connorcode.sigmautils.module.ModuleInfo; +import net.minecraft.block.Block; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.registry.Registries; +import net.minecraft.util.Identifier; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.List; +import java.util.Objects; +import java.util.Random; + +import static com.connorcode.sigmautils.SigmaUtils.client; + +@ModuleInfo(description = "Uses random textures for the background tessellation", documentation = "It will change every time you open a new screen.") +public class RandomBackground extends Module { + static final List validBackgrounds = new BufferedReader(new InputStreamReader(Objects.requireNonNull(SigmaUtils.class.getClassLoader() + .getResourceAsStream("assets/sigma-utils/background_blocks.txt")))).lines().toList(); + static EnumSetting filterType = Util.filterSetting(RandomBackground.class) + .description("Whether to blacklist or whitelist background textures.").value(Util.FilterType.Blacklist) + .build(); + static DynamicListSetting textures = new DynamicListSetting<>(RandomBackground.class, "Textures", BlockList::new).description("Possible background textures.") + .build(); + static String asset; + static int screenHash = -1; + + public static Identifier getTexture() { + int currentScreenHash = Objects.requireNonNull(Objects.requireNonNull(client).currentScreen).hashCode(); + + if (screenHash != currentScreenHash || asset == null) { + screenHash = currentScreenHash; + + List valid = switch (filterType.value()) { + case Whitelist -> + textures.value().stream().map(block -> Registries.BLOCK.getId(block).getPath()).toList(); + case Blacklist -> validBackgrounds.stream().filter(s -> !textures.value() + .contains(Registries.BLOCK.get(Identifier.tryParse("minecraft:" + s)))).toList(); + }; + + var assetIndex = new Random().nextInt(valid.size()); + asset = valid.get(assetIndex); + } + + return Identifier.tryParse("textures/block/" + asset + ".png"); + } + + static class BlockList extends SimpleList { + + public BlockList(DynamicListSetting setting) { + super(setting, Registries.BLOCK); + } + + @Override + public String getDisplay(Block value) { + return value.getName().getString(); + } + + @Override + public boolean renderSelector(Block resource, Screen screen, int x, int y) { + var rawId = Registries.BLOCK.getId(resource).getPath(); + var id = Identifier.tryParse("textures/block/" + rawId + ".png"); + if (!RandomBackground.validBackgrounds.contains(rawId) || this.setting.value().contains(resource)) + return false; + Util.addDrawable(screen, new Components.DrawableElement() { + @Override + public void render(DrawContext context, int mouseX, int mouseY, float delta) { + context.drawTexture(id, x - 1, y + 2, 0, 0.0F, 0.0F, 16, 16, 16, 16); + } + }); + return super.renderSelector(resource, screen, x + 16, y); + } + } +} diff --git a/src/main/java/com/connorcode/sigmautils/modules/misc/TickSpeed.java b/src/main/java/com/connorcode/sigmautils/modules/misc/TickSpeed.java index 030554e..3d780cb 100644 --- a/src/main/java/com/connorcode/sigmautils/modules/misc/TickSpeed.java +++ b/src/main/java/com/connorcode/sigmautils/modules/misc/TickSpeed.java @@ -23,14 +23,9 @@ Text getSliderTitle() { return Text.of(String.format("Tick Speed: %d [%d%%]", mspt.intValue(), Math.round((100 - mspt.value()) / .5))); } - void setTickSpeed(long mspt) { - // TODO - } - void setTickSpeedFromPercent(double percent) { mspt.value(50d * (percent * 2d)); mspt.value(Math.max(mspt.intValue(), 1)); - if (enabled) setTickSpeed(mspt.intValue()); } public void drawInterface(MinecraftClient client, Screen screen, int x, int y) { @@ -55,12 +50,4 @@ protected void applyValue() { } }); } - - public void enable(MinecraftClient client) { - setTickSpeed(mspt.intValue()); - } - - public void disable(MinecraftClient client) { - setTickSpeed(50); - } } diff --git a/src/main/resources/modules/modules.json b/src/main/resources/modules/modules.json index ff2c601..e77f077 100644 --- a/src/main/resources/modules/modules.json +++ b/src/main/resources/modules/modules.json @@ -12,6 +12,7 @@ "_interface.NoChatFade", "_interface.NoScoreboardValue", "_interface.PortalInventory", + "_interface.RandomBackground", "_interface.SeeThruLoading", "_interface.SignClickThrough", "_interface.SplashRefresh", @@ -58,7 +59,6 @@ "misc.SoundControl", "misc.TickSpeed", "misc.WindowTitle", - "rendering.MapBorder", "rendering.AllowShowBarrier", "rendering.Deadmau5Ears", "rendering.DebugRenderers", @@ -68,6 +68,7 @@ "rendering.FlippedEntities", "rendering.FullBright", "rendering.LightLevel", + "rendering.MapBorder", "rendering.NoArmor", "rendering.NoBreakParticles", "rendering.NoDarkSky", diff --git a/src/main/resources/sigma-utils.mixins.json b/src/main/resources/sigma-utils.mixins.json index b95c6f2..e0f123d 100644 --- a/src/main/resources/sigma-utils.mixins.json +++ b/src/main/resources/sigma-utils.mixins.json @@ -47,6 +47,7 @@ "RecipeBookWidgetMixin", "RenderTickCounter$DynamicMixin", "ScreenAccessor", + "ScreenMixin", "SimpleOptionAccessor", "SoundSystemMixin", "SplashTextResourceSupplierMixin", From 1e8f039a7ed7d720fab74d572f5650074a0028e6 Mon Sep 17 00:00:00 2001 From: Connor Slade Date: Sat, 29 Jun 2024 01:15:49 -0400 Subject: [PATCH 17/17] Real world bug fixes - Incorrect effect names - Opaque invis entities - Not fireing unknown packet events --- .../connorcode/sigmautils/misc/Consts.java | 7 ++++++ .../ClientCommonNetworkHandlerMixin.java | 20 ++++------------ .../mixin/LivingEntityRendererMixin.java | 17 ++++++++++++-- .../sigmautils/mixin/OptionsScreenMixin.java | 1 + .../mixin/UnknownCustomPayloadMixin.java | 23 +++++++++++++++++++ .../sigmautils/modules/hud/EffectHud.java | 5 +++- src/main/resources/sigma-utils.mixins.json | 5 +++- 7 files changed, 58 insertions(+), 20 deletions(-) create mode 100644 src/main/java/com/connorcode/sigmautils/misc/Consts.java create mode 100644 src/main/java/com/connorcode/sigmautils/mixin/UnknownCustomPayloadMixin.java diff --git a/src/main/java/com/connorcode/sigmautils/misc/Consts.java b/src/main/java/com/connorcode/sigmautils/misc/Consts.java new file mode 100644 index 0000000..bc040a7 --- /dev/null +++ b/src/main/java/com/connorcode/sigmautils/misc/Consts.java @@ -0,0 +1,7 @@ +package com.connorcode.sigmautils.misc; + +import net.minecraft.util.Identifier; + +public class Consts { + public static final Identifier DUMMY_IDENT = Identifier.ofVanilla("dummy"); +} diff --git a/src/main/java/com/connorcode/sigmautils/mixin/ClientCommonNetworkHandlerMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/ClientCommonNetworkHandlerMixin.java index 3b7c62b..6bd7ccd 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/ClientCommonNetworkHandlerMixin.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/ClientCommonNetworkHandlerMixin.java @@ -7,24 +7,12 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import static com.connorcode.sigmautils.misc.Consts.DUMMY_IDENT; + @Mixin(ClientCommonNetworkHandler.class) public class ClientCommonNetworkHandlerMixin { - @Inject(method = "onCustomPayload", at = @At("HEAD")) + @Inject(method = "onCustomPayload(Lnet/minecraft/network/packet/s2c/common/CustomPayloadS2CPacket;)V", at = @At("HEAD"), cancellable = true) void onCustomPayload(CustomPayloadS2CPacket packet, CallbackInfo ci) { -// var buf = packet.getPayload(); -// var event = new UnknownPacketEvent(buf, packet.payload().getId().id()); - System.out.println("CUSTOM PAYLOAD:" + packet.payload().getClass().getSimpleName()); + if (packet.payload().getId().id() == DUMMY_IDENT) ci.cancel(); } } - - -// @Inject(method = "readPayload", at = @At("HEAD"), cancellable = true) -// private static void onReadPayload(Identifier id, PacketByteBuf buf, CallbackInfoReturnable cir) { -// if (ID_TO_READER.containsKey(id)) return; -// -// var event = new UnknownPacketEvent(buf, id); -// SigmaUtils.eventBus.post(event); -// -// if (event.isCancelled()) cir.setReturnValue(new CancelledUnknownPacket(id)); -// else cir.setReturnValue(readUnknownPayload(id, buf)); -// } \ No newline at end of file diff --git a/src/main/java/com/connorcode/sigmautils/mixin/LivingEntityRendererMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/LivingEntityRendererMixin.java index 794e132..6c175e5 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/LivingEntityRendererMixin.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/LivingEntityRendererMixin.java @@ -2,19 +2,32 @@ import com.connorcode.sigmautils.config.Config; import com.connorcode.sigmautils.modules.rendering.FlippedEntities; +import com.connorcode.sigmautils.modules.rendering.ShowInvisibleEntities; import net.minecraft.client.render.entity.LivingEntityRenderer; import net.minecraft.client.render.entity.model.EntityModel; import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(LivingEntityRenderer.class) public class LivingEntityRendererMixin> { @Inject(method = "shouldFlipUpsideDown", at = @At("HEAD"), cancellable = true) private static void shouldFlipUpsideDown(LivingEntity entity, CallbackInfoReturnable cir) { - if (Config.getEnabled(FlippedEntities.class) && FlippedEntities.isFlipped(entity)) - cir.setReturnValue(true); + if (Config.getEnabled(FlippedEntities.class) && FlippedEntities.isFlipped(entity)) cir.setReturnValue(true); + } + + @Redirect(method = "render(Lnet/minecraft/entity/LivingEntity;FFLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/entity/LivingEntityRenderer;isVisible(Lnet/minecraft/entity/LivingEntity;)Z")) + boolean isVisible(LivingEntityRenderer livingEntityRenderer, T entity) { + return !entity.getFlag(5); + } + + @Redirect(method = "render(Lnet/minecraft/entity/LivingEntity;FFLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;isInvisibleTo(Lnet/minecraft/entity/player/PlayerEntity;)Z")) + boolean isVisibleTo(LivingEntity instance, PlayerEntity playerEntity) { + if (Config.getEnabled(ShowInvisibleEntities.class) && ShowInvisibleEntities.isVisible(instance)) return false; + return instance.isInvisibleTo(playerEntity); } } diff --git a/src/main/java/com/connorcode/sigmautils/mixin/OptionsScreenMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/OptionsScreenMixin.java index 3312373..d3a645e 100644 --- a/src/main/java/com/connorcode/sigmautils/mixin/OptionsScreenMixin.java +++ b/src/main/java/com/connorcode/sigmautils/mixin/OptionsScreenMixin.java @@ -26,6 +26,7 @@ public class OptionsScreenMixin extends Screen { @Unique void positionButton() { + if (soundButton == null) return; muteButton.setX(soundButton.getX() + soundButton.getWidth() + 5); muteButton.setY(soundButton.getY()); } diff --git a/src/main/java/com/connorcode/sigmautils/mixin/UnknownCustomPayloadMixin.java b/src/main/java/com/connorcode/sigmautils/mixin/UnknownCustomPayloadMixin.java new file mode 100644 index 0000000..f57f756 --- /dev/null +++ b/src/main/java/com/connorcode/sigmautils/mixin/UnknownCustomPayloadMixin.java @@ -0,0 +1,23 @@ +package com.connorcode.sigmautils.mixin; + +import com.connorcode.sigmautils.SigmaUtils; +import com.connorcode.sigmautils.event.network.UnknownPacketEvent; +import net.minecraft.network.PacketByteBuf; +import net.minecraft.network.packet.UnknownCustomPayload; +import net.minecraft.util.Identifier; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import static com.connorcode.sigmautils.misc.Consts.DUMMY_IDENT; + +@Mixin(UnknownCustomPayload.class) +public class UnknownCustomPayloadMixin { + @Inject(method = "method_56491(ILnet/minecraft/util/Identifier;Lnet/minecraft/network/PacketByteBuf;)Lnet/minecraft/network/packet/UnknownCustomPayload;", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/PacketByteBuf;skipBytes(I)Lnet/minecraft/network/PacketByteBuf;", shift = At.Shift.BEFORE), cancellable = true) + private static void onUnknownCustomPayload(int i, Identifier identifier, PacketByteBuf buf, CallbackInfoReturnable cir) { + var event = new UnknownPacketEvent(buf, identifier); + SigmaUtils.eventBus.post(event); + if (event.isCancelled()) cir.setReturnValue(new UnknownCustomPayload(DUMMY_IDENT)); + } +} diff --git a/src/main/java/com/connorcode/sigmautils/modules/hud/EffectHud.java b/src/main/java/com/connorcode/sigmautils/modules/hud/EffectHud.java index 31a7171..0bcad61 100644 --- a/src/main/java/com/connorcode/sigmautils/modules/hud/EffectHud.java +++ b/src/main/java/com/connorcode/sigmautils/modules/hud/EffectHud.java @@ -6,6 +6,7 @@ import net.minecraft.entity.effect.StatusEffect; import net.minecraft.entity.effect.StatusEffectInstance; import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.text.Text; import java.util.ArrayList; import java.util.List; @@ -28,7 +29,9 @@ public List lines() { Map, StatusEffectInstance> effectMap = Objects.requireNonNull(client.player).getActiveStatusEffects(); for (var i : effectMap.entrySet()) { - out.add(String.format("§r%sEffect: §f%s %d %ds", color, i.getKey().value(), i.getValue().getAmplifier() + 1, i.getValue().getDuration() / 20)); + var name = Text.translatable(i.getValue().getTranslationKey()).getString(); + out.add(String.format("§r%sEffect: §f%s %d %ds", color, name, i.getValue().getAmplifier() + 1, i.getValue() + .getDuration() / 20)); } return out; diff --git a/src/main/resources/sigma-utils.mixins.json b/src/main/resources/sigma-utils.mixins.json index e0f123d..f54e557 100644 --- a/src/main/resources/sigma-utils.mixins.json +++ b/src/main/resources/sigma-utils.mixins.json @@ -61,5 +61,8 @@ ], "injectors": { "defaultRequire": 1 - } + }, + "mixins": [ + "UnknownCustomPayloadMixin" + ] }