From de6a87e338d33fe26e7620680ed3bd48574b70b9 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Sat, 16 Dec 2023 15:32:48 -0800 Subject: [PATCH] Apply patches for 1.20.4 - Compile needs to be checked. - Behaviors around the new tick manager need to be designed and implemented. Chk update.txt for anything specific. --- build.gradle.kts | 4 +- gradle.properties | 6 +- gradle/wrapper/gradle-wrapper.jar | Bin 63721 -> 43462 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- patches/api/0002-Region-scheduler-API.patch | 2 +- ...king-ownership-of-region-by-position.patch | 4 +- patches/server/0001-Build-changes.patch | 18 +- patches/server/0003-Threaded-Regions.patch | 2161 +++++++++-------- patches/server/0004-Max-pending-logins.patch | 8 +- ...-getHandle-and-overrides-perform-thr.patch | 44 +- ...0007-Disable-mid-tick-task-execution.patch | 6 +- ...edOperationException-for-broken-APIs.patch | 16 +- ...dates-in-non-loaded-or-non-owned-chu.patch | 16 +- ...access-when-waking-players-up-during.patch | 8 +- ...ition-to-player-position-on-player-d.patch | 4 +- patches/server/0018-Region-profiler.patch | 232 +- update.txt | 2 + 17 files changed, 1301 insertions(+), 1232 deletions(-) create mode 100644 update.txt diff --git a/build.gradle.kts b/build.gradle.kts index 817a526..7221162 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,7 +4,7 @@ plugins { java `maven-publish` id("com.github.johnrengelman.shadow") version "8.1.1" apply false - id("io.papermc.paperweight.patcher") version "1.5.9" + id("io.papermc.paperweight.patcher") version "1.5.11" } val paperMavenPublicUrl = "https://repo.papermc.io/repository/maven-public/" @@ -17,7 +17,7 @@ repositories { } dependencies { - remapper("net.fabricmc:tiny-remapper:0.8.6:fat") + remapper("net.fabricmc:tiny-remapper:0.8.10:fat") decompiler("net.minecraftforge:forgeflower:2.0.627.2") paperclip("io.papermc:paperclip:3.0.3") } diff --git a/gradle.properties b/gradle.properties index c225a6c..438c33d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,8 +1,8 @@ group=dev.folia -version=1.20.2-R0.1-SNAPSHOT -mcVersion=1.20.2 -paperRef=ce7f0680956bb1c779ac4db9fe0fd1f00bb35bae +version=1.20.4-R0.1-SNAPSHOT +mcVersion=1.20.4 +paperRef=f1820dc80a02009980e6466ea5847933861b911a org.gradle.caching=true org.gradle.parallel=true diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7f93135c49b765f8051ef9d0a6055ff8e46073d8..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 63721 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鯊%1Et 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⁢ zv5o9#E7!G0XmdzfsS{efPNi`1b44~SZ4Z8fuX!I}#8g+(wxzQwUT#Xb2(tbY1+EUhGKoT@KEU9Ktl>_0 z%bjDJg;#*gtJZv!-Zs`?^}v5eKmnbjqlvnSzE@_SP|LG_PJ6CYU+6zY6>92%E+ z=j@TZf-iW4(%U{lnYxQA;7Q!b;^brF8n0D>)`q5>|WDDXLrqYU_tKN2>=#@~OE7grMnNh?UOz-O~6 z6%rHy{#h9K0AT+lDC7q4{hw^|q6*Ry;;L%Q@)Ga}$60_q%D)rv(CtS$CQbpq9|y1e zRSrN4;$Jyl{m5bZw`$8TGvb}(LpY{-cQ)fcyJv7l3S52TLXVDsphtv&aPuDk1OzCA z4A^QtC(!11`IsNx_HnSy?>EKpHJWT^wmS~hc^p^zIIh@9f6U@I2 zC=Mve{j2^)mS#U$e{@Q?SO6%LDsXz@SY+=cK_QMmXBIU)j!$ajc-zLx3V60EXJ!qC zi<%2x8Q24YN+&8U@CIlN zrZkcT9yh%LrlGS9`G)KdP(@9Eo-AQz@8GEFWcb7U=a0H^ZVbLmz{+&M7W(nXJ4sN8 zJLR7eeK(K8`2-}j(T7JsO`L!+CvbueT%izanm-^A1Dn{`1Nw`9P?cq;7no+XfC`K(GO9?O^5zNIt4M+M8LM0=7Gz8UA@Z0N+lg+cX)NfazRu z5D)~HA^(u%w^cz+@2@_#S|u>GpB+j4KzQ^&Wcl9f z&hG#bCA(Yk0D&t&aJE^xME^&E-&xGHhXn%}psEIj641H+Nl-}boj;)Zt*t(4wZ5DN z@GXF$bL=&pBq-#vkTkh>7hl%K5|3 z{`Vn9b$iR-SoGENp}bn4;fR3>9sA%X2@1L3aE9yTra;Wb#_`xWwLSLdfu+PAu+o3| zGVnpzPr=ch{uuoHjtw7+_!L_2;knQ!DuDl0R`|%jr+}jFzXtrHIKc323?JO{l&;VF z*L1+}JU7%QJOg|5|Tc|D8fN zJORAg=_vsy{ak|o);@)Yh8Lkcg@$FG3k@ep36BRa^>~UmnRPziS>Z=`Jb2x*Q#`%A zU*i3&Vg?TluO@X0O;r2Jl6LKLUOVhSqg1*qOt^|8*c7 zo(298@+r$k_wQNGHv{|$tW(T8L+4_`FQ{kEW5Jgg{yf7ey4ss_(SNKfz(N9lx&a;< je(UuV8hP?p&}TPdm1I$XmG#(RzlD&B2izSj9sl%y5~4qc diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 3fa8f86..1af9e09 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/patches/api/0002-Region-scheduler-API.patch b/patches/api/0002-Region-scheduler-API.patch index ad879bc..0c50c05 100644 --- a/patches/api/0002-Region-scheduler-API.patch +++ b/patches/api/0002-Region-scheduler-API.patch @@ -23,7 +23,7 @@ index fc2dae69165776d08274e34a69962cc70445f411..06149045a44148bf0af5f52952ff0092 } diff --git a/src/main/java/org/bukkit/scheduler/BukkitScheduler.java b/src/main/java/org/bukkit/scheduler/BukkitScheduler.java -index d2ab2ee1e1e8fbaac4edef5b3ee313ee4ceb6991..8476504e3d54721c64f02eddd5b48193ac8f366b 100644 +index 487b5ca23159b531475c3d650894be707b49914e..31b90d1c2259a8f200b0589909dbbfe4cc526989 100644 --- a/src/main/java/org/bukkit/scheduler/BukkitScheduler.java +++ b/src/main/java/org/bukkit/scheduler/BukkitScheduler.java @@ -7,6 +7,15 @@ import java.util.function.Consumer; diff --git a/patches/api/0005-Add-API-for-checking-ownership-of-region-by-position.patch b/patches/api/0005-Add-API-for-checking-ownership-of-region-by-position.patch index c14b660..19be254 100644 --- a/patches/api/0005-Add-API-for-checking-ownership-of-region-by-position.patch +++ b/patches/api/0005-Add-API-for-checking-ownership-of-region-by-position.patch @@ -11,7 +11,7 @@ the schedulers depending on the result of the ownership check. diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index 884902cb7f86c0b56594ccafc7d05c6c7a23ab53..b7e1c8bd8dd38e1a9e74925740b22dad61a75f49 100644 +index 4863d9f21f0a0f11974be85360edc587ffd7eab3..56548d416cb116b0f130a18a3c0ee8aed51a7be0 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java @@ -2827,6 +2827,14 @@ public final class Bukkit { @@ -30,7 +30,7 @@ index 884902cb7f86c0b56594ccafc7d05c6c7a23ab53..b7e1c8bd8dd38e1a9e74925740b22dad @NotNull public static Server.Spigot spigot() { diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index d0c634629aa0b6bac0da93655dd86ad3aea0ce30..85b169c04f44431363d4e14d4857140f160ceace 100644 +index f1fa97d12f97baf97beb92ca0719cf3cf906b225..e25f86fb8d4bda9284744c0b8ae7db4f4f9f93a0 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java @@ -2473,4 +2473,10 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi diff --git a/patches/server/0001-Build-changes.patch b/patches/server/0001-Build-changes.patch index a82de93..f8997d9 100644 --- a/patches/server/0001-Build-changes.patch +++ b/patches/server/0001-Build-changes.patch @@ -5,13 +5,13 @@ Subject: [PATCH] Build changes diff --git a/build.gradle.kts b/build.gradle.kts -index 79beac737c17412913983614bd478d33e3c6ed58..0cd12a854e544e867abfd94c18a9f138ba57e587 100644 +index 170a915098f09ace226648da342a04c5c7583d11..512496d086b21bd0d5c5cc070a41185eedc6c2f1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -13,8 +13,12 @@ configurations.named(log4jPlugins.compileClasspathConfigurationName) { - val alsoShade: Configuration by configurations.creating +@@ -27,8 +27,12 @@ repositories { dependencies { + extraRuntime(platform("net.kyori:adventure-bom:4.15.0-SNAPSHOT")) - implementation(project(":paper-api")) - implementation(project(":paper-mojangapi")) + // Folia start @@ -23,7 +23,7 @@ index 79beac737c17412913983614bd478d33e3c6ed58..0cd12a854e544e867abfd94c18a9f138 // Paper start implementation("org.jline:jline-terminal-jansi:3.21.0") implementation("net.minecrell:terminalconsoleappender:1.3.0") -@@ -70,7 +74,7 @@ tasks.jar { +@@ -84,7 +88,7 @@ tasks.jar { attributes( "Main-Class" to "org.bukkit.craftbukkit.Main", "Implementation-Title" to "CraftBukkit", @@ -32,7 +32,7 @@ index 79beac737c17412913983614bd478d33e3c6ed58..0cd12a854e544e867abfd94c18a9f138 "Implementation-Vendor" to date, // Paper "Specification-Title" to "Bukkit", "Specification-Version" to project.version, -@@ -154,7 +158,7 @@ fun TaskContainer.registerRunTask( +@@ -168,7 +172,7 @@ fun TaskContainer.registerRunTask( name: String, block: JavaExec.() -> Unit ): TaskProvider = register(name) { @@ -93,10 +93,10 @@ index 9d687da5bdf398bb3f6c84cdf1249a7213d09f2e..e2f704c115fd6e00960bb56bb0779f11 ).openBufferedStream()) { JsonObject json = new Gson().fromJson(reader, JsonObject.class); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 8f31413c939cc2b0454ad3d9a1b618dbae449d00..6758e3ff1100bba2852e44cbb0b38ce4f22490e8 100644 +index 34f19ac897a30c0c4e3ab406013fcca1c8b7db93..5ed6c8710b78458031ed6b0273fb2f6a5f482ea7 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1697,7 +1697,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop= 5000000000L) { ++ if (currtime - this.lastServerStatus >= MinecraftServer.STATUS_EXPIRE_TIME_NANOS) { + this.lastServerStatus = currtime; + mcServer.rebuildServerStatus(); + } @@ -8806,10 +8806,10 @@ index e08f4e39db4ee3fed62e37364d17dcc5c5683504..7e92e14cdb9f3d895550991b2ea154a6 } } diff --git a/src/main/java/io/papermc/paper/util/CollisionUtil.java b/src/main/java/io/papermc/paper/util/CollisionUtil.java -index bfb1de19f53d5d7c7b65e25a606fabfa416706b3..61e51d68df3bc5be3622c32025af9cb418b4ca75 100644 +index 5d4c5cc8eb06f2e6c31df6cbb98ea642b2264d49..0f74d6d64437150ad8f154354162f6ffe0532180 100644 --- a/src/main/java/io/papermc/paper/util/CollisionUtil.java +++ b/src/main/java/io/papermc/paper/util/CollisionUtil.java -@@ -1648,7 +1648,7 @@ public final class CollisionUtil { +@@ -1650,7 +1650,7 @@ public final class CollisionUtil { for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) { for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) { @@ -8863,10 +8863,10 @@ index 413e4b6da027876dbbe8eb78f2568a440f431547..3a7dbcb9964723b8ed5e6b0a1ee42679 throw new RuntimeException(); } diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java -index 8240bb085b619f257f8c0a25775e0b15068e440f..8f91b7f44baaf62b829a81afc0633311e6c13f19 100644 +index 200ed770b57e1a9240abf0473968d4b85cbefe3c..1f0ec6add54b7503415d5f4141fe2b6046f1ec69 100644 --- a/src/main/java/io/papermc/paper/util/MCUtil.java +++ b/src/main/java/io/papermc/paper/util/MCUtil.java -@@ -336,6 +336,7 @@ public final class MCUtil { +@@ -335,6 +335,7 @@ public final class MCUtil { */ public static void ensureMain(String reason, Runnable run) { if (!isMainThread()) { @@ -8874,7 +8874,7 @@ index 8240bb085b619f257f8c0a25775e0b15068e440f..8f91b7f44baaf62b829a81afc0633311 if (reason != null) { MinecraftServer.LOGGER.warn("Asynchronous " + reason + "!", new IllegalStateException()); } -@@ -476,6 +477,30 @@ public final class MCUtil { +@@ -475,6 +476,30 @@ public final class MCUtil { return new Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()); } @@ -9350,23 +9350,23 @@ index 0000000000000000000000000000000000000000..cf9b66afc1762dbe2c625f09f9e804ca + } +} diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/main/java/net/minecraft/commands/CommandSourceStack.java -index 56ae02aab93b9a698e9d2f07a0448aa4767169d9..4e196b4e7bc8ac6da8d3e61e68bdf461c7ea821f 100644 +index 14f4c0a93372a58cf36dc95265b5e210ea1605e5..b0d68a04b185c37659e7b42dd931b6d288970b2d 100644 --- a/src/main/java/net/minecraft/commands/CommandSourceStack.java +++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java -@@ -69,7 +69,7 @@ public class CommandSourceStack implements SharedSuggestionProvider, com.destroy +@@ -68,7 +68,7 @@ public class CommandSourceStack implements ExecutionCommandSource { -- }, EntityAnchorArgument.Anchor.FEET, CommandSigningContext.ANONYMOUS, TaskChainer.immediate(server), (j) -> { -+ }, EntityAnchorArgument.Anchor.FEET, CommandSigningContext.ANONYMOUS, TaskChainer.immediate((Runnable run) -> { io.papermc.paper.threadedregions.RegionizedServer.getInstance().addTask(run);}), (j) -> { // Folia - region threading - }); +- this(output, pos, rot, world, level, name, displayName, server, entity, false, CommandResultCallback.EMPTY, EntityAnchorArgument.Anchor.FEET, CommandSigningContext.ANONYMOUS, TaskChainer.immediate(server)); ++ this(output, pos, rot, world, level, name, displayName, server, entity, false, CommandResultCallback.EMPTY, EntityAnchorArgument.Anchor.FEET, CommandSigningContext.ANONYMOUS, TaskChainer.immediate((Runnable run) -> { io.papermc.paper.threadedregions.RegionizedServer.getInstance().addTask(run);})); // Folia - region threading } + protected CommandSourceStack(CommandSource output, Vec3 pos, Vec2 rot, ServerLevel world, int level, String name, Component displayName, MinecraftServer server, @Nullable Entity entity, boolean silent, CommandResultCallback resultStorer, EntityAnchorArgument.Anchor entityAnchor, CommandSigningContext signedArguments, TaskChainer messageChainTaskQueue) { diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java -index 3eec879bf3975636739b2491cc05b8177032d16d..3435bdeaf723c64103f7c924ea42a4ec78f2ba01 100644 +index 55f3f5396dac2b0bb0cc37b537547e9245042100..d94771b6e36b21ce9dcecfee56682f54576446da 100644 --- a/src/main/java/net/minecraft/commands/Commands.java +++ b/src/main/java/net/minecraft/commands/Commands.java -@@ -146,13 +146,13 @@ public class Commands { +@@ -159,13 +159,13 @@ public class Commands { AdvancementCommands.register(this.dispatcher); AttributeCommand.register(this.dispatcher, commandRegistryAccess); ExecuteCommand.register(this.dispatcher, commandRegistryAccess); @@ -9385,7 +9385,7 @@ index 3eec879bf3975636739b2491cc05b8177032d16d..3435bdeaf723c64103f7c924ea42a4ec DefaultGameModeCommands.register(this.dispatcher); DifficultyCommand.register(this.dispatcher); EffectCommands.register(this.dispatcher, commandRegistryAccess); -@@ -162,47 +162,47 @@ public class Commands { +@@ -175,46 +175,46 @@ public class Commands { FillCommand.register(this.dispatcher, commandRegistryAccess); FillBiomeCommand.register(this.dispatcher, commandRegistryAccess); ForceLoadCommand.register(this.dispatcher); @@ -9438,17 +9438,15 @@ index 3eec879bf3975636739b2491cc05b8177032d16d..3435bdeaf723c64103f7c924ea42a4ec + //TeamMsgCommand.register(this.dispatcher); // Folia - region threading - TODO later TeleportCommand.register(this.dispatcher); TellRawCommand.register(this.dispatcher); + TickCommand.register(this.dispatcher); TimeCommand.register(this.dispatcher); TitleCommand.register(this.dispatcher); - TriggerCommand.register(this.dispatcher); + //TriggerCommand.register(this.dispatcher); // Folia - region threading - TODO later WeatherCommand.register(this.dispatcher); -- WorldBorderCommand.register(this.dispatcher); -+ //WorldBorderCommand.register(this.dispatcher); // Folia - region threading - TODO later + WorldBorderCommand.register(this.dispatcher); if (JvmProfiler.INSTANCE.isAvailable()) { - JfrCommand.register(this.dispatcher); - } -@@ -223,8 +223,8 @@ public class Commands { +@@ -243,8 +243,8 @@ public class Commands { OpCommand.register(this.dispatcher); PardonCommand.register(this.dispatcher); PardonIpCommand.register(this.dispatcher); @@ -9459,7 +9457,7 @@ index 3eec879bf3975636739b2491cc05b8177032d16d..3435bdeaf723c64103f7c924ea42a4ec SaveOffCommand.register(this.dispatcher); SaveOnCommand.register(this.dispatcher); SetPlayerIdleTimeoutCommand.register(this.dispatcher); -@@ -454,9 +454,12 @@ public class Commands { +@@ -508,9 +508,12 @@ public class Commands { } // Paper start - Async command map building new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendCommandsEvent(player.getBukkitEntity(), (RootCommandNode) rootcommandnode, false).callEvent(); // Paper @@ -9489,10 +9487,10 @@ index 155bd3d6d9c7d3cac7fd04de8210301251d1e17a..446f590dcf8f1d30b365e71515683c9a } diff --git a/src/main/java/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java -index 80dbeb0a988c749feaaba26ce5ad93c181d88a5d..e92d8c8f6b208642e87cdb4080d3b38f95d84503 100644 +index 6df0db8b4cdab23494ea34236949ece4989110a3..2fd670d941bd575f99def28732ffee29f37a3182 100644 --- a/src/main/java/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java -@@ -62,7 +62,7 @@ public class BoatDispenseItemBehavior extends DefaultDispenseItemBehavior { +@@ -63,7 +63,7 @@ public class BoatDispenseItemBehavior extends DefaultDispenseItemBehavior { CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d1, d2 + d4, d3)); @@ -9502,10 +9500,10 @@ index 80dbeb0a988c749feaaba26ce5ad93c181d88a5d..e92d8c8f6b208642e87cdb4080d3b38f } diff --git a/src/main/java/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java -index 379890ae05b2fb4bd81b2fa907413d3736ba1169..4ea33c913b005d81a600215ac35a644ee1396cb3 100644 +index 6c78d90e73b47b62c4052727730850d4b67a9cd2..22bd34cf8994082e1b33d58f21ae86219d642b33 100644 --- a/src/main/java/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java -@@ -74,7 +74,7 @@ public class DefaultDispenseItemBehavior implements DispenseItemBehavior { +@@ -85,7 +85,7 @@ public class DefaultDispenseItemBehavior implements DispenseItemBehavior { CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), CraftVector.toBukkit(entityitem.getDeltaMovement())); @@ -9515,7 +9513,7 @@ index 379890ae05b2fb4bd81b2fa907413d3736ba1169..4ea33c913b005d81a600215ac35a644e } diff --git a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java -index a0c7c6208314d981e8577ad69ef1c5193290a085..f0c2ee38e9101a6c593f6deb6b8101b72ad4a067 100644 +index e6ac20a38f31bb0cd6b8840b2518f6992ef7f518..97a1a99258536f4d2d671964d0eaf8f865190e8a 100644 --- a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java @@ -222,7 +222,7 @@ public interface DispenseItemBehavior { @@ -9590,7 +9588,7 @@ index a0c7c6208314d981e8577ad69ef1c5193290a085..f0c2ee38e9101a6c593f6deb6b8101b7 worldserver.getCraftServer().getPluginManager().callEvent(event); } -@@ -707,7 +707,7 @@ public interface DispenseItemBehavior { +@@ -708,7 +708,7 @@ public interface DispenseItemBehavior { CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack.copyWithCount(1)); // Paper - single item in event BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); @@ -9599,7 +9597,7 @@ index a0c7c6208314d981e8577ad69ef1c5193290a085..f0c2ee38e9101a6c593f6deb6b8101b7 worldserver.getCraftServer().getPluginManager().callEvent(event); } -@@ -754,7 +754,7 @@ public interface DispenseItemBehavior { +@@ -755,7 +755,7 @@ public interface DispenseItemBehavior { CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack); BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); @@ -9608,7 +9606,7 @@ index a0c7c6208314d981e8577ad69ef1c5193290a085..f0c2ee38e9101a6c593f6deb6b8101b7 worldserver.getCraftServer().getPluginManager().callEvent(event); } -@@ -815,7 +815,7 @@ public interface DispenseItemBehavior { +@@ -818,7 +818,7 @@ public interface DispenseItemBehavior { CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack.copyWithCount(1)); // Paper - single item in event BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); @@ -9617,7 +9615,7 @@ index a0c7c6208314d981e8577ad69ef1c5193290a085..f0c2ee38e9101a6c593f6deb6b8101b7 worldserver.getCraftServer().getPluginManager().callEvent(event); } -@@ -833,7 +833,8 @@ public interface DispenseItemBehavior { +@@ -837,7 +837,8 @@ public interface DispenseItemBehavior { } } @@ -9627,7 +9625,7 @@ index a0c7c6208314d981e8577ad69ef1c5193290a085..f0c2ee38e9101a6c593f6deb6b8101b7 // CraftBukkit end if (!BoneMealItem.growCrop(stack, worldserver, blockposition) && !BoneMealItem.growWaterPlant(stack, worldserver, blockposition, (Direction) null)) { -@@ -842,13 +843,13 @@ public interface DispenseItemBehavior { +@@ -846,13 +847,13 @@ public interface DispenseItemBehavior { worldserver.levelEvent(1505, blockposition, 0); } // CraftBukkit start @@ -9647,7 +9645,7 @@ index a0c7c6208314d981e8577ad69ef1c5193290a085..f0c2ee38e9101a6c593f6deb6b8101b7 StructureGrowEvent structureEvent = null; if (treeType != null) { structureEvent = new StructureGrowEvent(location, treeType, false, null, blocks); -@@ -884,7 +885,7 @@ public interface DispenseItemBehavior { +@@ -888,7 +889,7 @@ public interface DispenseItemBehavior { CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector((double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D)); @@ -9656,7 +9654,7 @@ index a0c7c6208314d981e8577ad69ef1c5193290a085..f0c2ee38e9101a6c593f6deb6b8101b7 worldserver.getCraftServer().getPluginManager().callEvent(event); } -@@ -941,7 +942,7 @@ public interface DispenseItemBehavior { +@@ -945,7 +946,7 @@ public interface DispenseItemBehavior { CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack.copyWithCount(1)); // Paper - single item in event BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); @@ -9665,7 +9663,7 @@ index a0c7c6208314d981e8577ad69ef1c5193290a085..f0c2ee38e9101a6c593f6deb6b8101b7 worldserver.getCraftServer().getPluginManager().callEvent(event); } -@@ -990,7 +991,7 @@ public interface DispenseItemBehavior { +@@ -996,7 +997,7 @@ public interface DispenseItemBehavior { CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack.copyWithCount(1)); // Paper - single item in event BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); @@ -9674,7 +9672,7 @@ index a0c7c6208314d981e8577ad69ef1c5193290a085..f0c2ee38e9101a6c593f6deb6b8101b7 worldserver.getCraftServer().getPluginManager().callEvent(event); } -@@ -1063,7 +1064,7 @@ public interface DispenseItemBehavior { +@@ -1070,7 +1071,7 @@ public interface DispenseItemBehavior { CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack.copyWithCount(1)); // Paper - only single item in event BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); @@ -10040,10 +10038,10 @@ index c0ea20dcee8bb293df96bc6ee019e50ad6b383fd..b84e9d5ae5efe1a8257a5f1f78a0ab66 private static class InnerUtil { // Attempt to hide these methods from ProtocolLib, so it doesn't accidently pick them up. diff --git a/src/main/java/net/minecraft/network/protocol/PacketUtils.java b/src/main/java/net/minecraft/network/protocol/PacketUtils.java -index 9a49f5271ec1d9de17632bfffe8309cb1ba0d8b1..c06bed93f6a701b1639c1cc334802e7b802431a5 100644 +index c5c734b9eb80d1cdf0e9fd8a043f2b6d1f4cbffe..98fb69a9adeb6eaab199aec127692acb07f56808 100644 --- a/src/main/java/net/minecraft/network/protocol/PacketUtils.java +++ b/src/main/java/net/minecraft/network/protocol/PacketUtils.java -@@ -43,7 +43,7 @@ public class PacketUtils { +@@ -44,7 +44,7 @@ public class PacketUtils { public static void ensureRunningOnSameThread(Packet packet, T listener, BlockableEventLoop engine) throws RunningOnDifferentThreadException { if (!engine.isSameThread()) { @@ -10052,7 +10050,7 @@ index 9a49f5271ec1d9de17632bfffe8309cb1ba0d8b1..c06bed93f6a701b1639c1cc334802e7b packetProcessing.push(listener); // Paper - detailed watchdog information try { // Paper - detailed watchdog information if (MinecraftServer.getServer().hasStopped() || (listener instanceof ServerCommonPacketListenerImpl && ((ServerCommonPacketListenerImpl) listener).processedDisconnect)) return; // CraftBukkit, MC-142590 -@@ -77,7 +77,21 @@ public class PacketUtils { +@@ -91,7 +91,21 @@ public class PacketUtils { } // Paper end - detailed watchdog information @@ -10076,19 +10074,20 @@ index 9a49f5271ec1d9de17632bfffe8309cb1ba0d8b1..c06bed93f6a701b1639c1cc334802e7b // CraftBukkit start - SPIGOT-5477, MC-142590 } else if (MinecraftServer.getServer().hasStopped() || (listener instanceof ServerCommonPacketListenerImpl && ((ServerCommonPacketListenerImpl) listener).processedDisconnect)) { diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 6758e3ff1100bba2852e44cbb0b38ce4f22490e8..75d5e7f1b247e27f526a3f76fa7df7aeca4e90ac 100644 +index 5ed6c8710b78458031ed6b0273fb2f6a5f482ea7..99a086ed2c0d5615a55539a31b8cd8483569e9c0 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -238,7 +238,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); public int autosavePeriod; public Commands vanillaCommandDispatcher; -@@ -300,7 +300,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function serverFactory) { AtomicReference atomicreference = new AtomicReference(); Thread thread = new io.papermc.paper.util.TickThread(() -> { // Paper - rewrite chunk system -@@ -594,7 +622,21 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { +- return false; +- } : this::haveTime); ++ if (true) throw new UnsupportedOperationException(); // Folia - region threading this.profiler.popPush("nextTickWait"); this.mayHaveDelayedTasks = true; - this.delayedTasksMaxNextTickTime = Math.max(Util.getMillis() + 50L, this.nextTickTime); -@@ -1276,21 +1376,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop= MAX_CHUNK_EXEC_TIME) { + if (!moreTasks) { +- lastMidTickExecuteFailure = currTime; ++ worldData.lastMidTickExecuteFailure = currTime; // Folia - region threading + } + + // note: negative values reduce the time +@@ -1421,7 +1500,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop= 5000000000L) { +- if (i - this.lastServerStatus >= MinecraftServer.STATUS_EXPIRE_TIME_NANOS) { + // Folia - region threading ++ if (region == null) this.tickRateManager.tick(); // Folia - region threading + this.tickChildren(shouldKeepTicking, region); // Folia - region threading -+ if (region == null && i - this.lastServerStatus >= 5000000000L) { // Folia - region threading - moved to global tick ++ if (region == null && i - this.lastServerStatus >= MinecraftServer.STATUS_EXPIRE_TIME_NANOS) { // Folia - region threading this.lastServerStatus = i; this.status = this.buildServerStatus(); } -@@ -1388,15 +1527,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { return worldserver + " " + worldserver.dimension().location(); -@@ -1545,7 +1664,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop= MAX_CHUNK_EXEC_TIME) { - if (!moreTasks) { -- lastMidTickExecuteFailure = currTime; -+ worldData.lastMidTickExecuteFailure = currTime; // Folia - region threading - } - - // note: negative values reduce the time -@@ -2801,7 +2908,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop attribute, double multiplier) throws CommandSyntaxException { -- LivingEntity livingEntity = getEntityWithAttribute(target, attribute); -- double d = livingEntity.getAttributeValue(attribute); -- source.sendSuccess(() -> { -- return Component.translatable("commands.attribute.value.get.success", getAttributeDescription(attribute), target.getName(), d); -- }, false); -- return (int)(d * multiplier); + // Folia start - region threading + target.getBukkitEntity().taskScheduler.schedule((LivingEntity nmsEntity) -> { + try { -+ LivingEntity livingEntity = getEntityWithAttribute(nmsEntity, attribute); -+ double d = livingEntity.getAttributeValue(attribute); -+ source.sendSuccess(() -> { -+ return Component.translatable("commands.attribute.value.get.success", getAttributeDescription(attribute), nmsEntity.getName(), d); -+ }, false); ++ // Folia end - region threading + LivingEntity livingEntity = getEntityWithAttribute(target, attribute); + double d = livingEntity.getAttributeValue(attribute); + source.sendSuccess(() -> { + return Component.translatable("commands.attribute.value.get.success", getAttributeDescription(attribute), target.getName(), d); + }, false); +- return (int)(d * multiplier); ++ return; // Folia - region threading ++ // Folia start - region threading + } catch (CommandSyntaxException ex) { + sendMessage(source, ex); + } @@ -10850,20 +10862,18 @@ index 506c5a8369ec0b2af3605e5bdfce8b000cf56ec4..efb41b6f138fd45f6b240b1d17c3320d } private static int getAttributeBase(CommandSourceStack source, Entity target, Holder attribute, double multiplier) throws CommandSyntaxException { -- LivingEntity livingEntity = getEntityWithAttribute(target, attribute); -- double d = livingEntity.getAttributeBaseValue(attribute); -- source.sendSuccess(() -> { -- return Component.translatable("commands.attribute.base_value.get.success", getAttributeDescription(attribute), target.getName(), d); -- }, false); -- return (int)(d * multiplier); + // Folia start - region threading + target.getBukkitEntity().taskScheduler.schedule((LivingEntity nmsEntity) -> { + try { -+ LivingEntity livingEntity = getEntityWithAttribute(nmsEntity, attribute); -+ double d = livingEntity.getAttributeBaseValue(attribute); -+ source.sendSuccess(() -> { -+ return Component.translatable("commands.attribute.base_value.get.success", getAttributeDescription(attribute), nmsEntity.getName(), d); -+ }, false); ++ // Folia end - region threading + LivingEntity livingEntity = getEntityWithAttribute(target, attribute); + double d = livingEntity.getAttributeBaseValue(attribute); + source.sendSuccess(() -> { + return Component.translatable("commands.attribute.base_value.get.success", getAttributeDescription(attribute), target.getName(), d); + }, false); +- return (int)(d * multiplier); ++ return; // Folia - region threading ++ // Folia start - region threading + } catch (CommandSyntaxException ex) { + sendMessage(source, ex); + } @@ -10873,30 +10883,21 @@ index 506c5a8369ec0b2af3605e5bdfce8b000cf56ec4..efb41b6f138fd45f6b240b1d17c3320d } private static int getAttributeModifier(CommandSourceStack source, Entity target, Holder attribute, UUID uuid, double multiplier) throws CommandSyntaxException { -- LivingEntity livingEntity = getEntityWithAttribute(target, attribute); -- AttributeMap attributeMap = livingEntity.getAttributes(); -- if (!attributeMap.hasModifier(attribute, uuid)) { -- throw ERROR_NO_SUCH_MODIFIER.create(target.getName(), getAttributeDescription(attribute), uuid); -- } else { -- double d = attributeMap.getModifierValue(attribute, uuid); -- source.sendSuccess(() -> { -- return Component.translatable("commands.attribute.modifier.value.get.success", uuid, getAttributeDescription(attribute), target.getName(), d); -- }, false); -- return (int)(d * multiplier); -- } + // Folia start - region threading + target.getBukkitEntity().taskScheduler.schedule((LivingEntity nmsEntity) -> { + try { -+ LivingEntity livingEntity = getEntityWithAttribute(nmsEntity, attribute); -+ AttributeMap attributeMap = livingEntity.getAttributes(); -+ if (!attributeMap.hasModifier(attribute, uuid)) { -+ throw ERROR_NO_SUCH_MODIFIER.create(nmsEntity.getName(), getAttributeDescription(attribute), uuid); -+ } else { -+ double d = attributeMap.getModifierValue(attribute, uuid); -+ source.sendSuccess(() -> { -+ return Component.translatable("commands.attribute.modifier.value.get.success", uuid, getAttributeDescription(attribute), nmsEntity.getName(), d); -+ }, false); -+ } ++ // Folia end - region threading + LivingEntity livingEntity = getEntityWithAttribute(target, attribute); + AttributeMap attributeMap = livingEntity.getAttributes(); + if (!attributeMap.hasModifier(attribute, uuid)) { +@@ -120,19 +152,40 @@ public class AttributeCommand { + source.sendSuccess(() -> { + return Component.translatable("commands.attribute.modifier.value.get.success", Component.translationArg(uuid), getAttributeDescription(attribute), target.getName(), d); + }, false); +- return (int)(d * multiplier); ++ return; // Folia - region threading + } ++ // Folia start - region threading + } catch (CommandSyntaxException ex) { + sendMessage(source, ex); + } @@ -10906,51 +10907,39 @@ index 506c5a8369ec0b2af3605e5bdfce8b000cf56ec4..efb41b6f138fd45f6b240b1d17c3320d } private static int setAttributeBase(CommandSourceStack source, Entity target, Holder attribute, double value) throws CommandSyntaxException { -- getAttributeInstance(target, attribute).setBaseValue(value); -- source.sendSuccess(() -> { -- return Component.translatable("commands.attribute.base_value.set.success", getAttributeDescription(attribute), target.getName(), value); -- }, false); -- return 1; + // Folia start - region threading + target.getBukkitEntity().taskScheduler.schedule((LivingEntity nmsEntity) -> { + try { -+ getAttributeInstance(nmsEntity, attribute).setBaseValue(value); -+ source.sendSuccess(() -> { -+ return Component.translatable("commands.attribute.base_value.set.success", getAttributeDescription(attribute), nmsEntity.getName(), value); -+ }, false); ++ // Folia end - region threading + getAttributeInstance(target, attribute).setBaseValue(value); + source.sendSuccess(() -> { + return Component.translatable("commands.attribute.base_value.set.success", getAttributeDescription(attribute), target.getName(), value); + }, false); ++ // Folia start - region threading + } catch (CommandSyntaxException ex) { + sendMessage(source, ex); + } + }, null, 1L); -+ return 0; + // Folia end - region threading + return 1; } private static int addModifier(CommandSourceStack source, Entity target, Holder attribute, UUID uuid, String name, double value, AttributeModifier.Operation operation) throws CommandSyntaxException { -- AttributeInstance attributeInstance = getAttributeInstance(target, attribute); -- AttributeModifier attributeModifier = new AttributeModifier(uuid, name, value, operation); -- if (attributeInstance.hasModifier(attributeModifier)) { -- throw ERROR_MODIFIER_ALREADY_PRESENT.create(target.getName(), getAttributeDescription(attribute), uuid); -- } else { -- attributeInstance.addPermanentModifier(attributeModifier); -- source.sendSuccess(() -> { -- return Component.translatable("commands.attribute.modifier.add.success", uuid, getAttributeDescription(attribute), target.getName()); -- }, false); -- return 1; -- } + // Folia start - region threading + target.getBukkitEntity().taskScheduler.schedule((LivingEntity nmsEntity) -> { + try { -+ AttributeInstance attributeInstance = getAttributeInstance(nmsEntity, attribute); -+ AttributeModifier attributeModifier = new AttributeModifier(uuid, name, value, operation); -+ if (attributeInstance.hasModifier(attributeModifier)) { -+ throw ERROR_MODIFIER_ALREADY_PRESENT.create(nmsEntity.getName(), getAttributeDescription(attribute), uuid); -+ } else { -+ attributeInstance.addPermanentModifier(attributeModifier); -+ source.sendSuccess(() -> { -+ return Component.translatable("commands.attribute.modifier.add.success", uuid, getAttributeDescription(attribute), nmsEntity.getName()); -+ }, false); -+ } ++ // Folia end - region threading + AttributeInstance attributeInstance = getAttributeInstance(target, attribute); + AttributeModifier attributeModifier = new AttributeModifier(uuid, name, value, operation); + if (attributeInstance.hasModifier(attributeModifier)) { +@@ -142,20 +195,38 @@ public class AttributeCommand { + source.sendSuccess(() -> { + return Component.translatable("commands.attribute.modifier.add.success", Component.translationArg(uuid), getAttributeDescription(attribute), target.getName()); + }, false); +- return 1; ++ return; // Folia - region threading + } ++ // Folia start - region threading + } catch (CommandSyntaxException ex) { + sendMessage(source, ex); + } @@ -10960,26 +10949,21 @@ index 506c5a8369ec0b2af3605e5bdfce8b000cf56ec4..efb41b6f138fd45f6b240b1d17c3320d } private static int removeModifier(CommandSourceStack source, Entity target, Holder attribute, UUID uuid) throws CommandSyntaxException { -- AttributeInstance attributeInstance = getAttributeInstance(target, attribute); -- if (attributeInstance.removePermanentModifier(uuid)) { -- source.sendSuccess(() -> { -- return Component.translatable("commands.attribute.modifier.remove.success", uuid, getAttributeDescription(attribute), target.getName()); -- }, false); -- return 1; -- } else { -- throw ERROR_NO_SUCH_MODIFIER.create(target.getName(), getAttributeDescription(attribute), uuid); -- } + // Folia start - region threading + target.getBukkitEntity().taskScheduler.schedule((LivingEntity nmsEntity) -> { + try { -+ AttributeInstance attributeInstance = getAttributeInstance(nmsEntity, attribute); -+ if (attributeInstance.removePermanentModifier(uuid)) { -+ source.sendSuccess(() -> { -+ return Component.translatable("commands.attribute.modifier.remove.success", uuid, getAttributeDescription(attribute), nmsEntity.getName()); -+ }, false); -+ } else { -+ throw ERROR_NO_SUCH_MODIFIER.create(nmsEntity.getName(), getAttributeDescription(attribute), uuid); -+ } ++ // Folia end - region threading + AttributeInstance attributeInstance = getAttributeInstance(target, attribute); + if (attributeInstance.removePermanentModifier(uuid)) { + source.sendSuccess(() -> { + return Component.translatable("commands.attribute.modifier.remove.success", Component.translationArg(uuid), getAttributeDescription(attribute), target.getName()); + }, false); +- return 1; ++ return; // Folia - region threading + } else { + throw ERROR_NO_SUCH_MODIFIER.create(target.getName(), getAttributeDescription(attribute), uuid); + } ++ // Folia start - region threading + } catch (CommandSyntaxException ex) { + sendMessage(source, ex); + } @@ -10990,7 +10974,7 @@ index 506c5a8369ec0b2af3605e5bdfce8b000cf56ec4..efb41b6f138fd45f6b240b1d17c3320d private static Component getAttributeDescription(Holder attribute) { diff --git a/src/main/java/net/minecraft/server/commands/ClearInventoryCommands.java b/src/main/java/net/minecraft/server/commands/ClearInventoryCommands.java -index 90c061eaf40ed756dcd56bb877a617a219ea90e1..36f5d081fae92289e1b6bf012018671343dd92a0 100644 +index 3d8076ce2a04c550109fb8f04f2b3d0c76b28795..581172fdd35d8a34c7e5427007981f9d67a21513 100644 --- a/src/main/java/net/minecraft/server/commands/ClearInventoryCommands.java +++ b/src/main/java/net/minecraft/server/commands/ClearInventoryCommands.java @@ -46,9 +46,12 @@ public class ClearInventoryCommands { @@ -11123,7 +11107,7 @@ index ebe50e2e69d346ce9266ed3f180d91ceb58008bd..227acbe74ff009c9275542af734852e3 } diff --git a/src/main/java/net/minecraft/server/commands/EnchantCommand.java b/src/main/java/net/minecraft/server/commands/EnchantCommand.java -index 664cbce2e06fcb95d3d3d6c5302fc9119f938925..3f68902a2842f1dddc73e86ba6278e6b4b39d1dc 100644 +index 37d9c354af887c474094b1a364782007a5f2035d..e4c11fb7872338f684f97a48f95c122514180f4f 100644 --- a/src/main/java/net/minecraft/server/commands/EnchantCommand.java +++ b/src/main/java/net/minecraft/server/commands/EnchantCommand.java @@ -46,47 +46,73 @@ public class EnchantCommand { @@ -11260,30 +11244,33 @@ index 24dfe8e9697331f0d7e67e90b9ca537d7ead575e..30b2dafda64a2e56d53d5d90c3087774 if (i == 0) { diff --git a/src/main/java/net/minecraft/server/commands/FillBiomeCommand.java b/src/main/java/net/minecraft/server/commands/FillBiomeCommand.java -index 618f524a7bba8e5c75445872538c5fd1ceff20e4..87920a58207436b328abff257369a271752df174 100644 +index b920f1c8f48aa8e542028acc125293d603aee7c0..785f9be8e9c66c340e5f8f46386fddfd112685d6 100644 --- a/src/main/java/net/minecraft/server/commands/FillBiomeCommand.java +++ b/src/main/java/net/minecraft/server/commands/FillBiomeCommand.java -@@ -69,6 +69,12 @@ public class FillBiomeCommand { - }; +@@ -80,6 +80,16 @@ public class FillBiomeCommand { + }); } + // Folia start - region threading -+ private static void sendMessage(CommandSourceStack src, CommandSyntaxException ex) { -+ src.sendFailure((Component)ex.getRawMessage()); ++ private static void sendMessage(Consumer> src, Supplier> supplier) { ++ Either either = supplier.get(); ++ CommandSyntaxException ex = either == null ? null : either.right().orElse(null); ++ if (ex != null) { ++ src.accept(() -> (Component)ex.getRawMessage()); ++ } + } + // Folia end - region threading + - private static int fill(CommandSourceStack source, BlockPos from, BlockPos to, Holder.Reference biome, Predicate> filter) throws CommandSyntaxException { + public static Either fill(ServerLevel world, BlockPos from, BlockPos to, Holder biome, Predicate> filter, Consumer> feedbackConsumer) { BlockPos blockPos = quantize(from); BlockPos blockPos2 = quantize(to); -@@ -79,8 +85,19 @@ public class FillBiomeCommand { - throw ERROR_VOLUME_TOO_LARGE.create(j, i); +@@ -89,8 +99,18 @@ public class FillBiomeCommand { + if (i > j) { + return Either.right(ERROR_VOLUME_TOO_LARGE.create(j, i)); } else { - ServerLevel serverLevel = source.getLevel(); + // Folia start - region threading -+ int buffer = 0; -+ // no buffer, we do not touch neighbours -+ serverLevel.loadChunksAsync( ++ int buffer = 0; // no buffer, we do not touch neighbours ++ world.loadChunksAsync( + (boundingBox.minX() - buffer) >> 4, + (boundingBox.maxX() + buffer) >> 4, + (boundingBox.minZ() - buffer) >> 4, @@ -11291,27 +11278,26 @@ index 618f524a7bba8e5c75445872538c5fd1ceff20e4..87920a58207436b328abff257369a271 + net.minecraft.world.level.chunk.ChunkStatus.FULL, + ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.NORMAL, + (chunks) -> { -+ try { // Folia end - region threading ++ sendMessage(feedbackConsumer, () -> { List list = new ArrayList<>(); - for(int k = SectionPos.blockToSectionCoord(boundingBox.minZ()); k <= SectionPos.blockToSectionCoord(boundingBox.maxZ()); ++k) { for(int l = SectionPos.blockToSectionCoord(boundingBox.minX()); l <= SectionPos.blockToSectionCoord(boundingBox.maxX()); ++l) { - ChunkAccess chunkAccess = serverLevel.getChunk(l, k, ChunkStatus.FULL, false); -@@ -103,7 +120,11 @@ public class FillBiomeCommand { - source.sendSuccess(() -> { + ChunkAccess chunkAccess = world.getChunk(l, k, ChunkStatus.FULL, false); +@@ -114,6 +134,11 @@ public class FillBiomeCommand { return Component.translatable("commands.fillbiome.success.count", mutableInt.getValue(), boundingBox.minX(), boundingBox.minY(), boundingBox.minZ(), boundingBox.maxX(), boundingBox.maxY(), boundingBox.maxZ()); - }, true); -- return mutableInt.getValue(); + }); + return Either.left(mutableInt.getValue()); + // Folia start - region threading -+ } catch (CommandSyntaxException ex) { -+ sendMessage(source, ex); -+ } -+ }); return 0; // Folia end - region threading ++ }); // sendMessage ++ }); // loadChunksASync ++ return Either.left(Integer.valueOf(0)); ++ // Folia end - region threading } } - } + diff --git a/src/main/java/net/minecraft/server/commands/FillCommand.java b/src/main/java/net/minecraft/server/commands/FillCommand.java -index e75b08126d9c42d49058fc91d68d1906fc277e8a..cb68b211bc7e5d4e4e68aa8c7d9dd95901b98e5f 100644 +index 287e0b193060829174d9ac7d127c3034c5eee1e1..353dd419f57e923672e065c0b7b27546e12ca7a9 100644 --- a/src/main/java/net/minecraft/server/commands/FillCommand.java +++ b/src/main/java/net/minecraft/server/commands/FillCommand.java @@ -57,6 +57,12 @@ public class FillCommand { @@ -11362,10 +11348,10 @@ index e75b08126d9c42d49058fc91d68d1906fc277e8a..cb68b211bc7e5d4e4e68aa8c7d9dd959 } diff --git a/src/main/java/net/minecraft/server/commands/ForceLoadCommand.java b/src/main/java/net/minecraft/server/commands/ForceLoadCommand.java -index 99250f40978aa3c45df821c3d83f80b541dbb14c..a3ea3fb7ac0f1464ea33e07978ba11c01803dcbe 100644 +index cbcacceb69dd032b70c39075c59cd8d50a77ea17..8ccbb9584bb9aeb8507ba35fd1ce22da936788b5 100644 --- a/src/main/java/net/minecraft/server/commands/ForceLoadCommand.java +++ b/src/main/java/net/minecraft/server/commands/ForceLoadCommand.java -@@ -49,47 +49,67 @@ public class ForceLoadCommand { +@@ -49,7 +49,17 @@ public class ForceLoadCommand { })))); } @@ -11376,30 +11362,23 @@ index 99250f40978aa3c45df821c3d83f80b541dbb14c..a3ea3fb7ac0f1464ea33e07978ba11c0 + // Folia end - region threading + private static int queryForceLoad(CommandSourceStack source, ColumnPos pos) throws CommandSyntaxException { - ChunkPos chunkPos = pos.toChunkPos(); - ServerLevel serverLevel = source.getLevel(); - ResourceKey resourceKey = serverLevel.dimension(); -- boolean bl = serverLevel.getForcedChunks().contains(chunkPos.toLong()); -- if (bl) { -- source.sendSuccess(() -> { -- return Component.translatable("commands.forceload.query.success", chunkPos, resourceKey.location()); -- }, false); -- return 1; -- } else { -- throw ERROR_NOT_TICKING.create(chunkPos, resourceKey.location()); -- } + // Folia start - region threading + io.papermc.paper.threadedregions.RegionizedServer.getInstance().addTask(() -> { + try { -+ boolean bl = serverLevel.getForcedChunks().contains(chunkPos.toLong()); -+ if (bl) { -+ source.sendSuccess(() -> { -+ return Component.translatable("commands.forceload.query.success", chunkPos, resourceKey.location()); -+ }, false); -+ return; -+ } else { -+ throw ERROR_NOT_TICKING.create(chunkPos, resourceKey.location()); -+ } ++ // Folia end - region threading + ChunkPos chunkPos = pos.toChunkPos(); + ServerLevel serverLevel = source.getLevel(); + ResourceKey resourceKey = serverLevel.dimension(); +@@ -58,14 +68,22 @@ public class ForceLoadCommand { + source.sendSuccess(() -> { + return Component.translatable("commands.forceload.query.success", Component.translationArg(chunkPos), Component.translationArg(resourceKey.location())); + }, false); +- return 1; ++ return; // Folia - region threading + } else { + throw ERROR_NOT_TICKING.create(chunkPos, resourceKey.location()); + } ++ // Folia start - region threading + } catch (CommandSyntaxException ex) { + sendMessage(source, ex); + } @@ -11410,44 +11389,18 @@ index 99250f40978aa3c45df821c3d83f80b541dbb14c..a3ea3fb7ac0f1464ea33e07978ba11c0 private static int listForceLoad(CommandSourceStack source) { ServerLevel serverLevel = source.getLevel(); ++ io.papermc.paper.threadedregions.RegionizedServer.getInstance().addTask(() -> { // Folia - region threading ResourceKey resourceKey = serverLevel.dimension(); -- LongSet longSet = serverLevel.getForcedChunks(); -- int i = longSet.size(); -- if (i > 0) { -- String string = Joiner.on(", ").join(longSet.stream().sorted().map(ChunkPos::new).map(ChunkPos::toString).iterator()); -- if (i == 1) { -- source.sendSuccess(() -> { -- return Component.translatable("commands.forceload.list.single", resourceKey.location(), string); -- }, false); -+ // Folia start - region threading -+ io.papermc.paper.threadedregions.RegionizedServer.getInstance().addTask(() -> { -+ LongSet longSet = serverLevel.getForcedChunks(); -+ int i = longSet.size(); -+ if (i > 0) { -+ String string = Joiner.on(", ").join(longSet.stream().sorted().map(ChunkPos::new).map(ChunkPos::toString).iterator()); -+ if (i == 1) { -+ source.sendSuccess(() -> { -+ return Component.translatable("commands.forceload.list.single", resourceKey.location(), string); -+ }, false); -+ } else { -+ source.sendSuccess(() -> { -+ return Component.translatable("commands.forceload.list.multiple", i, resourceKey.location(), string); -+ }, false); -+ } - } else { -- source.sendSuccess(() -> { -- return Component.translatable("commands.forceload.list.multiple", i, resourceKey.location(), string); -- }, false); -+ source.sendFailure(Component.translatable("commands.forceload.added.none", resourceKey.location())); - } -- } else { -- source.sendFailure(Component.translatable("commands.forceload.added.none", resourceKey.location())); -- } + LongSet longSet = serverLevel.getForcedChunks(); + int i = longSet.size(); +@@ -83,13 +101,15 @@ public class ForceLoadCommand { + } else { + source.sendFailure(Component.translatable("commands.forceload.added.none", Component.translationArg(resourceKey.location()))); + } ++ }); // Folia - region threading - return i; -+ }); -+ return 1; -+ // Folia end - region threading ++ return 1; // Folia - region threading } private static int removeAll(CommandSourceStack source) { @@ -11457,118 +11410,37 @@ index 99250f40978aa3c45df821c3d83f80b541dbb14c..a3ea3fb7ac0f1464ea33e07978ba11c0 LongSet longSet = serverLevel.getForcedChunks(); longSet.forEach((chunkPos) -> { serverLevel.setChunkForced(ChunkPos.getX(chunkPos), ChunkPos.getZ(chunkPos), false); -@@ -97,61 +117,71 @@ public class ForceLoadCommand { +@@ -97,10 +117,15 @@ public class ForceLoadCommand { source.sendSuccess(() -> { - return Component.translatable("commands.forceload.removed.all", resourceKey.location()); + return Component.translatable("commands.forceload.removed.all", Component.translationArg(resourceKey.location())); }, true); + }); // Folia - region threading return 0; } private static int changeForceLoad(CommandSourceStack source, ColumnPos from, ColumnPos to, boolean forceLoaded) throws CommandSyntaxException { -- int i = Math.min(from.x(), to.x()); -- int j = Math.min(from.z(), to.z()); -- int k = Math.max(from.x(), to.x()); -- int l = Math.max(from.z(), to.z()); -- if (i >= -30000000 && j >= -30000000 && k < 30000000 && l < 30000000) { -- int m = SectionPos.blockToSectionCoord(i); -- int n = SectionPos.blockToSectionCoord(j); -- int o = SectionPos.blockToSectionCoord(k); -- int p = SectionPos.blockToSectionCoord(l); -- long q = ((long)(o - m) + 1L) * ((long)(p - n) + 1L); -- if (q > 256L) { -- throw ERROR_TOO_MANY_CHUNKS.create(256, q); -- } else { -- ServerLevel serverLevel = source.getLevel(); -- ResourceKey resourceKey = serverLevel.dimension(); -- ChunkPos chunkPos = null; -- int r = 0; + // Folia start - region threading + io.papermc.paper.threadedregions.RegionizedServer.getInstance().addTask(() -> { + try { -+ int i = Math.min(from.x(), to.x()); -+ int j = Math.min(from.z(), to.z()); -+ int k = Math.max(from.x(), to.x()); -+ int l = Math.max(from.z(), to.z()); -+ if (i >= -30000000 && j >= -30000000 && k < 30000000 && l < 30000000) { -+ int m = SectionPos.blockToSectionCoord(i); -+ int n = SectionPos.blockToSectionCoord(j); -+ int o = SectionPos.blockToSectionCoord(k); -+ int p = SectionPos.blockToSectionCoord(l); -+ long q = ((long)(o - m) + 1L) * ((long)(p - n) + 1L); -+ if (q > 256L) { -+ throw ERROR_TOO_MANY_CHUNKS.create(256, q); -+ } else { -+ ServerLevel serverLevel = source.getLevel(); -+ ResourceKey resourceKey = serverLevel.dimension(); -+ ChunkPos chunkPos = null; -+ int r = 0; - -- for(int s = m; s <= o; ++s) { -- for(int t = n; t <= p; ++t) { -- boolean bl = serverLevel.setChunkForced(s, t, forceLoaded); -- if (bl) { -- ++r; -- if (chunkPos == null) { -- chunkPos = new ChunkPos(s, t); -+ for(int s = m; s <= o; ++s) { -+ for(int t = n; t <= p; ++t) { -+ boolean bl = serverLevel.setChunkForced(s, t, forceLoaded); -+ if (bl) { -+ ++r; -+ if (chunkPos == null) { -+ chunkPos = new ChunkPos(s, t); -+ } -+ } - } - } -- } -- } - -- ChunkPos chunkPos2 = chunkPos; -- if (r == 0) { -- throw (forceLoaded ? ERROR_ALL_ADDED : ERROR_NONE_REMOVED).create(); -- } else { -- if (r == 1) { -- source.sendSuccess(() -> { -- return Component.translatable("commands.forceload." + (forceLoaded ? "added" : "removed") + ".single", chunkPos2, resourceKey.location()); -- }, true); -- } else { -- ChunkPos chunkPos3 = new ChunkPos(m, n); -- ChunkPos chunkPos4 = new ChunkPos(o, p); -- source.sendSuccess(() -> { -- return Component.translatable("commands.forceload." + (forceLoaded ? "added" : "removed") + ".multiple", chunkPos2, resourceKey.location(), chunkPos3, chunkPos4); -- }, true); -- } -+ ChunkPos chunkPos2 = chunkPos; -+ if (r == 0) { -+ throw (forceLoaded ? ERROR_ALL_ADDED : ERROR_NONE_REMOVED).create(); -+ } else { -+ if (r == 1) { -+ source.sendSuccess(() -> { -+ return Component.translatable("commands.forceload." + (forceLoaded ? "added" : "removed") + ".single", chunkPos2, resourceKey.location()); -+ }, true); -+ } else { -+ ChunkPos chunkPos3 = new ChunkPos(m, n); -+ ChunkPos chunkPos4 = new ChunkPos(o, p); -+ source.sendSuccess(() -> { -+ return Component.translatable("commands.forceload." + (forceLoaded ? "added" : "removed") + ".multiple", chunkPos2, resourceKey.location(), chunkPos3, chunkPos4); -+ }, true); -+ } ++ // Folia end - region threading + int i = Math.min(from.x(), to.x()); + int j = Math.min(from.z(), to.z()); + int k = Math.max(from.x(), to.x()); +@@ -147,11 +172,18 @@ public class ForceLoadCommand { + }, true); + } - return r; -+ return; -+ } -+ } -+ } else { -+ throw BlockPosArgument.ERROR_OUT_OF_WORLD.create(); ++ return; // Folia - region threading } + } + } else { + throw BlockPosArgument.ERROR_OUT_OF_WORLD.create(); + } ++ // Folia start - region threading + } catch (CommandSyntaxException ex) { + sendMessage(source, ex); - } -- } else { -- throw BlockPosArgument.ERROR_OUT_OF_WORLD.create(); -- } ++ } + }); + return 1; + // Folia end - region threading @@ -11634,7 +11506,7 @@ index 0026da50714adca207b1d3970ee808c9c09d4443..ac694041183e49ab44c5a27f3aa57ad1 if (targets.size() == 1) { diff --git a/src/main/java/net/minecraft/server/commands/PlaceCommand.java b/src/main/java/net/minecraft/server/commands/PlaceCommand.java -index 1ca63d5504999eb63bece58e697fe42732bcdb7e..02a9fb1c3d9b94cda8f60f044245d44ce90d35dc 100644 +index a78ac2c2a536abb0a77371c3d8a9ce0dc5084c38..4f0c962231562c13be8980f98a7d801ab292ab38 100644 --- a/src/main/java/net/minecraft/server/commands/PlaceCommand.java +++ b/src/main/java/net/minecraft/server/commands/PlaceCommand.java @@ -88,12 +88,25 @@ public class PlaceCommand { @@ -11754,7 +11626,7 @@ index 1ca63d5504999eb63bece58e697fe42732bcdb7e..02a9fb1c3d9b94cda8f60f044245d44c Optional optional; @@ -180,9 +238,17 @@ public class PlaceCommand { source.sendSuccess(() -> { - return Component.translatable("commands.place.template.success", id, pos.getX(), pos.getY(), pos.getZ()); + return Component.translatable("commands.place.template.success", Component.translationArg(id), pos.getX(), pos.getY(), pos.getZ()); }, true); - return 1; + return; // Folia - region threading @@ -12041,8 +11913,185 @@ index 8f5714221bc32fb2c9201cbc8a0a35610977f574..c78a7e5e5c6b012756e6a1e50159dd97 return duration; } } +diff --git a/src/main/java/net/minecraft/server/commands/WorldBorderCommand.java b/src/main/java/net/minecraft/server/commands/WorldBorderCommand.java +index 812f2adc6fc20aa126e629284fe594a923b24540..0a5e6961fb37e9a53cd39b1bd233e0204986b244 100644 +--- a/src/main/java/net/minecraft/server/commands/WorldBorderCommand.java ++++ b/src/main/java/net/minecraft/server/commands/WorldBorderCommand.java +@@ -56,7 +56,17 @@ public class WorldBorderCommand { + }))))); + } + ++ // Folia start - region threading ++ private static void sendMessage(CommandSourceStack src, CommandSyntaxException ex) { ++ src.sendFailure((Component)ex.getRawMessage()); ++ } ++ // Folia end - region threading ++ + private static int setDamageBuffer(CommandSourceStack source, float distance) throws CommandSyntaxException { ++ // Folia start - region threading ++ io.papermc.paper.threadedregions.RegionizedServer.getInstance().addTask(() -> { ++ try { ++ // Folia end - region threading + WorldBorder worldborder = source.getLevel().getWorldBorder(); // CraftBukkit + + if (worldborder.getDamageSafeZone() == (double) distance) { +@@ -66,11 +76,22 @@ public class WorldBorderCommand { + source.sendSuccess(() -> { + return Component.translatable("commands.worldborder.damage.buffer.success", String.format(Locale.ROOT, "%.2f", distance)); + }, true); +- return (int) distance; ++ return; // Folia - region threading + } ++ // Folia start - region threading ++ } catch (CommandSyntaxException ex) { ++ sendMessage(source, ex); ++ } ++ }); ++ return 1; ++ // Folia end - region threading + } + + private static int setDamageAmount(CommandSourceStack source, float damagePerBlock) throws CommandSyntaxException { ++ // Folia start - region threading ++ io.papermc.paper.threadedregions.RegionizedServer.getInstance().addTask(() -> { ++ try { ++ // Folia end - region threading + WorldBorder worldborder = source.getLevel().getWorldBorder(); // CraftBukkit + + if (worldborder.getDamagePerBlock() == (double) damagePerBlock) { +@@ -80,11 +101,22 @@ public class WorldBorderCommand { + source.sendSuccess(() -> { + return Component.translatable("commands.worldborder.damage.amount.success", String.format(Locale.ROOT, "%.2f", damagePerBlock)); + }, true); +- return (int) damagePerBlock; ++ return; // Folia - region threading + } ++ // Folia start - region threading ++ } catch (CommandSyntaxException ex) { ++ sendMessage(source, ex); ++ } ++ }); ++ return 1; ++ // Folia end - region threading + } + + private static int setWarningTime(CommandSourceStack source, int time) throws CommandSyntaxException { ++ // Folia start - region threading ++ io.papermc.paper.threadedregions.RegionizedServer.getInstance().addTask(() -> { ++ try { ++ // Folia end - region threading + WorldBorder worldborder = source.getLevel().getWorldBorder(); // CraftBukkit + + if (worldborder.getWarningTime() == time) { +@@ -94,11 +126,22 @@ public class WorldBorderCommand { + source.sendSuccess(() -> { + return Component.translatable("commands.worldborder.warning.time.success", time); + }, true); +- return time; ++ return; // Folia - region threading + } ++ // Folia start - region threading ++ } catch (CommandSyntaxException ex) { ++ sendMessage(source, ex); ++ } ++ }); ++ return 1; ++ // Folia end - region threading + } + + private static int setWarningDistance(CommandSourceStack source, int distance) throws CommandSyntaxException { ++ // Folia start - region threading ++ io.papermc.paper.threadedregions.RegionizedServer.getInstance().addTask(() -> { ++ try { ++ // Folia end - region threading + WorldBorder worldborder = source.getLevel().getWorldBorder(); // CraftBukkit + + if (worldborder.getWarningBlocks() == distance) { +@@ -108,20 +151,38 @@ public class WorldBorderCommand { + source.sendSuccess(() -> { + return Component.translatable("commands.worldborder.warning.distance.success", distance); + }, true); +- return distance; ++ return; // Folia - region threading + } ++ // Folia start - region threading ++ } catch (CommandSyntaxException ex) { ++ sendMessage(source, ex); ++ } ++ }); ++ return 1; ++ // Folia end - region threading + } + + private static int getSize(CommandSourceStack source) { ++ // Folia start - region threading ++ io.papermc.paper.threadedregions.RegionizedServer.getInstance().addTask(() -> { ++ // Folia end - region threading + double d0 = source.getLevel().getWorldBorder().getSize(); // CraftBukkit + + source.sendSuccess(() -> { + return Component.translatable("commands.worldborder.get", String.format(Locale.ROOT, "%.0f", d0)); + }, false); +- return Mth.floor(d0 + 0.5D); ++ return; // Folia - region threading ++ // Folia start - region threading ++ }); ++ return 1; ++ // Folia end - region threading + } + + private static int setCenter(CommandSourceStack source, Vec2 pos) throws CommandSyntaxException { ++ // Folia start - region threading ++ io.papermc.paper.threadedregions.RegionizedServer.getInstance().addTask(() -> { ++ try { ++ // Folia end - region threading + WorldBorder worldborder = source.getLevel().getWorldBorder(); // CraftBukkit + + if (worldborder.getCenterX() == (double) pos.x && worldborder.getCenterZ() == (double) pos.y) { +@@ -131,13 +192,24 @@ public class WorldBorderCommand { + source.sendSuccess(() -> { + return Component.translatable("commands.worldborder.center.success", String.format(Locale.ROOT, "%.2f", pos.x), String.format(Locale.ROOT, "%.2f", pos.y)); + }, true); +- return 0; ++ return; // Folia - region threading + } else { + throw WorldBorderCommand.ERROR_TOO_FAR_OUT.create(); + } ++ // Folia start - region threading ++ } catch (CommandSyntaxException ex) { ++ sendMessage(source, ex); ++ } ++ }); ++ return 1; ++ // Folia end - region threading + } + + private static int setSize(CommandSourceStack source, double distance, long time) throws CommandSyntaxException { ++ // Folia start - region threading ++ io.papermc.paper.threadedregions.RegionizedServer.getInstance().addTask(() -> { ++ try { ++ // Folia end - region threading + WorldBorder worldborder = source.getLevel().getWorldBorder(); // CraftBukkit + double d1 = worldborder.getSize(); + +@@ -166,7 +238,14 @@ public class WorldBorderCommand { + }, true); + } + +- return (int) (distance - d1); ++ return; // Folia - region threading + } ++ // Folia start - region threading ++ } catch (CommandSyntaxException ex) { ++ sendMessage(source, ex); ++ } ++ }); ++ return 1; ++ // Folia end - region threading + } + } diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index cf605aa56adf7f80d3b409f60a92a5ca7ae8fd07..05d8cabd2294456e3c8df60265f8b035990dd896 100644 +index 58536aabf607015939a1326f80207c0a06eed8ff..12af517a7dd8c0bb2bc55ab3eb0e68a074011bb5 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java @@ -442,9 +442,9 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface @@ -12058,7 +12107,7 @@ index cf605aa56adf7f80d3b409f60a92a5ca7ae8fd07..05d8cabd2294456e3c8df60265f8b035 } @Override -@@ -765,7 +765,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -766,7 +766,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface Waitable[] waitableArray = new Waitable[1]; // Paper rconConsoleSource.prepareForCommand(); final java.util.concurrent.atomic.AtomicReference command = new java.util.concurrent.atomic.AtomicReference<>(s); // Paper @@ -12067,7 +12116,7 @@ index cf605aa56adf7f80d3b409f60a92a5ca7ae8fd07..05d8cabd2294456e3c8df60265f8b035 CommandSourceStack wrapper = rconConsoleSource.createCommandSourceStack(); RemoteServerCommandEvent event = new RemoteServerCommandEvent(rconConsoleSource.getBukkitSender(wrapper), s); this.server.getPluginManager().callEvent(event); -@@ -789,7 +789,16 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -790,7 +790,16 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface ConsoleInput serverCommand = new ConsoleInput(event.getCommand(), wrapper); this.server.dispatchServerCommand(event.getSender(), serverCommand); } // Paper @@ -12731,10 +12780,10 @@ index 55f96545d6db95e3e657502a7910d96fded1113e..b39dd5a11a34407244666d8b9c1e775d public String getDebugStatus() { diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 8c33a12ca879c46893150d6adfb8aa4d397c6b4c..4ed40924942bc3252fb1a533190765fbfdb2ba72 100644 +index 6e212f672579a3e08dc362c287be59ca5170d717..a363c9d74d2a50a3bb3c3e323f7cf921c50bbff7 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -60,73 +60,42 @@ public class ServerChunkCache extends ChunkSource { +@@ -58,73 +58,42 @@ public class ServerChunkCache extends ChunkSource { public final ServerChunkCache.MainThreadExecutor mainThreadProcessor; public final ChunkMap chunkMap; private final DimensionDataStorage dataStorage; @@ -12820,7 +12869,7 @@ index 8c33a12ca879c46893150d6adfb8aa4d397c6b4c..4ed40924942bc3252fb1a533190765fb } public final LevelChunk getChunkAtIfLoadedMainThreadNoCache(int x, int z) { -@@ -163,8 +132,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -161,8 +130,7 @@ public class ServerChunkCache extends ChunkSource { this.distanceManager.removeTicket(ticketType, chunkPos, ticketLevel, identifier); } @@ -12830,7 +12879,7 @@ index 8c33a12ca879c46893150d6adfb8aa4d397c6b4c..4ed40924942bc3252fb1a533190765fb // Paper end public ServerChunkCache(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor workerExecutor, ChunkGenerator chunkGenerator, int viewDistance, int simulationDistance, boolean dsync, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier persistentStateManagerFactory) { -@@ -238,26 +206,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -236,26 +204,7 @@ public class ServerChunkCache extends ChunkSource { public LevelChunk getChunkAtIfLoadedImmediately(int x, int z) { long k = ChunkPos.asLong(x, z); @@ -12858,7 +12907,7 @@ index 8c33a12ca879c46893150d6adfb8aa4d397c6b4c..4ed40924942bc3252fb1a533190765fb } // Paper end -@@ -331,6 +280,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -329,6 +278,7 @@ public class ServerChunkCache extends ChunkSource { } public CompletableFuture> getChunkFuture(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) { @@ -12866,62 +12915,22 @@ index 8c33a12ca879c46893150d6adfb8aa4d397c6b4c..4ed40924942bc3252fb1a533190765fb boolean flag1 = io.papermc.paper.util.TickThread.isTickThread(); // Paper - rewrite chunk system CompletableFuture completablefuture; -@@ -508,10 +458,11 @@ public class ServerChunkCache extends ChunkSource { +@@ -507,10 +457,11 @@ public class ServerChunkCache extends ChunkSource { } private void tickChunks() { -+ io.papermc.paper.threadedregions.RegionizedWorldData regionizedWorldData = this.level.getCurrentWorldData(); // Folia - region threading - long i = this.level.getGameTime(); +- long i = this.level.getGameTime(); - long j = i - this.lastInhabitedUpdate; ++ io.papermc.paper.threadedregions.RegionizedWorldData regionizedWorldData = this.level.getCurrentWorldData(); // Folia - region threading ++ //long i = this.level.getGameTime(); // Folia - region threading + long j = 1; // Folia - region threading - this.lastInhabitedUpdate = i; + //this.lastInhabitedUpdate = i; // Folia - region threading - boolean flag = this.level.isDebug(); + if (!this.level.isDebug()) { + ProfilerFiller gameprofilerfiller = this.level.getProfiler(); - if (flag) { -@@ -522,7 +473,7 @@ public class ServerChunkCache extends ChunkSource { - - gameprofilerfiller.push("pollingChunks"); - int k = this.level.getGameRules().getInt(GameRules.RULE_RANDOMTICKING); -- boolean flag1 = this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) != 0L && worlddata.getGameTime() % this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) == 0L; // CraftBukkit -+ boolean flag1 = this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) != 0L && this.level.getRedstoneGameTime() % this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) == 0L; // CraftBukkit // Folia - region threading - - gameprofilerfiller.push("naturalSpawnCount"); - this.level.timings.countNaturalMobs.startTiming(); // Paper - timings -@@ -531,7 +482,7 @@ public class ServerChunkCache extends ChunkSource { - NaturalSpawner.SpawnState spawnercreature_d; // moved down - if ((this.spawnFriendlies || this.spawnEnemies) && this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { // don't count mobs when animals and monsters are disabled - // re-set mob counts -- for (ServerPlayer player : this.level.players) { -+ for (ServerPlayer player : regionizedWorldData.getLocalPlayers()) { // Folia - region threading - // Paper start - per player mob spawning backoff - for (int ii = 0; ii < ServerPlayer.MOBCATEGORY_TOTAL_ENUMS; ii++) { - player.mobCounts[ii] = 0; -@@ -544,14 +495,14 @@ public class ServerChunkCache extends ChunkSource { - } - // Paper end - per player mob spawning backoff - } -- spawnercreature_d = NaturalSpawner.createState(l, this.level.getAllEntities(), this::getFullChunk, null, true); -+ spawnercreature_d = NaturalSpawner.createState(l, regionizedWorldData.getLoadedEntities(), this::getFullChunk, null, true); // Folia - region threading - } else { -- spawnercreature_d = NaturalSpawner.createState(l, this.level.getAllEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false); -+ spawnercreature_d = NaturalSpawner.createState(l, regionizedWorldData.getLoadedEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false); // Folia - region threading - } - // Paper end - this.level.timings.countNaturalMobs.stopTiming(); // Paper - timings - -- this.lastSpawnState = spawnercreature_d; -+ regionizedWorldData.lastSpawnState = spawnercreature_d; // Folia - region threading - gameprofilerfiller.popPush("filteringLoadedChunks"); - // Paper - optimise chunk tick iteration - // Paper - optimise chunk tick iteration -@@ -560,13 +511,13 @@ public class ServerChunkCache extends ChunkSource { - // Paper - optimise chunk tick iteration - - gameprofilerfiller.popPush("spawnAndTick"); -- boolean flag2 = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.players().isEmpty(); // CraftBukkit -+ boolean flag2 = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !regionizedWorldData.getLocalPlayers().isEmpty(); // CraftBukkit // Folia - region threading +@@ -520,9 +471,9 @@ public class ServerChunkCache extends ChunkSource { // Paper start - optimise chunk tick iteration ChunkMap playerChunkMap = this.chunkMap; @@ -12933,7 +12942,7 @@ index 8c33a12ca879c46893150d6adfb8aa4d397c6b4c..4ed40924942bc3252fb1a533190765fb player.playerNaturallySpawnedEvent = null; player.lastEntitySpawnRadiusSquared = -1.0; continue; -@@ -582,7 +533,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -538,7 +489,7 @@ public class ServerChunkCache extends ChunkSource { com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent event = new com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent(player.getBukkitEntity(), (byte)chunkRange); event.callEvent(); if (event.isCancelled() || event.getSpawnRadius() < 0) { @@ -12942,7 +12951,7 @@ index 8c33a12ca879c46893150d6adfb8aa4d397c6b4c..4ed40924942bc3252fb1a533190765fb player.playerNaturallySpawnedEvent = null; player.lastEntitySpawnRadiusSquared = -1.0; continue; -@@ -592,7 +543,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -548,7 +499,7 @@ public class ServerChunkCache extends ChunkSource { int chunkX = io.papermc.paper.util.CoordinateUtils.getChunkCoordinate(player.getX()); int chunkZ = io.papermc.paper.util.CoordinateUtils.getChunkCoordinate(player.getZ()); @@ -12951,21 +12960,82 @@ index 8c33a12ca879c46893150d6adfb8aa4d397c6b4c..4ed40924942bc3252fb1a533190765fb player.lastEntitySpawnRadiusSquared = (double)((range << 4) * (range << 4)); // used in anyPlayerCloseEnoughForSpawning player.playerNaturallySpawnedEvent = event; } -@@ -603,10 +554,10 @@ public class ServerChunkCache extends ChunkSource { - io.papermc.paper.util.player.NearbyPlayers nearbyPlayers = this.chunkMap.getNearbyPlayers(); // Paper - optimise chunk tick iteration - Iterator iterator1; - if (this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { -- iterator1 = this.tickingChunks.iterator(); -+ iterator1 = regionizedWorldData.getTickingChunks().iterator(); // Folia - region threading - } else { -- iterator1 = this.tickingChunks.unsafeIterator(); -- List shuffled = Lists.newArrayListWithCapacity(this.tickingChunks.size()); -+ iterator1 = regionizedWorldData.getTickingChunks().unsafeIterator(); // Folia - region threading -+ List shuffled = Lists.newArrayListWithCapacity(regionizedWorldData.getTickingChunks().size()); // Folia - region threading - while (iterator1.hasNext()) { - shuffled.add(iterator1.next()); +@@ -563,7 +514,7 @@ public class ServerChunkCache extends ChunkSource { + NaturalSpawner.SpawnState spawnercreature_d; // moved down + if ((this.spawnFriendlies || this.spawnEnemies) && this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { // don't count mobs when animals and monsters are disabled + // re-set mob counts +- for (ServerPlayer player : this.level.players) { ++ for (ServerPlayer player : this.level.getLocalPlayers()) { // Folia - region threading + // Paper start - per player mob spawning backoff + for (int ii = 0; ii < ServerPlayer.MOBCATEGORY_TOTAL_ENUMS; ii++) { + player.mobCounts[ii] = 0; +@@ -576,21 +527,21 @@ public class ServerChunkCache extends ChunkSource { + } + // Paper end - per player mob spawning backoff + } +- spawnercreature_d = NaturalSpawner.createState(naturalSpawnChunkCount, this.level.getAllEntities(), this::getFullChunk, null, true); ++ spawnercreature_d = NaturalSpawner.createState(naturalSpawnChunkCount, regionizedWorldData.getLoadedEntities(), this::getFullChunk, null, true); // Folia - region threading - note: function only cares about loaded entities, doesn't need all + } else { +- spawnercreature_d = NaturalSpawner.createState(naturalSpawnChunkCount, this.level.getAllEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false); ++ spawnercreature_d = NaturalSpawner.createState(naturalSpawnChunkCount, regionizedWorldData.getLoadedEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false); // Folia - region threading - note: function only cares about loaded entities, doesn't need all } -@@ -673,17 +624,21 @@ public class ServerChunkCache extends ChunkSource { + // Paper end + this.level.timings.countNaturalMobs.stopTiming(); // Paper - timings + +- this.lastSpawnState = spawnercreature_d; ++ regionizedWorldData.lastSpawnState = spawnercreature_d; // Folia - region threading + gameprofilerfiller.popPush("spawnAndTick"); +- boolean flag = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.players().isEmpty(); // CraftBukkit ++ boolean flag = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.getLocalPlayers().isEmpty(); // CraftBukkit // Folia - region threadin + + // Paper start - optimise chunk tick iteration +- for (ServerPlayer player : this.level.players) { ++ for (ServerPlayer player : this.level.getLocalPlayers()) { // Folia - region threading + if (!player.affectsSpawning || player.isSpectator()) { +- playerChunkMap.playerMobSpawnMap.remove(player); ++ regionizedWorldData.mobSpawnMap.remove(player); // Folia - region threading + player.playerNaturallySpawnedEvent = null; + player.lastEntitySpawnRadiusSquared = -1.0; + continue; +@@ -606,7 +557,7 @@ public class ServerChunkCache extends ChunkSource { + com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent event = new com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent(player.getBukkitEntity(), (byte)chunkRange); + event.callEvent(); + if (event.isCancelled() || event.getSpawnRadius() < 0) { +- playerChunkMap.playerMobSpawnMap.remove(player); ++ regionizedWorldData.mobSpawnMap.remove(player); // Folia - region threading + player.playerNaturallySpawnedEvent = null; + player.lastEntitySpawnRadiusSquared = -1.0; + continue; +@@ -616,23 +567,23 @@ public class ServerChunkCache extends ChunkSource { + int chunkX = io.papermc.paper.util.CoordinateUtils.getChunkCoordinate(player.getX()); + int chunkZ = io.papermc.paper.util.CoordinateUtils.getChunkCoordinate(player.getZ()); + +- playerChunkMap.playerMobSpawnMap.addOrUpdate(player, chunkX, chunkZ, range); ++ regionizedWorldData.mobSpawnMap.addOrUpdate(player, chunkX, chunkZ, range); // Folia - region threading + player.lastEntitySpawnRadiusSquared = (double)((range << 4) * (range << 4)); // used in anyPlayerCloseEnoughForSpawning + player.playerNaturallySpawnedEvent = event; + } + // Paper end - optimise chunk tick iteration + int l = this.level.getGameRules().getInt(GameRules.RULE_RANDOMTICKING); +- boolean flag1 = this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) != 0L && this.level.getLevelData().getGameTime() % this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) == 0L; // CraftBukkit ++ boolean flag1 = this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) != 0L && this.level.getRedstoneGameTime() % this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) == 0L; // CraftBukkit // Folia - region threading + + int chunksTicked = 0; // Paper + // Paper start - optimise chunk tick iteration + io.papermc.paper.util.player.NearbyPlayers nearbyPlayers = this.chunkMap.getNearbyPlayers(); // Paper - optimise chunk tick iteration + Iterator chunkIterator; + if (this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { +- chunkIterator = this.tickingChunks.iterator(); ++ chunkIterator = regionizedWorldData.getTickingChunks().iterator(); // Folia - region threading + } else { +- chunkIterator = this.tickingChunks.unsafeIterator(); +- List shuffled = Lists.newArrayListWithCapacity(this.tickingChunks.size()); ++ chunkIterator = regionizedWorldData.getTickingChunks().unsafeIterator(); // Folia - region threading ++ List shuffled = Lists.newArrayListWithCapacity(regionizedWorldData.getTickingChunks().size()); // Folia - region threading + while (chunkIterator.hasNext()) { + shuffled.add(chunkIterator.next()); + } +@@ -702,17 +653,21 @@ public class ServerChunkCache extends ChunkSource { // Paper - optimise chunk tick iteration this.level.timings.broadcastChunkUpdates.startTiming(); // Paper - timing // Paper start - optimise chunk tick iteration @@ -12984,7 +13054,7 @@ index 8c33a12ca879c46893150d6adfb8aa4d397c6b4c..4ed40924942bc3252fb1a533190765fb + if (!io.papermc.paper.util.TickThread.isTickThreadFor(holder.newChunkHolder.world, holder.pos)) { + continue; + } -+ // don't need to worry about chunk holder remove, as that can only be done by this tick thread ++ // don't need to worry about asynchronous chunk holder remove, as that can only be done by this tick thread + holder.broadcastChanges(holder.getFullChunkNowUnchecked()); + if (!holder.needsBroadcastChanges()) { + iterator.remove(); @@ -12995,7 +13065,7 @@ index 8c33a12ca879c46893150d6adfb8aa4d397c6b4c..4ed40924942bc3252fb1a533190765fb // Paper end - optimise chunk tick iteration this.level.timings.broadcastChunkUpdates.stopTiming(); // Paper - timing // Paper - optimise chunk tick iteration -@@ -747,14 +702,19 @@ public class ServerChunkCache extends ChunkSource { +@@ -775,14 +730,19 @@ public class ServerChunkCache extends ChunkSource { @Override public void onLightUpdate(LightLayer type, SectionPos pos) { @@ -13017,7 +13087,7 @@ index 8c33a12ca879c46893150d6adfb8aa4d397c6b4c..4ed40924942bc3252fb1a533190765fb } public void addRegionTicket(TicketType ticketType, ChunkPos pos, int radius, T argument) { -@@ -826,7 +786,8 @@ public class ServerChunkCache extends ChunkSource { +@@ -854,7 +814,8 @@ public class ServerChunkCache extends ChunkSource { @Nullable @VisibleForDebug public NaturalSpawner.SpawnState getLastSpawnState() { @@ -13027,7 +13097,7 @@ index 8c33a12ca879c46893150d6adfb8aa4d397c6b4c..4ed40924942bc3252fb1a533190765fb } public void removeTicketsOnClosing() { -@@ -859,8 +820,43 @@ public class ServerChunkCache extends ChunkSource { +@@ -887,8 +848,43 @@ public class ServerChunkCache extends ChunkSource { return ServerChunkCache.this.mainThread; } @@ -13071,7 +13141,7 @@ index 8c33a12ca879c46893150d6adfb8aa4d397c6b4c..4ed40924942bc3252fb1a533190765fb ServerChunkCache.this.level.getProfiler().incrementCounter("runTask"); super.doRunTask(task); } -@@ -868,10 +864,15 @@ public class ServerChunkCache extends ChunkSource { +@@ -896,10 +892,15 @@ public class ServerChunkCache extends ChunkSource { @Override // CraftBukkit start - process pending Chunk loadCallback() and unloadCallback() after each run task public boolean pollTask() { @@ -13089,10 +13159,10 @@ index 8c33a12ca879c46893150d6adfb8aa4d397c6b4c..4ed40924942bc3252fb1a533190765fb } diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d30d5fd827 100644 +index b78a9628a88f2a495ef6de74446a02a14d41a1f6..72af30b281f2bb1dd4beee746a1b3f7bebbc7260 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -192,36 +192,35 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -194,36 +194,35 @@ public class ServerLevel extends Level implements WorldGenLevel { public final ServerChunkCache chunkSource; private final MinecraftServer server; public final PrimaryLevelData serverLevelData; // CraftBukkit - type @@ -13138,7 +13208,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 private final alternate.current.wire.WireHandler wireHandler = new alternate.current.wire.WireHandler(this); // Paper - optimize redstone (Alternate Current) public static Throwable getAddToWorldStackTrace(Entity entity) { final Throwable thr = new Throwable(entity + " Added to world at " + new java.util.Date()); -@@ -257,6 +256,36 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -259,6 +258,36 @@ public class ServerLevel extends Level implements WorldGenLevel { ServerChunkCache chunkProvider = this.getChunkSource(); @@ -13175,7 +13245,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 for (int cx = minChunkX; cx <= maxChunkX; ++cx) { for (int cz = minChunkZ; cz <= maxChunkZ; ++cz) { if (chunkProvider.getChunkAtIfLoadedImmediately(cx, cz) == null) { -@@ -565,14 +594,14 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -567,14 +596,14 @@ public class ServerLevel extends Level implements WorldGenLevel { } // Paper end // Paper start - lag compensation @@ -13193,7 +13263,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 } // Paper end - lag compensation // Paper start - optimise nearby player retrieval -@@ -619,7 +648,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -621,7 +650,7 @@ public class ServerLevel extends Level implements WorldGenLevel { ServerPlayer nearest = null; double nearestDist = Double.MAX_VALUE; @@ -13202,7 +13272,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 double dist = player.distanceToSqr(x, y, z); if (dist >= nearestDist) { continue; -@@ -675,7 +704,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -677,7 +706,7 @@ public class ServerLevel extends Level implements WorldGenLevel { return nearest; } else { @@ -13211,7 +13281,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 } } -@@ -684,6 +713,58 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -686,6 +715,58 @@ public class ServerLevel extends Level implements WorldGenLevel { return this.getNearestPlayer(targetPredicate, null, x, y, z); } // Paper end - optimise nearby player retrieval @@ -13270,7 +13340,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 // Add env and gen to constructor, IWorldDataServer -> WorldDataServer public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List list, boolean flag1, @Nullable RandomSequences randomsequences, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) { -@@ -696,13 +777,13 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -698,13 +779,13 @@ public class ServerLevel extends Level implements WorldGenLevel { this.convertable = convertable_conversionsession; this.uuid = WorldUUID.getUUID(convertable_conversionsession.levelDirectory.path().toFile()); // CraftBukkit end @@ -13290,7 +13360,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 this.dragonParts = new Int2ObjectOpenHashMap(); this.tickTime = flag1; this.server = minecraftserver; -@@ -741,7 +822,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -743,7 +824,7 @@ public class ServerLevel extends Level implements WorldGenLevel { }); this.chunkSource.getGeneratorState().ensureStructuresGenerated(); this.portalForcer = new PortalForcer(this); @@ -13299,7 +13369,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 this.prepareWeather(); this.getWorldBorder().setAbsoluteMaxSize(minecraftserver.getAbsoluteMaxWorldSize()); this.raids = (Raids) this.getDataStorage().computeIfAbsent(Raids.factory(this), Raids.getFileId(this.dimensionTypeRegistration())); -@@ -768,7 +849,14 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -770,7 +851,14 @@ public class ServerLevel extends Level implements WorldGenLevel { this.chunkTaskScheduler = new io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler(this, io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.workerThreads); // Paper - rewrite chunk system this.entityLookup = new io.papermc.paper.chunk.system.entity.EntityLookup(this, new EntityCallbacks()); // Paper - rewrite chunk system @@ -13314,7 +13384,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 // Paper start @Override -@@ -801,47 +889,30 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -803,44 +891,27 @@ public class ServerLevel extends Level implements WorldGenLevel { return this.structureManager; } @@ -13325,14 +13395,20 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 - this.handlingTick = true; + regionizedWorldData.setHandlingTick(true); // Folia - regionised ticking - gameprofilerfiller.push("world border"); -- this.getWorldBorder().tick(); -+ if (region == null) this.getWorldBorder().tick(); // Folia - regionised ticking - moved into global tick - gameprofilerfiller.popPush("weather"); -- this.advanceWeatherCycle(); + TickRateManager tickratemanager = this.tickRateManager(); + boolean flag = tickratemanager.runsNormally(); + + if (flag) { + gameprofilerfiller.push("world border"); +- this.getWorldBorder().tick(); ++ if (region == null) this.getWorldBorder().tick(); // Folia - regionised ticking + gameprofilerfiller.popPush("weather"); +- this.advanceWeatherCycle(); ++ if (region == null) this.advanceWeatherCycle(); // Folia - regionised ticking + } + - int i = this.getGameRules().getInt(GameRules.RULE_PLAYERS_SLEEPING_PERCENTAGE); -+ if (region == null) this.advanceWeatherCycle(); -+ //int i = this.getGameRules().getInt(GameRules.RULE_PLAYERS_SLEEPING_PERCENTAGE); // Folia - region threading - move intotickSleep ++ //int i = this.getGameRules().getInt(GameRules.RULE_PLAYERS_SLEEPING_PERCENTAGE); // Folia - region threading - move into tickSleep long j; - if (this.sleepStatus.areEnoughSleeping(i) && this.sleepStatus.areEnoughDeepSleeping(i, this.players)) { @@ -13358,10 +13434,13 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 - this.updateSkyBrightness(); + if (region == null) this.updateSkyBrightness(); // Folia - region threading - this.tickTime(); + if (flag) { + this.tickTime(); + } +@@ -848,11 +919,11 @@ public class ServerLevel extends Level implements WorldGenLevel { gameprofilerfiller.popPush("tickPending"); this.timings.scheduledBlocks.startTiming(); // Paper - if (!this.isDebug()) { + if (!this.isDebug() && flag) { - j = this.getGameTime(); + j = regionizedWorldData.getRedstoneGameTime(); // Folia - region threading gameprofilerfiller.push("blockTicks"); @@ -13373,26 +13452,26 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 gameprofilerfiller.pop(); } this.timings.scheduledBlocks.stopTiming(); // Paper -@@ -858,7 +929,7 @@ public class ServerLevel extends Level implements WorldGenLevel { - this.timings.doSounds.startTiming(); // Spigot - this.runBlockEvents(); - this.timings.doSounds.stopTiming(); // Spigot +@@ -875,7 +946,7 @@ public class ServerLevel extends Level implements WorldGenLevel { + this.timings.doSounds.stopTiming(); // Spigot + } + - this.handlingTick = false; + regionizedWorldData.setHandlingTick(false); // Folia - regionised ticking gameprofilerfiller.pop(); - boolean flag = true || !this.players.isEmpty() || !this.getForcedChunks().isEmpty(); // CraftBukkit - this prevents entity cleanup, other issues on servers with no players + boolean flag1 = true || !this.players.isEmpty() || !this.getForcedChunks().isEmpty(); // CraftBukkit - this prevents entity cleanup, other issues on servers with no players -@@ -870,20 +941,30 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -887,20 +958,30 @@ public class ServerLevel extends Level implements WorldGenLevel { gameprofilerfiller.push("entities"); this.timings.tickEntities.startTiming(); // Spigot - if (this.dragonFight != null) { + if (this.dragonFight != null && flag) { + if (io.papermc.paper.util.TickThread.isTickThreadFor(this, this.dragonFight.origin)) { // Folia - region threading gameprofilerfiller.push("dragonFight"); this.dragonFight.tick(); gameprofilerfiller.pop(); -+ } else { // Folia start - region threading ++ } else { // Folia start - region threading + // try to load dragon fight -+ ChunkPos fightCenter = new ChunkPos(0, 0); ++ ChunkPos fightCenter = new ChunkPos(this.dragonFight.origin); + this.chunkSource.addTicketAtLevel( + TicketType.UNKNOWN, fightCenter, io.papermc.paper.chunk.system.scheduling.ChunkHolderManager.MAX_TICKET_LEVEL, + fightCenter @@ -13407,14 +13486,14 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 if (!entity.isRemoved()) { if (false && this.shouldDiscardEntity(entity)) { // CraftBukkit - We prevent spawning in general, so this butchering is not needed entity.discard(); - } else { + } else if (!tickratemanager.isEntityFrozen(entity)) { gameprofilerfiller.push("checkDespawn"); entity.checkDespawn(); + if (entity.isRemoved()) return; // Folia - region threading - if we despawned, DON'T TICK IT! gameprofilerfiller.pop(); if (true || this.chunkSource.chunkMap.getDistanceManager().inEntityTickingRange(entity.chunkPosition().toLong())) { // Paper - now always true if in the ticking list Entity entity1 = entity.getVehicle(); -@@ -914,6 +995,31 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -931,6 +1012,31 @@ public class ServerLevel extends Level implements WorldGenLevel { gameprofilerfiller.pop(); } @@ -13446,7 +13525,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 @Override public boolean shouldTickBlocksAt(long chunkPos) { // Paper start - replace player chunk loader system -@@ -924,11 +1030,12 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -941,11 +1047,12 @@ public class ServerLevel extends Level implements WorldGenLevel { protected void tickTime() { if (this.tickTime) { @@ -13463,7 +13542,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 this.setDayTime(this.levelData.getDayTime() + 1L); } -@@ -957,15 +1064,23 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -974,15 +1081,23 @@ public class ServerLevel extends Level implements WorldGenLevel { private void wakeUpAllPlayers() { this.sleepStatus.removeAllSleepers(); (this.players.stream().filter(LivingEntity::isSleeping).collect(Collectors.toList())).forEach((entityplayer) -> { // CraftBukkit - decompile error @@ -13490,7 +13569,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 ChunkPos chunkcoordintpair = chunk.getPos(); boolean flag = this.isRaining(); int j = chunkcoordintpair.getMinBlockX(); -@@ -973,7 +1088,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -990,7 +1105,7 @@ public class ServerLevel extends Level implements WorldGenLevel { ProfilerFiller gameprofilerfiller = this.getProfiler(); gameprofilerfiller.push("thunder"); @@ -13499,7 +13578,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 if (!this.paperConfig().environment.disableThunder && flag && this.isThundering() && this.spigotConfig.thunderChance > 0 && this.random.nextInt(this.spigotConfig.thunderChance) == 0) { // Spigot // Paper - disable thunder blockposition.set(this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15))); // Paper -@@ -1027,7 +1142,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1046,7 +1161,7 @@ public class ServerLevel extends Level implements WorldGenLevel { int yPos = (sectionIndex + minSection) << 4; for (int a = 0; a < randomTickSpeed; ++a) { int tickingBlocks = section.tickingList.size(); @@ -13508,16 +13587,16 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 if (index >= tickingBlocks) { continue; } -@@ -1041,7 +1156,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1060,7 +1175,7 @@ public class ServerLevel extends Level implements WorldGenLevel { BlockPos blockposition2 = blockposition.set(j + randomX, randomY, k + randomZ); BlockState iblockdata = com.destroystokyo.paper.util.maplist.IBlockDataList.getBlockDataFromRaw(raw); - iblockdata.randomTick(this, blockposition2, this.randomTickRandom); + iblockdata.randomTick(this, blockposition2, randomTickRandom); // Folia - region threading - // We drop the fluid tick since LAVA is ALREADY TICKED by the above method (See LiquidBlock). - // TODO CHECK ON UPDATE (ping the Canadian) } -@@ -1142,7 +1257,7 @@ public class ServerLevel extends Level implements WorldGenLevel { + // We drop the fluid tick since LAVA is ALREADY TICKED by the above method (See LiquidBlock). + // TODO CHECK ON UPDATE (ping the Canadian) +@@ -1165,7 +1280,7 @@ public class ServerLevel extends Level implements WorldGenLevel { } public boolean isHandlingTick() { @@ -13526,7 +13605,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 } public boolean canSleepThroughNights() { -@@ -1174,6 +1289,14 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1197,6 +1312,14 @@ public class ServerLevel extends Level implements WorldGenLevel { } public void updateSleepingPlayerList() { @@ -13541,7 +13620,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 if (!this.players.isEmpty() && this.sleepStatus.update(this.players)) { this.announceSleepStatus(); } -@@ -1185,7 +1308,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1208,7 +1331,7 @@ public class ServerLevel extends Level implements WorldGenLevel { return this.server.getScoreboard(); } @@ -13550,7 +13629,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 boolean flag = this.isRaining(); if (this.dimensionType().hasSkyLight()) { -@@ -1271,23 +1394,24 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1294,23 +1417,24 @@ public class ServerLevel extends Level implements WorldGenLevel { this.server.getPlayerList().broadcastAll(new PacketPlayOutGameStateChange(PacketPlayOutGameStateChange.THUNDER_LEVEL_CHANGE, this.thunderLevel)); } // */ @@ -13584,7 +13663,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 } } // CraftBukkit end -@@ -1351,7 +1475,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1375,7 +1499,7 @@ public class ServerLevel extends Level implements WorldGenLevel { public void tickNonPassenger(Entity entity) { // Paper start - log detailed entity tick information @@ -13593,7 +13672,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 try { if (currentlyTickingEntity.get() == null) { currentlyTickingEntity.lazySet(entity); -@@ -1384,7 +1508,16 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1408,7 +1532,16 @@ public class ServerLevel extends Level implements WorldGenLevel { if (isActive) { // Paper - EAR 2 TimingHistory.activatedEntityTicks++; entity.tick(); @@ -13611,7 +13690,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 } else { entity.inactiveTick(); } // Paper - EAR 2 this.getProfiler().pop(); } finally { timer.stopTiming(); } // Paper - timings -@@ -1407,7 +1540,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1431,7 +1564,7 @@ public class ServerLevel extends Level implements WorldGenLevel { private void tickPassenger(Entity vehicle, Entity passenger) { if (!passenger.isRemoved() && passenger.getVehicle() == vehicle) { @@ -13620,7 +13699,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 // Paper - EAR 2 final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(passenger); co.aikar.timings.Timing timer = isActive ? passenger.getType().passengerTickTimer.startTiming() : passenger.getType().passengerInactiveTickTimer.startTiming(); // Paper -@@ -1424,7 +1557,16 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1448,7 +1581,16 @@ public class ServerLevel extends Level implements WorldGenLevel { // Paper start - EAR 2 if (isActive) { passenger.rideTick(); @@ -13638,7 +13717,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 } else { passenger.setDeltaMovement(Vec3.ZERO); passenger.inactiveTick(); -@@ -1512,7 +1654,15 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1536,7 +1678,15 @@ public class ServerLevel extends Level implements WorldGenLevel { // Paper - rewrite chunk system - entity saving moved into ChunkHolder } else if (close) { chunkproviderserver.close(false); } // Paper - rewrite chunk system @@ -13654,7 +13733,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 // CraftBukkit start - moved from MinecraftServer.saveChunks ServerLevel worldserver1 = this; -@@ -1520,12 +1670,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1544,12 +1694,7 @@ public class ServerLevel extends Level implements WorldGenLevel { this.serverLevelData.setCustomBossEvents(this.server.getCustomBossEvents().save()); this.convertable.saveDataTag(this.server.registryAccess(), this.serverLevelData, this.server.getPlayerList().getSingleplayerData()); // CraftBukkit end @@ -13668,7 +13747,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 this.getChunkSource().getDataStorage().save(); } -@@ -1580,6 +1725,19 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1604,6 +1749,19 @@ public class ServerLevel extends Level implements WorldGenLevel { return list; } @@ -13688,7 +13767,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 @Nullable public ServerPlayer getRandomPlayer() { List list = this.getPlayers(LivingEntity::isAlive); -@@ -1681,8 +1839,8 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1705,8 +1863,8 @@ public class ServerLevel extends Level implements WorldGenLevel { } else { if (entity instanceof net.minecraft.world.entity.item.ItemEntity itemEntity && itemEntity.getItem().isEmpty()) return false; // Paper - Prevent empty items from being added // Paper start - capture all item additions to the world @@ -13699,7 +13778,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 return true; } // Paper end -@@ -1826,7 +1984,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1850,7 +2008,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @Override public void sendBlockUpdated(BlockPos pos, BlockState oldState, BlockState newState, int flags) { @@ -13708,7 +13787,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 String s = "recursive call to sendBlockUpdated"; Util.logAndPauseIfInIde("recursive call to sendBlockUpdated", new IllegalStateException("recursive call to sendBlockUpdated")); -@@ -1839,7 +1997,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1863,7 +2021,7 @@ public class ServerLevel extends Level implements WorldGenLevel { if (Shapes.joinIsNotEmpty(voxelshape, voxelshape1, BooleanOp.NOT_SAME)) { List list = new ObjectArrayList(); @@ -13717,7 +13796,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 while (iterator.hasNext()) { // CraftBukkit start - fix SPIGOT-6362 -@@ -1862,7 +2020,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1886,7 +2044,7 @@ public class ServerLevel extends Level implements WorldGenLevel { } try { @@ -13726,7 +13805,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 iterator = list.iterator(); while (iterator.hasNext()) { -@@ -1871,7 +2029,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1895,7 +2053,7 @@ public class ServerLevel extends Level implements WorldGenLevel { navigationabstract1.recomputePath(); } } finally { @@ -13735,7 +13814,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 } } -@@ -1880,23 +2038,23 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1904,23 +2062,23 @@ public class ServerLevel extends Level implements WorldGenLevel { @Override public void updateNeighborsAt(BlockPos pos, Block sourceBlock) { @@ -13764,7 +13843,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 } @Override -@@ -1927,7 +2085,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1951,7 +2109,7 @@ public class ServerLevel extends Level implements WorldGenLevel { explosion.clearToBlow(); } @@ -13773,7 +13852,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 while (iterator.hasNext()) { ServerPlayer entityplayer = (ServerPlayer) iterator.next(); -@@ -1942,25 +2100,28 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1966,25 +2124,28 @@ public class ServerLevel extends Level implements WorldGenLevel { @Override public void blockEvent(BlockPos pos, Block block, int type, int data) { @@ -13808,7 +13887,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 } private boolean doBlockEvent(BlockEventData event) { -@@ -1971,12 +2132,12 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1995,12 +2156,12 @@ public class ServerLevel extends Level implements WorldGenLevel { @Override public LevelTicks getBlockTicks() { @@ -13823,7 +13902,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 } @Nonnull -@@ -2000,7 +2161,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2024,7 +2185,7 @@ public class ServerLevel extends Level implements WorldGenLevel { public int sendParticles(ServerPlayer sender, T t0, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6, boolean force) { // Paper start - Particle API Expansion @@ -13832,7 +13911,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 } public int sendParticles(List receivers, @Nullable ServerPlayer sender, T t0, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6, boolean force) { // Paper end -@@ -2053,7 +2214,14 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2077,7 +2238,14 @@ public class ServerLevel extends Level implements WorldGenLevel { public Entity getEntityOrPart(int id) { Entity entity = (Entity) this.getEntities().get(id); @@ -13848,7 +13927,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 } @Nullable -@@ -2220,6 +2388,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2255,6 +2423,7 @@ public class ServerLevel extends Level implements WorldGenLevel { } public boolean setChunkForced(int x, int z, boolean forced) { @@ -13856,7 +13935,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 ForcedChunksSavedData forcedchunk = (ForcedChunksSavedData) this.getDataStorage().computeIfAbsent(ForcedChunksSavedData.factory(), "chunks"); ChunkPos chunkcoordintpair = new ChunkPos(x, z); long k = chunkcoordintpair.toLong(); -@@ -2228,7 +2397,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2263,7 +2432,7 @@ public class ServerLevel extends Level implements WorldGenLevel { if (forced) { flag1 = forcedchunk.getChunks().add(k); if (flag1) { @@ -13865,7 +13944,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 } } else { flag1 = forcedchunk.getChunks().remove(k); -@@ -2256,13 +2425,18 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2291,13 +2460,18 @@ public class ServerLevel extends Level implements WorldGenLevel { BlockPos blockposition1 = pos.immutable(); optional.ifPresent((holder) -> { @@ -13887,7 +13966,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 // Paper start if (optional.isEmpty() && this.getPoiManager().exists(blockposition1, poiType -> true)) { this.getPoiManager().remove(blockposition1); -@@ -2270,7 +2444,12 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2305,7 +2479,12 @@ public class ServerLevel extends Level implements WorldGenLevel { // Paper end this.getPoiManager().add(blockposition1, holder); DebugPackets.sendPoiAddedPacket(this, blockposition1); @@ -13901,7 +13980,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 }); } } -@@ -2317,7 +2496,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2352,7 +2531,7 @@ public class ServerLevel extends Level implements WorldGenLevel { BufferedWriter bufferedwriter = Files.newBufferedWriter(path.resolve("stats.txt")); try { @@ -13910,7 +13989,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 NaturalSpawner.SpawnState spawnercreature_d = this.getChunkSource().getLastSpawnState(); if (spawnercreature_d != null) { -@@ -2331,7 +2510,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2366,7 +2545,7 @@ public class ServerLevel extends Level implements WorldGenLevel { } bufferedwriter.write(String.format(Locale.ROOT, "entities: %s\n", this.entityLookup.getDebugInfo())); // Paper - rewrite chunk system @@ -13919,7 +13998,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 bufferedwriter.write(String.format(Locale.ROOT, "block_ticks: %d\n", this.getBlockTicks().count())); bufferedwriter.write(String.format(Locale.ROOT, "fluid_ticks: %d\n", this.getFluidTicks().count())); bufferedwriter.write("distance_manager: " + playerchunkmap.getDistanceManager().getDebugStatus() + "\n"); -@@ -2477,7 +2656,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2512,7 +2691,7 @@ public class ServerLevel extends Level implements WorldGenLevel { private void dumpBlockEntityTickers(Writer writer) throws IOException { CsvOutput csvwriter = CsvOutput.builder().addColumn("x").addColumn("y").addColumn("z").addColumn("type").build(writer); @@ -13928,7 +14007,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 while (iterator.hasNext()) { TickingBlockEntity tickingblockentity = (TickingBlockEntity) iterator.next(); -@@ -2490,7 +2669,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2525,7 +2704,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @VisibleForTesting public void clearBlockEvents(BoundingBox box) { @@ -13937,7 +14016,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 return box.isInside(blockactiondata.pos()); }); } -@@ -2499,7 +2678,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2534,7 +2713,7 @@ public class ServerLevel extends Level implements WorldGenLevel { public void blockUpdated(BlockPos pos, Block block) { if (!this.isDebug()) { // CraftBukkit start @@ -13946,7 +14025,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 return; } // CraftBukkit end -@@ -2542,9 +2721,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2577,9 +2756,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @VisibleForTesting public String getWatchdogStats() { @@ -13957,7 +14036,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 } private static String getTypeCount(Iterable items, Function classifier) { -@@ -2577,6 +2754,12 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2612,6 +2789,12 @@ public class ServerLevel extends Level implements WorldGenLevel { public static void makeObsidianPlatform(ServerLevel worldserver, Entity entity) { // CraftBukkit end BlockPos blockposition = ServerLevel.END_SPAWN_POINT; @@ -13970,7 +14049,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 int i = blockposition.getX(); int j = blockposition.getY() - 2; int k = blockposition.getZ(); -@@ -2589,11 +2772,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2624,11 +2807,7 @@ public class ServerLevel extends Level implements WorldGenLevel { BlockPos.betweenClosed(i - 2, j, k - 2, i + 2, j, k + 2).forEach((blockposition1) -> { blockList.setBlock(blockposition1, Blocks.OBSIDIAN.defaultBlockState(), 3); }); @@ -13983,7 +14062,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 blockList.updateList(); } // CraftBukkit end -@@ -2614,13 +2793,14 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2649,13 +2828,14 @@ public class ServerLevel extends Level implements WorldGenLevel { } public void startTickingChunk(LevelChunk chunk) { @@ -14002,7 +14081,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 } @Override -@@ -2642,7 +2822,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2677,7 +2857,7 @@ public class ServerLevel extends Level implements WorldGenLevel { // Paper end - rewrite chunk system } @@ -14011,7 +14090,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 // Paper start - optimize is ticking ready type functions io.papermc.paper.chunk.system.scheduling.NewChunkHolder chunkHolder = this.chunkTaskScheduler.chunkHolderManager.getChunkHolder(chunkPos); // isTicking implies the chunk is loaded, and the chunk is loaded now implies the entities are loaded -@@ -2698,16 +2878,16 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2743,16 +2923,16 @@ public class ServerLevel extends Level implements WorldGenLevel { public void onCreated(Entity entity) {} public void onDestroyed(Entity entity) { @@ -14031,7 +14110,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 // Paper start - Reset pearls when they stop being ticked if (paperConfig().fixes.disableUnloadedChunkEnderpearlExploit && entity instanceof net.minecraft.world.entity.projectile.ThrownEnderpearl pearl) { pearl.cachedOwner = null; -@@ -2718,6 +2898,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2763,6 +2943,7 @@ public class ServerLevel extends Level implements WorldGenLevel { public void onTrackingStart(Entity entity) { org.spigotmc.AsyncCatcher.catchOp("entity register"); // Spigot @@ -14039,7 +14118,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 // ServerLevel.this.getChunkSource().addEntity(entity); // Paper - moved down below valid=true if (entity instanceof ServerPlayer) { ServerPlayer entityplayer = (ServerPlayer) entity; -@@ -2735,7 +2916,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2780,7 +2961,7 @@ public class ServerLevel extends Level implements WorldGenLevel { Util.logAndPauseIfInIde("onTrackingStart called during navigation iteration", new IllegalStateException("onTrackingStart called during navigation iteration")); } @@ -14048,7 +14127,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 } if (entity instanceof EnderDragon) { -@@ -2746,7 +2927,9 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2791,7 +2972,9 @@ public class ServerLevel extends Level implements WorldGenLevel { for (int j = 0; j < i; ++j) { EnderDragonPart entitycomplexpart = aentitycomplexpart[j]; @@ -14058,7 +14137,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 } } -@@ -2767,16 +2950,24 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2813,16 +2996,24 @@ public class ServerLevel extends Level implements WorldGenLevel { public void onTrackingEnd(Entity entity) { org.spigotmc.AsyncCatcher.catchOp("entity unregister"); // Spigot @@ -14084,7 +14163,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 map.carriedByPlayers.remove( (Player) entity ); for ( Iterator iter = (Iterator) map.carriedBy.iterator(); iter.hasNext(); ) { -@@ -2786,6 +2977,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2832,6 +3023,7 @@ public class ServerLevel extends Level implements WorldGenLevel { iter.remove(); } } @@ -14092,7 +14171,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 } } } ); -@@ -2820,7 +3012,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2866,7 +3058,7 @@ public class ServerLevel extends Level implements WorldGenLevel { Util.logAndPauseIfInIde("onTrackingStart called during navigation iteration", new IllegalStateException("onTrackingStart called during navigation iteration")); } @@ -14101,7 +14180,7 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 } if (entity instanceof EnderDragon) { -@@ -2831,13 +3023,16 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2877,13 +3069,16 @@ public class ServerLevel extends Level implements WorldGenLevel { for (int j = 0; j < i; ++j) { EnderDragonPart entitycomplexpart = aentitycomplexpart[j]; @@ -14119,10 +14198,10 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..10cf0ffb2cf519f0904dbe709b9042d3 for (ServerPlayer player : ServerLevel.this.players) { player.getBukkitEntity().onEntityRemove(entity); diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index f71a4a8307fb092d33545e12d253e0b80c884168..89f7825a8cf415f3c2e0ddcb41c159a84d2e4bd1 100644 +index 8efbbd379244e3ed54d4aba199037cc20ccd096a..c66815bd2a13554aec7176258f8fae542d668d3f 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -185,7 +185,7 @@ import org.bukkit.inventory.MainHand; +@@ -191,7 +191,7 @@ import org.bukkit.inventory.MainHand; public class ServerPlayer extends Player { private static final Logger LOGGER = LogUtils.getLogger(); @@ -14130,8 +14209,8 @@ index f71a4a8307fb092d33545e12d253e0b80c884168..89f7825a8cf415f3c2e0ddcb41c159a8 + public long lastSave = Long.MIN_VALUE; // Paper // Folia - threaded regions - changed to nanoTime private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_XZ = 32; private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10; - public ServerGamePacketListenerImpl connection; -@@ -463,51 +463,151 @@ public class ServerPlayer extends Player { + private static final int FLY_STAT_RECORDING_SPEED = 25; +@@ -470,51 +470,151 @@ public class ServerPlayer extends Player { } // CraftBukkit end @@ -14214,7 +14293,7 @@ index f71a4a8307fb092d33545e12d253e0b80c884168..89f7825a8cf415f3c2e0ddcb41c159a8 + ++attemptCount[0]; - if (blockposition1 != null) { -- this.moveTo(blockposition1, 0.0F, 0.0F); +- this.moveTo(blockposition1, world.getSharedSpawnAngle(), 0.0F); // Paper - MC-200092 - fix first spawn pos yaw being ignored - if (world.noCollision(this, this.getBoundingBox(), true)) { // Paper - make sure this loads chunks, we default to NOT loading now - break; + BlockPos rough = getRandomSpawn(world, random); @@ -14241,7 +14320,7 @@ index f71a4a8307fb092d33545e12d253e0b80c884168..89f7825a8cf415f3c2e0ddcb41c159a8 } - } - } else { -- this.moveTo(blockposition, 0.0F, 0.0F); +- this.moveTo(blockposition, world.getSharedSpawnAngle(), 0.0F); // Paper - MC-200092 - fix first spawn pos yaw being ignored + ); + return true; + } @@ -14313,7 +14392,7 @@ index f71a4a8307fb092d33545e12d253e0b80c884168..89f7825a8cf415f3c2e0ddcb41c159a8 return horizontalSpawnArea <= 16 ? horizontalSpawnArea - 1 : 17; } -@@ -1166,6 +1266,337 @@ public class ServerPlayer extends Player { +@@ -1168,6 +1268,337 @@ public class ServerPlayer extends Player { } } @@ -14651,7 +14730,7 @@ index f71a4a8307fb092d33545e12d253e0b80c884168..89f7825a8cf415f3c2e0ddcb41c159a8 @Nullable @Override public Entity changeDimension(ServerLevel destination) { -@@ -1175,6 +1606,11 @@ public class ServerPlayer extends Player { +@@ -1177,6 +1608,11 @@ public class ServerPlayer extends Player { @Nullable public Entity changeDimension(ServerLevel worldserver, PlayerTeleportEvent.TeleportCause cause) { @@ -14663,7 +14742,7 @@ index f71a4a8307fb092d33545e12d253e0b80c884168..89f7825a8cf415f3c2e0ddcb41c159a8 // CraftBukkit end if (this.isSleeping()) return this; // CraftBukkit - SPIGOT-3154 // this.isChangingDimension = true; // CraftBukkit - Moved down and into PlayerList#changeDimension -@@ -2132,6 +2568,12 @@ public class ServerPlayer extends Player { +@@ -2231,6 +2667,12 @@ public class ServerPlayer extends Player { public void setCamera(@Nullable Entity entity) { Entity entity1 = this.getCamera(); @@ -14676,7 +14755,7 @@ index f71a4a8307fb092d33545e12d253e0b80c884168..89f7825a8cf415f3c2e0ddcb41c159a8 this.camera = (Entity) (entity == null ? this : entity); if (entity1 != this.camera) { // Paper start - Add PlayerStartSpectatingEntityEvent and PlayerStopSpectatingEntity Event -@@ -2633,7 +3075,7 @@ public class ServerPlayer extends Player { +@@ -2732,7 +3174,7 @@ public class ServerPlayer extends Player { this.experienceLevel = this.newLevel; this.totalExperience = this.newTotalExp; this.experienceProgress = 0; @@ -14686,7 +14765,7 @@ index f71a4a8307fb092d33545e12d253e0b80c884168..89f7825a8cf415f3c2e0ddcb41c159a8 this.removeAllEffects(org.bukkit.event.entity.EntityPotionEffectEvent.Cause.DEATH); this.effectsDirty = true; diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -index 106a312aba249d1e83e4b535fc6e741e04ccfd14..0806559b4f4cebc88fb1f724a6916dac0c0c95e4 100644 +index 58f972832c39a27a8ccd606f9144e1c54adbf6f3..150bc66a9319cf33ce0782e22173e88cd77073e9 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java @@ -128,7 +128,7 @@ public class ServerPlayerGameMode { @@ -14707,16 +14786,16 @@ index 106a312aba249d1e83e4b535fc6e741e04ccfd14..0806559b4f4cebc88fb1f724a6916dac if (iblockdata == null) { this.isDestroyingBlock = false; return; -@@ -417,7 +417,7 @@ public class ServerPlayerGameMode { +@@ -416,7 +416,7 @@ public class ServerPlayerGameMode { } else { // CraftBukkit start org.bukkit.block.BlockState state = bblock.getState(); - this.level.captureDrops = new ArrayList<>(); + this.level.getCurrentWorldData().captureDrops = new ArrayList<>(); // Folia - region threading // CraftBukkit end - block.playerWillDestroy(this.level, pos, iblockdata, this.player); + BlockState iblockdata1 = block.playerWillDestroy(this.level, pos, iblockdata, this.player); boolean flag = this.level.removeBlock(pos, false); -@@ -445,8 +445,8 @@ public class ServerPlayerGameMode { +@@ -444,8 +444,8 @@ public class ServerPlayerGameMode { // return true; // CraftBukkit } // CraftBukkit start @@ -14838,7 +14917,7 @@ index 658e63ebde81dc14c8ab5850fb246dc0aab25dea..7e1f15ac8d2f7c86d4aba1be5df71705 public static TicketType create(String name, Comparator argumentComparator) { return new TicketType<>(name, argumentComparator, 0L); diff --git a/src/main/java/net/minecraft/server/level/WorldGenRegion.java b/src/main/java/net/minecraft/server/level/WorldGenRegion.java -index 50ed7cfe1ecef6d075ba484804827cec83ba2bf2..41c03421edd88dba669354595a2ace1277d93af6 100644 +index 14a5492428eac823a295ef3746d0aca6fbdab4ec..f06392b0515da3640720e115709fe98f86821024 100644 --- a/src/main/java/net/minecraft/server/level/WorldGenRegion.java +++ b/src/main/java/net/minecraft/server/level/WorldGenRegion.java @@ -84,6 +84,13 @@ public class WorldGenRegion implements WorldGenLevel { @@ -14856,7 +14935,7 @@ index 50ed7cfe1ecef6d075ba484804827cec83ba2bf2..41c03421edd88dba669354595a2ace12 this.generatingStatus = status; this.writeRadiusCutoff = placementRadius; diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -index 598f807f0d0caac98b81e0e2991f1bd497c4534e..2bb944cef9bc8c5e56023ef20921ef13509d4823 100644 +index 4a712f5fc4f0b4a4434ae808c989113bee8d8634..ce200192b4dddfc9b2d3c355838596b7deef1c69 100644 --- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java @@ -85,6 +85,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack @@ -14916,7 +14995,7 @@ index 598f807f0d0caac98b81e0e2991f1bd497c4534e..2bb944cef9bc8c5e56023ef20921ef13 protected boolean isSingleplayerOwner() { diff --git a/src/main/java/net/minecraft/server/network/ServerConfigurationPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerConfigurationPacketListenerImpl.java -index 8dbcc1b3a70b6bbea3bd2d15b6d66cc4f9cd53f8..d57130a8e1d28ce2458d11197911d12b9ca801ea 100644 +index cae10b963d153fb1777b18054796a45b2809342b..080a25714937e8413c4e9d15eb257f726a03ea7f 100644 --- a/src/main/java/net/minecraft/server/network/ServerConfigurationPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerConfigurationPacketListenerImpl.java @@ -43,6 +43,7 @@ public class ServerConfigurationPacketListenerImpl extends ServerCommonPacketLis @@ -15015,19 +15094,19 @@ index 79326308f6126f84a3cbb3d5a33302de048d8a50..81090d1b5d67506268a41c6387a1d453 Collections.shuffle( this.connections ); } diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775679c4ce9 100644 +index 30ccbab1586a656e0ae41d7406525fb02d9e025b..645ab5d149a207bed00357fe0aaf070d4b27d15a 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -289,7 +289,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - private final LastSeenMessagesValidator lastSeenMessages; - private final MessageSignatureCache messageSignatureCache; +@@ -292,7 +292,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + private final LastSeenMessagesValidator lastSeenMessages = new LastSeenMessagesValidator(20); + private final MessageSignatureCache messageSignatureCache = MessageSignatureCache.createDefault(); private final FutureChain chatMessageChain; - private boolean waitingForSwitchToConfig; + public volatile boolean waitingForSwitchToConfig; // Folia - rewrite login process - fix bad ordering of this field write + public private static final int MAX_SIGN_LINE_LENGTH = Integer.getInteger("Paper.maxSignLength", 80); // Paper public ServerGamePacketListenerImpl(MinecraftServer server, Connection connection, ServerPlayer player, CommonListenerCookie clientData) { -@@ -307,10 +307,10 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -310,10 +310,10 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } // CraftBukkit start - add fields @@ -15041,7 +15120,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 private int dropCount = 0; // Get position of last block hit for BlockDamageLevel.STOPPED -@@ -323,8 +323,21 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -326,8 +326,21 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl private boolean hasMoved; // Spigot // CraftBukkit end @@ -15063,7 +15142,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 if (this.ackBlockChangesUpTo > -1) { this.send(new ClientboundBlockChangedAckPacket(this.ackBlockChangesUpTo)); this.ackBlockChangesUpTo = -1; -@@ -373,7 +386,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -376,7 +389,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.aboveGroundVehicleTickCount = 0; } @@ -15072,7 +15151,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 // CraftBukkit start for (int spam; (spam = this.chatSpamTickCount.get()) > 0 && !this.chatSpamTickCount.compareAndSet(spam, spam - 1); ) ; if (tabSpamLimiter.get() > 0) tabSpamLimiter.getAndDecrement(); // Paper - split to seperate variable -@@ -410,6 +423,19 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -413,6 +426,19 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.lastGoodX = this.player.getX(); this.lastGoodY = this.player.getY(); this.lastGoodZ = this.player.getZ(); @@ -15092,7 +15171,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 } @Override -@@ -506,9 +532,10 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -509,9 +535,10 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // Paper end - fix large move vectors killing the server // CraftBukkit start - handle custom speeds and skipped ticks @@ -15105,7 +15184,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 ++this.receivedMovePacketCount; int i = this.receivedMovePacketCount - this.knownMovePacketCount; -@@ -583,7 +610,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -586,7 +613,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl Location curPos = this.getCraftPlayer().getLocation(); // Spigot entity.absMoveTo(d3, d4, d5, f, f1); @@ -15114,7 +15193,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 // Paper start - optimise out extra getCubes boolean teleportBack = flag2; // violating this is always a fail -@@ -596,11 +623,19 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -599,11 +626,19 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } if (teleportBack) { // Paper end - optimise out extra getCubes entity.absMoveTo(d0, d1, d2, f, f1); @@ -15135,7 +15214,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 // CraftBukkit start - fire PlayerMoveEvent Player player = this.getCraftPlayer(); // Spigot Start -@@ -646,7 +681,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -649,7 +684,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // If the event is cancelled we move the player back to their old location. if (event.isCancelled()) { @@ -15144,7 +15223,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 return; } -@@ -654,7 +689,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -657,7 +692,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // there to avoid any 'Moved wrongly' or 'Moved too quickly' errors. // We only do this if the Event was not cancelled. if (!oldTo.equals(event.getTo()) && !event.isCancelled()) { @@ -15153,7 +15232,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 return; } -@@ -771,13 +806,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -774,13 +809,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // Paper - run this async // CraftBukkit start if (this.chatSpamTickCount.addAndGet(io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.tabSpamIncrement) > io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.tabSpamLimit && !this.server.getPlayerList().isOp(this.player.getGameProfile())) { // Paper start - split and make configurable @@ -15169,7 +15248,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 return; } // Paper end -@@ -802,7 +837,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -805,7 +840,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (!event.isHandled()) { if (!event.isCancelled()) { @@ -15178,7 +15257,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 ParseResults parseresults = this.server.getCommands().getDispatcher().parse(stringreader, this.player.createCommandSourceStack()); this.server.getCommands().getDispatcher().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> { -@@ -818,7 +853,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -821,7 +856,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), suggestEvent.getSuggestions())); // Paper end - Brigadier API }); @@ -15187,7 +15266,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 } } else if (!completions.isEmpty()) { final com.mojang.brigadier.suggestion.SuggestionsBuilder builder0 = new com.mojang.brigadier.suggestion.SuggestionsBuilder(command, stringreader.getTotalLength()); -@@ -1130,7 +1165,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1135,7 +1170,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl int byteLength = testString.getBytes(java.nio.charset.StandardCharsets.UTF_8).length; if (byteLength > 256 * 4) { ServerGamePacketListenerImpl.LOGGER.warn(this.player.getScoreboardName() + " tried to send a book with with a page too large!"); @@ -15196,7 +15275,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 return; } byteTotal += byteLength; -@@ -1153,17 +1188,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1158,17 +1193,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (byteTotal > byteAllowed) { ServerGamePacketListenerImpl.LOGGER.warn(this.player.getScoreboardName() + " tried to send too large of a book. Book Size: " + byteTotal + " - Allowed: "+ byteAllowed + " - Pages: " + pageList.size()); @@ -15218,7 +15297,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 // CraftBukkit end int i = packet.getSlot(); -@@ -1183,7 +1218,19 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1188,7 +1223,19 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.updateBookContents(list1, i); }; @@ -15239,20 +15318,20 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 } } -@@ -1349,9 +1396,10 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - int i = this.receivedMovePacketCount - this.knownMovePacketCount; +@@ -1375,9 +1422,10 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + int i = this.receivedMovePacketCount - this.knownMovePacketCount; - // CraftBukkit start - handle custom speeds and skipped ticks -- this.allowedPlayerTicks += (System.currentTimeMillis() / 50) - this.lastTick; -+ int currTick = (int)(Util.getMillis() / 50); // Folia - region threading -+ this.allowedPlayerTicks += currTick - this.lastTick; // Folia - region threading - this.allowedPlayerTicks = Math.max(this.allowedPlayerTicks, 1); -- this.lastTick = (int) (System.currentTimeMillis() / 50); -+ this.lastTick = (int) currTick; // Folia - region threading + // CraftBukkit start - handle custom speeds and skipped ticks +- this.allowedPlayerTicks += (System.currentTimeMillis() / 50) - this.lastTick; ++ int currTick = (int)(Util.getMillis() / 50); // Folia - region threading ++ this.allowedPlayerTicks += currTick - this.lastTick; // Folia - region threading + this.allowedPlayerTicks = Math.max(this.allowedPlayerTicks, 1); +- this.lastTick = (int) (System.currentTimeMillis() / 50); ++ this.lastTick = (int) currTick; // Folia - region threading - if (i > Math.max(this.allowedPlayerTicks, 5)) { - ServerGamePacketListenerImpl.LOGGER.debug("{} is sending move packets too frequently ({} packets since last tick)", this.player.getName().getString(), i); -@@ -1537,7 +1585,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + if (i > Math.max(this.allowedPlayerTicks, 5)) { + ServerGamePacketListenerImpl.LOGGER.debug("{} is sending move packets too frequently ({} packets since last tick)", this.player.getName().getString(), i); +@@ -1564,7 +1612,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // If the event is cancelled we move the player back to their old location. if (event.isCancelled()) { @@ -15261,7 +15340,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 return; } -@@ -1545,7 +1593,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1572,7 +1620,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // there to avoid any 'Moved wrongly' or 'Moved too quickly' errors. // We only do this if the Event was not cancelled. if (!oldTo.equals(event.getTo()) && !event.isCancelled()) { @@ -15270,7 +15349,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 return; } -@@ -1778,9 +1826,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1805,9 +1853,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (!this.player.isSpectator()) { // limit how quickly items can be dropped // If the ticks aren't the same then the count starts from 0 and we update the lastDropTick. @@ -15282,7 +15361,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 } else { // Else we increment the drop count and check the amount. this.dropCount++; -@@ -1808,7 +1856,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1835,7 +1883,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl case ABORT_DESTROY_BLOCK: case STOP_DESTROY_BLOCK: // Paper start - Don't allow digging in unloaded chunks @@ -15291,7 +15370,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 this.player.connection.ackBlockChangesUpTo(packet.getSequence()); return; } -@@ -1892,7 +1940,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1919,7 +1967,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl BlockPos blockposition = movingobjectpositionblock.getBlockPos(); Vec3 vec3d1 = Vec3.atCenterOf(blockposition); @@ -15300,7 +15379,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 Vec3 vec3d2 = vec3d.subtract(vec3d1); double d0 = 1.0000001D; -@@ -2006,7 +2054,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2033,7 +2081,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl Entity entity = packet.getEntity(worldserver); if (entity != null) { @@ -15309,7 +15388,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 return; } } -@@ -2043,7 +2091,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2070,7 +2118,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } // CraftBukkit end ServerGamePacketListenerImpl.LOGGER.info("{} lost connection: {}", this.player.getName().getString(), reason.getString()); @@ -15318,7 +15397,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 super.onDisconnect(reason, quitMessage); // Paper } -@@ -2052,6 +2100,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2079,6 +2127,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.removePlayerFromWorld(null); } @@ -15327,7 +15406,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 private void removePlayerFromWorld(@Nullable net.kyori.adventure.text.Component quitMessage) { // Paper end this.chatMessageChain.close(); -@@ -2064,6 +2114,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2091,6 +2141,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.player.disconnect(); // Paper start - Adventure quitMessage = quitMessage == null ? this.server.getPlayerList().remove(this.player) : this.server.getPlayerList().remove(this.player, quitMessage); // Paper - pass in quitMessage to fix kick message not being used @@ -15336,29 +15415,25 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 if ((quitMessage != null) && !quitMessage.equals(net.kyori.adventure.text.Component.empty())) { this.server.getPlayerList().broadcastSystemMessage(PaperAdventure.asVanilla(quitMessage), false); // Paper end -@@ -2116,9 +2168,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2143,7 +2195,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } // CraftBukkit end if (ServerGamePacketListenerImpl.isChatMessageIllegal(packet.message())) { -- this.server.scheduleOnMain(() -> { // Paper - push to main for event firing + // Folia - region threading this.disconnect(Component.translatable("multiplayer.disconnect.illegal_characters"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_CHARACTERS); // Paper - add cause -- }); // Paper - push to main for event firing + // Folia - region threading } else { - Optional optional = this.tryHandleChat(packet.message(), packet.timeStamp(), packet.lastSeenMessages()); + Optional optional = this.tryHandleChat(packet.lastSeenMessages()); -@@ -2151,23 +2203,22 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2175,21 +2229,22 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void handleChatCommand(ServerboundChatCommandPacket packet) { if (ServerGamePacketListenerImpl.isChatMessageIllegal(packet.command())) { -- this.server.scheduleOnMain(() -> { // Paper - push to main for event firing + // Folia - region threading this.disconnect(Component.translatable("multiplayer.disconnect.illegal_characters"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_CHARACTERS); // Paper -- }); // Paper - push to main for event firing + // Folia - region threading } else { - Optional optional = this.tryHandleChat(packet.command(), packet.timeStamp(), packet.lastSeenMessages()); + Optional optional = this.tryHandleChat(packet.lastSeenMessages()); if (optional.isPresent()) { - this.server.submit(() -> { @@ -15376,19 +15451,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 } } -@@ -2241,9 +2292,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - private Optional tryHandleChat(String message, Instant timestamp, LastSeenMessages.Update acknowledgment) { - if (!this.updateChatOrder(timestamp)) { - ServerGamePacketListenerImpl.LOGGER.warn("{} sent out-of-order chat: '{}': {} > {}", this.player.getName().getString(), message, this.lastChatTimeStamp.get().getEpochSecond(), timestamp.getEpochSecond()); // Paper -- this.server.scheduleOnMain(() -> { // Paper - push to main -+ // Folia - region threading - this.disconnect(Component.translatable("multiplayer.disconnect.out_of_order_chat"), org.bukkit.event.player.PlayerKickEvent.Cause.OUT_OF_ORDER_CHAT); // Paper - kick event causes -- }); // Paper - push to main -+ // Folia - region threading - return Optional.empty(); - } else { - Optional optional = this.unpackAndApplyLastSeen(acknowledgment); -@@ -2318,7 +2369,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2320,7 +2375,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl String originalFormat = event.getFormat(), originalMessage = event.getMessage(); this.cserver.getPluginManager().callEvent(event); @@ -15397,7 +15460,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 // Evil plugins still listening to deprecated event final PlayerChatEvent queueEvent = new PlayerChatEvent(player, event.getMessage(), event.getFormat(), event.getRecipients()); queueEvent.setCancelled(event.isCancelled()); -@@ -2429,6 +2480,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2431,6 +2486,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (s.isEmpty()) { ServerGamePacketListenerImpl.LOGGER.warn(this.player.getScoreboardName() + " tried to send an empty message"); } else if (this.getCraftPlayer().isConversing()) { @@ -15405,7 +15468,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 final String conversationInput = s; this.server.processQueue.add(new Runnable() { @Override -@@ -2665,8 +2717,25 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2667,8 +2723,25 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // Spigot End public void switchToConfig() { @@ -15432,7 +15495,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 this.send(new ClientboundStartConfigurationPacket()); } -@@ -2691,7 +2760,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2693,7 +2766,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.player.resetLastActionTime(); this.player.setShiftKeyDown(packet.isUsingSecondaryAction()); @@ -15441,7 +15504,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 if (!worldserver.getWorldBorder().isWithinBounds(entity.blockPosition())) { return; } -@@ -2832,6 +2901,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2834,6 +2907,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl switch (packetplayinclientcommand_enumclientcommand) { case PERFORM_RESPAWN: if (this.player.wonGame) { @@ -15454,7 +15517,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 this.player.wonGame = false; this.player = this.server.getPlayerList().respawn(this.player, this.server.getLevel(this.player.getRespawnDimension()), true, null, true, RespawnReason.END_PORTAL, org.bukkit.event.player.PlayerRespawnEvent.RespawnFlag.END_PORTAL); // Paper - add isEndCreditsRespawn argument CriteriaTriggers.CHANGED_DIMENSION.trigger(this.player, Level.END, Level.OVERWORLD); -@@ -2840,6 +2915,18 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2842,6 +2921,18 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl return; } @@ -15473,7 +15536,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 this.player = this.server.getPlayerList().respawn(this.player, false, RespawnReason.DEATH); if (this.server.isHardcore()) { this.player.setGameMode(GameType.SPECTATOR, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.HARDCORE_DEATH, null); // Paper -@@ -3198,7 +3285,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3200,7 +3291,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // Paper start if (!org.bukkit.Bukkit.isPrimaryThread()) { if (this.recipeSpamPackets.addAndGet(io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.recipeSpamIncrement) > io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.recipeSpamLimit) { @@ -15482,7 +15545,7 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 return; } } -@@ -3367,7 +3454,18 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3369,7 +3460,18 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.filterTextPacket(list).thenAcceptAsync((list1) -> { this.updateSignText(packet, list1); @@ -15503,10 +15566,10 @@ index 65bb221993147a558995b36fb835f7b82e0eb4bd..159d3a27c1686fd2b0025cab5b7e7775 private void updateSignText(ServerboundSignUpdatePacket packet, List signText) { diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index 1c4f272219e68373eaae93fc5ea9af7d8f3fd6f9..6f483c6581daeaf68f85e3b730d31c5b7a6ae001 100644 +index 89b3184be952fd0803520dd0f717f3acfc3cb496..d0f7434164f6241ec81c990c7a127f504e019291 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -@@ -82,9 +82,13 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, +@@ -83,9 +83,13 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, } // Paper end if (this.state == ServerLoginPacketListenerImpl.State.VERIFYING) { @@ -15522,7 +15585,7 @@ index 1c4f272219e68373eaae93fc5ea9af7d8f3fd6f9..6f483c6581daeaf68f85e3b730d31c5b } if (this.state == ServerLoginPacketListenerImpl.State.WAITING_FOR_DUPE_DISCONNECT && !this.isPlayerAlreadyInWorld((GameProfile) Objects.requireNonNull(this.authenticatedProfile))) { -@@ -227,7 +231,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, +@@ -200,7 +204,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, })); } @@ -15531,7 +15594,7 @@ index 1c4f272219e68373eaae93fc5ea9af7d8f3fd6f9..6f483c6581daeaf68f85e3b730d31c5b if (flag) { this.state = ServerLoginPacketListenerImpl.State.WAITING_FOR_DUPE_DISCONNECT; -@@ -353,7 +357,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, +@@ -320,7 +324,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, uniqueId = gameprofile.getId(); // Paper end @@ -15593,10 +15656,10 @@ index 8b1da1fb5ca27432a39aff6dbc452b793268dab5..e83f3676d5a194fa8d3d1567edcb4b6f // Guess we don't have a date } diff --git a/src/main/java/net/minecraft/server/players/OldUsersConverter.java b/src/main/java/net/minecraft/server/players/OldUsersConverter.java -index ce43cb0152ba07c6c21e08142d65813d47c3b63b..8bdb1d10648965e2011b4a22a1dfc575d3bbe4e0 100644 +index c24898f8e81e8ab9a1f90bf4439ea6c6f42f0508..ce4f2239e99e94285186b46bdcd40f1dcdc3553e 100644 --- a/src/main/java/net/minecraft/server/players/OldUsersConverter.java +++ b/src/main/java/net/minecraft/server/players/OldUsersConverter.java -@@ -512,7 +512,7 @@ public class OldUsersConverter { +@@ -511,7 +511,7 @@ public class OldUsersConverter { Date date1; try { @@ -15606,10 +15669,10 @@ index ce43cb0152ba07c6c21e08142d65813d47c3b63b..8bdb1d10648965e2011b4a22a1dfc575 date1 = fallback; } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 33abcf12b4426572b74ca4c813e4392c823494bc..6cce2a9bc9beeeef25b7bacd2ad307ed3ae44432 100644 +index a35638a92479b90afa89cf201fc45b49c9e767f3..0fa69640a699e1c33cb307366b0335ac9bac4282 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -133,10 +133,10 @@ public abstract class PlayerList { +@@ -131,10 +131,10 @@ public abstract class PlayerList { public static final Component DUPLICATE_LOGIN_DISCONNECT_MESSAGE = Component.translatable("multiplayer.disconnect.duplicate_login"); private static final Logger LOGGER = LogUtils.getLogger(); private static final int SEND_PLAYER_INFO_INTERVAL = 600; @@ -15622,7 +15685,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..6cce2a9bc9beeeef25b7bacd2ad307ed private final UserBanList bans; private final IpBanList ipBans; private final ServerOpList ops; -@@ -157,9 +157,56 @@ public abstract class PlayerList { +@@ -155,9 +155,56 @@ public abstract class PlayerList { // CraftBukkit start private CraftServer cserver; @@ -15680,7 +15743,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..6cce2a9bc9beeeef25b7bacd2ad307ed public PlayerList(MinecraftServer server, LayeredRegistryAccess registryManager, PlayerDataStorage saveHandler, int maxPlayers) { this.cserver = server.server = new CraftServer((DedicatedServer) server, this); server.console = new com.destroystokyo.paper.console.TerminalConsoleCommandSender(); // Paper -@@ -180,7 +227,7 @@ public abstract class PlayerList { +@@ -178,7 +225,7 @@ public abstract class PlayerList { } abstract public void loadAndSaveFiles(); // Paper - moved from DedicatedPlayerList constructor @@ -15689,7 +15752,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..6cce2a9bc9beeeef25b7bacd2ad307ed player.isRealPlayer = true; // Paper player.loginTime = System.currentTimeMillis(); // Paper GameProfile gameprofile = player.getGameProfile(); -@@ -259,18 +306,42 @@ public abstract class PlayerList { +@@ -257,18 +304,42 @@ public abstract class PlayerList { player.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT; // set Player SpawnReason to DEFAULT on first login // Paper start - reset to main world spawn if first spawn or invalid world } @@ -15734,7 +15797,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..6cce2a9bc9beeeef25b7bacd2ad307ed Location loc = ev.getSpawnLocation(); worldserver1 = ((CraftWorld) loc.getWorld()).getHandle(); -@@ -289,6 +360,10 @@ public abstract class PlayerList { +@@ -287,6 +358,10 @@ public abstract class PlayerList { player.loadGameTypes(nbttagcompound); ServerGamePacketListenerImpl playerconnection = new ServerGamePacketListenerImpl(this.server, connection, player, clientData); @@ -15745,7 +15808,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..6cce2a9bc9beeeef25b7bacd2ad307ed GameRules gamerules = worldserver1.getGameRules(); boolean flag = gamerules.getBoolean(GameRules.RULE_DO_IMMEDIATE_RESPAWN); boolean flag1 = gamerules.getBoolean(GameRules.RULE_REDUCEDDEBUGINFO); -@@ -304,7 +379,7 @@ public abstract class PlayerList { +@@ -302,7 +377,7 @@ public abstract class PlayerList { this.sendPlayerPermissionLevel(player); player.getStats().markAllDirty(); player.getRecipeBook().sendInitialRecipeBook(player); @@ -15754,7 +15817,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..6cce2a9bc9beeeef25b7bacd2ad307ed this.server.invalidateStatus(); MutableComponent ichatmutablecomponent; -@@ -346,7 +421,7 @@ public abstract class PlayerList { +@@ -344,7 +419,7 @@ public abstract class PlayerList { this.cserver.getPluginManager().callEvent(playerJoinEvent); if (!player.connection.isAcceptingMessages()) { @@ -15763,7 +15826,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..6cce2a9bc9beeeef25b7bacd2ad307ed } final net.kyori.adventure.text.Component jm = playerJoinEvent.joinMessage(); -@@ -361,8 +436,7 @@ public abstract class PlayerList { +@@ -359,8 +434,7 @@ public abstract class PlayerList { ClientboundPlayerInfoUpdatePacket packet = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player)); // Paper final List onlinePlayers = Lists.newArrayListWithExpectedSize(this.players.size() - 1); // Paper - use single player info update packet @@ -15773,16 +15836,16 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..6cce2a9bc9beeeef25b7bacd2ad307ed if (entityplayer1.getBukkitEntity().canSee(bukkitPlayer)) { // Paper start -@@ -484,7 +558,7 @@ public abstract class PlayerList { +@@ -482,7 +556,7 @@ public abstract class PlayerList { // Paper start - Add to collideRule team if needed - final Scoreboard scoreboard = this.getServer().getLevel(Level.OVERWORLD).getScoreboard(); + final net.minecraft.world.scores.Scoreboard scoreboard = this.getServer().getLevel(Level.OVERWORLD).getScoreboard(); final PlayerTeam collideRuleTeam = scoreboard.getPlayerTeam(this.collideRuleTeamName); - if (this.collideRuleTeamName != null && collideRuleTeam != null && player.getTeam() == null) { + if (false && this.collideRuleTeamName != null && collideRuleTeam != null && player.getTeam() == null) { // Folia - region threading scoreboard.addPlayerToTeam(player.getScoreboardName(), collideRuleTeam); } // Paper end -@@ -579,7 +653,7 @@ public abstract class PlayerList { +@@ -577,7 +651,7 @@ public abstract class PlayerList { protected void save(ServerPlayer player) { if (!player.getBukkitEntity().isPersistent()) return; // CraftBukkit @@ -15791,16 +15854,16 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..6cce2a9bc9beeeef25b7bacd2ad307ed this.playerIo.save(player); ServerStatsCounter serverstatisticmanager = (ServerStatsCounter) player.getStats(); // CraftBukkit -@@ -619,7 +693,7 @@ public abstract class PlayerList { +@@ -617,7 +691,7 @@ public abstract class PlayerList { // CraftBukkit end // Paper start - Remove from collideRule team if needed - if (this.collideRuleTeamName != null) { + if (false && this.collideRuleTeamName != null) { // Folia - region threading - final Scoreboard scoreBoard = this.server.getLevel(Level.OVERWORLD).getScoreboard(); + final net.minecraft.world.scores.Scoreboard scoreBoard = this.server.getLevel(Level.OVERWORLD).getScoreboard(); final PlayerTeam team = scoreBoard.getPlayersTeam(this.collideRuleTeamName); if (entityplayer.getTeam() == team && team != null) { -@@ -659,7 +733,7 @@ public abstract class PlayerList { +@@ -657,7 +731,7 @@ public abstract class PlayerList { entityplayer.unRide(); worldserver.removePlayerImmediately(entityplayer, Entity.RemovalReason.UNLOADED_WITH_PLAYER); @@ -15809,7 +15872,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..6cce2a9bc9beeeef25b7bacd2ad307ed entityplayer.getAdvancements().stopListening(); this.players.remove(entityplayer); this.playersByName.remove(entityplayer.getScoreboardName().toLowerCase(java.util.Locale.ROOT)); // Spigot -@@ -678,8 +752,7 @@ public abstract class PlayerList { +@@ -676,8 +750,7 @@ public abstract class PlayerList { // CraftBukkit start // this.broadcastAll(new ClientboundPlayerInfoRemovePacket(List.of(entityplayer.getUUID()))); ClientboundPlayerInfoRemovePacket packet = new ClientboundPlayerInfoRemovePacket(List.of(entityplayer.getUUID())); @@ -15819,7 +15882,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..6cce2a9bc9beeeef25b7bacd2ad307ed if (entityplayer2.getBukkitEntity().canSee(entityplayer.getBukkitEntity())) { entityplayer2.connection.send(packet); -@@ -704,19 +777,13 @@ public abstract class PlayerList { +@@ -702,19 +775,13 @@ public abstract class PlayerList { ServerPlayer entityplayer; @@ -15841,7 +15904,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..6cce2a9bc9beeeef25b7bacd2ad307ed } // Instead of kicking then returning, we need to store the kick reason -@@ -735,7 +802,7 @@ public abstract class PlayerList { +@@ -733,7 +800,7 @@ public abstract class PlayerList { ichatmutablecomponent = Component.translatable("multiplayer.disconnect.banned.reason", gameprofilebanentry.getReason()); if (gameprofilebanentry.getExpires() != null) { @@ -15850,7 +15913,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..6cce2a9bc9beeeef25b7bacd2ad307ed } // return chatmessage; -@@ -748,14 +815,14 @@ public abstract class PlayerList { +@@ -746,14 +813,14 @@ public abstract class PlayerList { ichatmutablecomponent = Component.translatable("multiplayer.disconnect.banned_ip.reason", ipbanentry.getReason()); if (ipbanentry.getExpires() != null) { @@ -15867,7 +15930,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..6cce2a9bc9beeeef25b7bacd2ad307ed event.disallow(PlayerLoginEvent.Result.KICK_FULL, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.serverFullMessage)); // Spigot // Paper - Adventure } } -@@ -821,6 +888,11 @@ public abstract class PlayerList { +@@ -819,6 +886,11 @@ public abstract class PlayerList { public ServerPlayer respawn(ServerPlayer entityplayer, ServerLevel worldserver, boolean flag, Location location, boolean avoidSuffocation, RespawnReason reason, org.bukkit.event.player.PlayerRespawnEvent.RespawnFlag...respawnFlags) { // Paper end @@ -15879,7 +15942,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..6cce2a9bc9beeeef25b7bacd2ad307ed entityplayer.stopRiding(); // CraftBukkit this.players.remove(entityplayer); this.playersByName.remove(entityplayer.getScoreboardName().toLowerCase(java.util.Locale.ROOT)); // Spigot -@@ -1014,10 +1086,10 @@ public abstract class PlayerList { +@@ -1012,10 +1084,10 @@ public abstract class PlayerList { public void tick() { if (++this.sendAllPlayerInfoIn > 600) { // CraftBukkit start @@ -15893,7 +15956,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..6cce2a9bc9beeeef25b7bacd2ad307ed @Override public boolean test(ServerPlayer input) { return target.getBukkitEntity().canSee(input.getBukkitEntity()); -@@ -1043,18 +1115,17 @@ public abstract class PlayerList { +@@ -1041,18 +1113,17 @@ public abstract class PlayerList { // CraftBukkit start - add a world/entity limited version public void broadcastAll(Packet packet, net.minecraft.world.entity.player.Player entityhuman) { @@ -15916,17 +15979,17 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..6cce2a9bc9beeeef25b7bacd2ad307ed } } -@@ -1098,8 +1169,7 @@ public abstract class PlayerList { - if (scoreboardteambase == null) { +@@ -1096,8 +1167,7 @@ public abstract class PlayerList { + if (scoreboardteam == null) { this.broadcastSystemMessage(message, false); } else { - for (int i = 0; i < this.players.size(); ++i) { - ServerPlayer entityplayer = (ServerPlayer) this.players.get(i); + for (ServerPlayer entityplayer : this.players) { // Folia - region threading - if (entityplayer.getTeam() != scoreboardteambase) { + if (entityplayer.getTeam() != scoreboardteam) { entityplayer.sendSystemMessage(message); -@@ -1110,10 +1180,12 @@ public abstract class PlayerList { +@@ -1108,10 +1178,12 @@ public abstract class PlayerList { } public String[] getPlayerNamesArray() { @@ -15942,7 +16005,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..6cce2a9bc9beeeef25b7bacd2ad307ed } return astring; -@@ -1132,7 +1204,9 @@ public abstract class PlayerList { +@@ -1130,7 +1202,9 @@ public abstract class PlayerList { ServerPlayer entityplayer = this.getPlayer(profile.getId()); if (entityplayer != null) { @@ -15952,7 +16015,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..6cce2a9bc9beeeef25b7bacd2ad307ed } } -@@ -1142,7 +1216,10 @@ public abstract class PlayerList { +@@ -1140,7 +1214,10 @@ public abstract class PlayerList { ServerPlayer entityplayer = this.getPlayer(profile.getId()); if (entityplayer != null) { @@ -15963,7 +16026,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..6cce2a9bc9beeeef25b7bacd2ad307ed } } -@@ -1203,8 +1280,7 @@ public abstract class PlayerList { +@@ -1201,8 +1278,7 @@ public abstract class PlayerList { } public void broadcast(@Nullable net.minecraft.world.entity.player.Player player, double x, double y, double z, double distance, ResourceKey worldKey, Packet packet) { @@ -15973,7 +16036,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..6cce2a9bc9beeeef25b7bacd2ad307ed // CraftBukkit start - Test if player receiving packet can see the source of the packet if (player != null && !entityplayer.getBukkitEntity().canSee(player.getBukkitEntity())) { -@@ -1234,12 +1310,21 @@ public abstract class PlayerList { +@@ -1232,12 +1308,21 @@ public abstract class PlayerList { io.papermc.paper.util.MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main MinecraftTimings.savePlayers.startTiming(); // Paper int numSaved = 0; @@ -16027,14 +16090,14 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..6cce2a9bc9beeeef25b7bacd2ad307ed // Paper start - Remove collideRule team if it exists - if (this.collideRuleTeamName != null) { + if (false && this.collideRuleTeamName != null) { // Folia - region threading - final Scoreboard scoreboard = this.getServer().getLevel(Level.OVERWORLD).getScoreboard(); + final net.minecraft.world.scores.Scoreboard scoreboard = this.getServer().getLevel(Level.OVERWORLD).getScoreboard(); final PlayerTeam team = scoreboard.getPlayersTeam(this.collideRuleTeamName); if (team != null) scoreboard.removePlayerTeam(team); diff --git a/src/main/java/net/minecraft/server/players/StoredUserList.java b/src/main/java/net/minecraft/server/players/StoredUserList.java -index 09fc086548b9d0f97849f56f41e3a5be87f5091a..4dfb52f7fde8603b9fc236ea57e9b768a9d04fc6 100644 +index 665120a62525f56912263a3e1b6f12f6c3e15dec..d37315eba7c1db671136e913d6c1d73a6995fc8e 100644 --- a/src/main/java/net/minecraft/server/players/StoredUserList.java +++ b/src/main/java/net/minecraft/server/players/StoredUserList.java -@@ -143,6 +143,7 @@ public abstract class StoredUserList> { +@@ -126,6 +126,7 @@ public abstract class StoredUserList> { } public void save() throws IOException { @@ -16042,7 +16105,7 @@ index 09fc086548b9d0f97849f56f41e3a5be87f5091a..4dfb52f7fde8603b9fc236ea57e9b768 this.removeExpired(); // Paper - remove expired values before saving JsonArray jsonarray = new JsonArray(); Stream stream = this.map.values().stream().map((jsonlistentry) -> { // CraftBukkit - decompile error -@@ -173,10 +174,12 @@ public abstract class StoredUserList> { +@@ -156,10 +157,12 @@ public abstract class StoredUserList> { if (bufferedwriter != null) { bufferedwriter.close(); } @@ -16055,7 +16118,7 @@ index 09fc086548b9d0f97849f56f41e3a5be87f5091a..4dfb52f7fde8603b9fc236ea57e9b768 if (this.file.exists()) { BufferedReader bufferedreader = Files.newReader(this.file, StandardCharsets.UTF_8); -@@ -233,5 +236,6 @@ public abstract class StoredUserList> { +@@ -216,5 +219,6 @@ public abstract class StoredUserList> { } } @@ -16270,10 +16333,10 @@ index ea27b46eec01bda427653335f922ccd068cffcb5..e551d3b875eab6851b75041f418c9a08 return blockToFallLocation(blockState); } else { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index c655c6fee393c62ba79301f76baa72f9b1154a9a..dd18591d7928ab04f6f7c09aa89a26ccbe20c323 100644 +index 9abe817ae202edaa2d88cd59ae5c7db0b1c634be..9f38cec134dfd476d0a8d56b628238d2d27baf83 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -166,7 +166,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -167,7 +167,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S // Paper start public static RandomSource SHARED_RANDOM = new RandomRandomSource(); @@ -16282,7 +16345,7 @@ index c655c6fee393c62ba79301f76baa72f9b1154a9a..dd18591d7928ab04f6f7c09aa89a26cc private boolean locked = false; @Override -@@ -240,7 +240,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -241,7 +241,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S public com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData; // Paper public boolean collisionLoadChunks = false; // Paper @@ -16291,7 +16354,7 @@ index c655c6fee393c62ba79301f76baa72f9b1154a9a..dd18591d7928ab04f6f7c09aa89a26cc public @org.jetbrains.annotations.Nullable net.minecraft.server.level.ChunkMap.TrackedEntity tracker; // Paper public @Nullable Throwable addedToWorldStack; // Paper - entity debug -@@ -531,6 +531,25 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -536,6 +536,25 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S this.teleportTo(worldserver, null); } // Paper end - make end portalling safe @@ -16317,7 +16380,7 @@ index c655c6fee393c62ba79301f76baa72f9b1154a9a..dd18591d7928ab04f6f7c09aa89a26cc public boolean isLegacyTrackingEntity = false; -@@ -538,28 +557,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -543,28 +562,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S this.isLegacyTrackingEntity = isLegacyTrackingEntity; } @@ -16347,7 +16410,7 @@ index c655c6fee393c62ba79301f76baa72f9b1154a9a..dd18591d7928ab04f6f7c09aa89a26cc // Paper end - optimise entity tracking public Entity(EntityType type, Level world) { -@@ -803,6 +801,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -808,6 +806,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S // CraftBukkit start public void postTick() { @@ -16360,7 +16423,7 @@ index c655c6fee393c62ba79301f76baa72f9b1154a9a..dd18591d7928ab04f6f7c09aa89a26cc // No clean way to break out of ticking once the entity has been copied to a new world, so instead we move the portalling later in the tick cycle if (!(this instanceof ServerPlayer) && this.isAlive()) { // Paper - don't attempt to teleport dead entities this.handleNetherPortal(); -@@ -825,7 +829,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -830,7 +834,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S this.walkDistO = this.walkDist; this.xRotO = this.getXRot(); this.yRotO = this.getYRot(); @@ -16369,7 +16432,7 @@ index c655c6fee393c62ba79301f76baa72f9b1154a9a..dd18591d7928ab04f6f7c09aa89a26cc if (this.canSpawnSprintParticle()) { this.spawnSprintParticle(); } -@@ -934,11 +938,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -939,11 +943,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S // This will be called every single tick the entity is in lava, so don't throw an event this.setSecondsOnFire(15, false); } @@ -16383,7 +16446,7 @@ index c655c6fee393c62ba79301f76baa72f9b1154a9a..dd18591d7928ab04f6f7c09aa89a26cc // CraftBukkit end - we also don't throw an event unless the object in lava is living, to save on some event calls } -@@ -1083,8 +1087,8 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -1088,8 +1092,8 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S } else { this.wasOnFire = this.isOnFire(); if (movementType == MoverType.PISTON) { @@ -16394,7 +16457,7 @@ index c655c6fee393c62ba79301f76baa72f9b1154a9a..dd18591d7928ab04f6f7c09aa89a26cc movement = this.limitPistonMovement(movement); if (movement.equals(Vec3.ZERO)) { return; -@@ -2946,7 +2950,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3001,7 +3005,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S this.passengers = ImmutableList.copyOf(list); } @@ -16403,7 +16466,7 @@ index c655c6fee393c62ba79301f76baa72f9b1154a9a..dd18591d7928ab04f6f7c09aa89a26cc } } -@@ -2995,7 +2999,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3050,7 +3054,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S } entity.boardingCooldown = 60; @@ -16412,10 +16475,10 @@ index c655c6fee393c62ba79301f76baa72f9b1154a9a..dd18591d7928ab04f6f7c09aa89a26cc } return true; // CraftBukkit } -@@ -3275,6 +3279,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3330,6 +3334,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S @Nullable - public Team getTeam() { + public PlayerTeam getTeam() { + // Folia start - region threading + if (true) { + return null; @@ -16424,7 +16487,7 @@ index c655c6fee393c62ba79301f76baa72f9b1154a9a..dd18591d7928ab04f6f7c09aa89a26cc if (!this.level().paperConfig().scoreboards.allowNonPlayerEntitiesOnScoreboards && !(this instanceof Player)) { return null; } // Paper return this.level().getScoreboard().getPlayersTeam(this.getScoreboardName()); } -@@ -3390,9 +3399,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3445,9 +3454,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S if (this.fireImmune()) { return; } @@ -16436,7 +16499,7 @@ index c655c6fee393c62ba79301f76baa72f9b1154a9a..dd18591d7928ab04f6f7c09aa89a26cc return; } // CraftBukkit end -@@ -3565,6 +3574,775 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3620,6 +3629,775 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S this.portalEntrancePos = original.portalEntrancePos; } @@ -17212,7 +17275,7 @@ index c655c6fee393c62ba79301f76baa72f9b1154a9a..dd18591d7928ab04f6f7c09aa89a26cc @Nullable public Entity changeDimension(ServerLevel destination) { // CraftBukkit start -@@ -3573,6 +4351,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3628,6 +4406,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S @Nullable public Entity teleportTo(ServerLevel worldserver, Vec3 location) { @@ -17224,7 +17287,7 @@ index c655c6fee393c62ba79301f76baa72f9b1154a9a..dd18591d7928ab04f6f7c09aa89a26cc // CraftBukkit end // Paper start - fix bad state entities causing dupes if (!this.isAlive() || !this.valid) { -@@ -3661,6 +4444,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3720,6 +4503,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S } } @@ -17237,7 +17300,7 @@ index c655c6fee393c62ba79301f76baa72f9b1154a9a..dd18591d7928ab04f6f7c09aa89a26cc protected void removeAfterChangingDimensions() { this.setRemoved(Entity.RemovalReason.CHANGED_DIMENSION); } -@@ -4589,7 +5378,8 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -4657,7 +5446,8 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S } } // Paper end - fix MC-4 @@ -17247,7 +17310,7 @@ index c655c6fee393c62ba79301f76baa72f9b1154a9a..dd18591d7928ab04f6f7c09aa89a26cc synchronized (this.posLock) { // Paper this.position = new Vec3(x, y, z); } // Paper -@@ -4610,7 +5400,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -4678,7 +5468,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S // Paper start - never allow AABB to become desynced from position // hanging has its own special logic @@ -17256,7 +17319,7 @@ index c655c6fee393c62ba79301f76baa72f9b1154a9a..dd18591d7928ab04f6f7c09aa89a26cc this.setBoundingBox(this.makeBoundingBox()); } // Paper end -@@ -4697,6 +5487,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -4765,6 +5555,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S return this.removalReason != null; } @@ -17269,7 +17332,7 @@ index c655c6fee393c62ba79301f76baa72f9b1154a9a..dd18591d7928ab04f6f7c09aa89a26cc @Nullable public Entity.RemovalReason getRemovalReason() { return this.removalReason; -@@ -4712,6 +5508,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -4780,6 +5576,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S } // Paper end - rewrite chunk system final boolean alreadyRemoved = this.removalReason != null; @@ -17279,7 +17342,7 @@ index c655c6fee393c62ba79301f76baa72f9b1154a9a..dd18591d7928ab04f6f7c09aa89a26cc if (this.removalReason == null) { this.removalReason = reason; } -@@ -4734,6 +5533,10 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -4802,6 +5601,10 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S this.removalReason = null; } @@ -17291,10 +17354,10 @@ index c655c6fee393c62ba79301f76baa72f9b1154a9a..dd18591d7928ab04f6f7c09aa89a26cc /** * Invoked only when the entity is truly removed from the server, never to be added to any world. diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index a76eb3d051db0229ed088b71c92ff3f131449007..db4f220bc9767ced5a98addc9e8b440b4f4f5b03 100644 +index 45b1a182acf6b2aef40b714d31ca125d8f74619a..d74c6ee198daa125d78cd815e1e0d1f7194caeac 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -276,6 +276,13 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -275,6 +275,13 @@ public abstract class LivingEntity extends Entity implements Attackable { ++this.noActionTime; // Above all the floats } // Spigot end @@ -17308,7 +17371,7 @@ index a76eb3d051db0229ed088b71c92ff3f131449007..db4f220bc9767ced5a98addc9e8b440b protected LivingEntity(EntityType type, Level world) { super(type, world); -@@ -481,7 +488,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -480,7 +487,7 @@ public abstract class LivingEntity extends Entity implements Attackable { if (this.isDeadOrDying() && this.level().shouldTickDeath(this)) { this.tickDeath(); @@ -17317,7 +17380,7 @@ index a76eb3d051db0229ed088b71c92ff3f131449007..db4f220bc9767ced5a98addc9e8b440b if (this.lastHurtByPlayerTime > 0) { --this.lastHurtByPlayerTime; -@@ -627,11 +634,14 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -626,11 +633,14 @@ public abstract class LivingEntity extends Entity implements Attackable { return true; } @@ -17334,7 +17397,7 @@ index a76eb3d051db0229ed088b71c92ff3f131449007..db4f220bc9767ced5a98addc9e8b440b } } -@@ -852,9 +862,9 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -851,9 +861,9 @@ public abstract class LivingEntity extends Entity implements Attackable { } this.hurtTime = nbt.getShort("HurtTime"); @@ -17346,16 +17409,15 @@ index a76eb3d051db0229ed088b71c92ff3f131449007..db4f220bc9767ced5a98addc9e8b440b String s = nbt.getString("Team"); PlayerTeam scoreboardteam = this.level().getScoreboard().getPlayerTeam(s); if (!this.level().paperConfig().scoreboards.allowNonPlayerEntitiesOnScoreboards && !(this instanceof net.minecraft.world.entity.player.Player)) { scoreboardteam = null; } // Paper -@@ -1134,7 +1144,7 @@ public abstract class LivingEntity extends Entity implements Attackable { - } - - public boolean addEffect(MobEffectInstance mobeffect, @Nullable Entity entity, EntityPotionEffectEvent.Cause cause) { -- // org.spigotmc.AsyncCatcher.catchOp("effect add"); // Spigot // Paper - move to API +@@ -1139,6 +1149,7 @@ public abstract class LivingEntity extends Entity implements Attackable { + public boolean addEffect(MobEffectInstance mobeffect, @Nullable Entity entity, EntityPotionEffectEvent.Cause cause, boolean fireEvent) { + // Paper end + // org.spigotmc.AsyncCatcher.catchOp("effect add"); // Spigot // Paper - move to API + if (!this.hasNullCallback()) io.papermc.paper.util.TickThread.ensureTickThread(this, "Cannot add effects to entities asynchronously"); // Folia - region threading if (this.isTickingEffects) { this.effectsToProcess.add(new ProcessableEffect(mobeffect, cause)); return true; -@@ -2331,7 +2341,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2336,7 +2347,7 @@ public abstract class LivingEntity extends Entity implements Attackable { @Nullable public LivingEntity getKillCredit() { @@ -17364,7 +17426,7 @@ index a76eb3d051db0229ed088b71c92ff3f131449007..db4f220bc9767ced5a98addc9e8b440b } public final float getMaxHealth() { -@@ -3469,7 +3479,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3479,7 +3490,7 @@ public abstract class LivingEntity extends Entity implements Attackable { this.pushEntities(); this.level().getProfiler().pop(); // Paper start @@ -17373,7 +17435,7 @@ index a76eb3d051db0229ed088b71c92ff3f131449007..db4f220bc9767ced5a98addc9e8b440b if (this.xo != this.getX() || this.yo != this.getY() || this.zo != this.getZ() || this.yRotO != this.getYRot() || this.xRotO != this.getXRot()) { Location from = new Location(this.level().getWorld(), this.xo, this.yo, this.zo, this.yRotO, this.xRotO); Location to = new Location (this.level().getWorld(), this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot()); -@@ -4163,7 +4173,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4173,7 +4184,7 @@ public abstract class LivingEntity extends Entity implements Attackable { BlockPos blockposition = BlockPos.containing(d0, d1, d2); Level world = this.level(); @@ -17383,10 +17445,10 @@ index a76eb3d051db0229ed088b71c92ff3f131449007..db4f220bc9767ced5a98addc9e8b440b while (!flag2 && blockposition.getY() > world.getMinBuildHeight()) { diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index 956d05e2ae59978ea9623ca0e167c0afe0b87306..4e9d510646abbc2d2b6f2d935f7416b6872eb234 100644 +index 5af48151159135b869ec4753bbcf79dd257c1570..51628bf76f80c6ad9d7feb127377f004adce9669 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java -@@ -136,6 +136,14 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -137,6 +137,14 @@ public abstract class Mob extends LivingEntity implements Targeting { public boolean aware = true; // CraftBukkit @@ -17401,7 +17463,7 @@ index 956d05e2ae59978ea9623ca0e167c0afe0b87306..4e9d510646abbc2d2b6f2d935f7416b6 protected Mob(EntityType type, Level world) { super(type, world); this.handItems = NonNullList.withSize(2, ItemStack.EMPTY); -@@ -287,9 +295,21 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -288,9 +296,21 @@ public abstract class Mob extends LivingEntity implements Targeting { @Nullable @Override public LivingEntity getTarget() { @@ -17423,7 +17485,7 @@ index 956d05e2ae59978ea9623ca0e167c0afe0b87306..4e9d510646abbc2d2b6f2d935f7416b6 public org.bukkit.craftbukkit.entity.CraftMob getBukkitMob() { return (org.bukkit.craftbukkit.entity.CraftMob) super.getBukkitEntity(); } // Paper public void setTarget(@Nullable LivingEntity target) { // CraftBukkit start - fire event -@@ -297,7 +317,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -298,7 +318,7 @@ public abstract class Mob extends LivingEntity implements Targeting { } public boolean setTarget(LivingEntity entityliving, EntityTargetEvent.TargetReason reason, boolean fireEvent) { @@ -17432,7 +17494,7 @@ index 956d05e2ae59978ea9623ca0e167c0afe0b87306..4e9d510646abbc2d2b6f2d935f7416b6 if (fireEvent) { if (reason == EntityTargetEvent.TargetReason.UNKNOWN && this.getTarget() != null && entityliving == null) { reason = this.getTarget().isAlive() ? EntityTargetEvent.TargetReason.FORGOT_TARGET : EntityTargetEvent.TargetReason.TARGET_DIED; -@@ -907,7 +927,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -908,7 +928,7 @@ public abstract class Mob extends LivingEntity implements Targeting { this.level().getProfiler().push("sensing"); this.sensing.tick(); this.level().getProfiler().pop(); @@ -17441,7 +17503,7 @@ index 956d05e2ae59978ea9623ca0e167c0afe0b87306..4e9d510646abbc2d2b6f2d935f7416b6 if (i % 2 != 0 && this.tickCount > 1) { this.level().getProfiler().push("targetSelector"); -@@ -1744,6 +1764,15 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -1746,6 +1766,15 @@ public abstract class Mob extends LivingEntity implements Targeting { this.goalSelector.removeAllGoals(predicate); } @@ -17457,7 +17519,7 @@ index 956d05e2ae59978ea9623ca0e167c0afe0b87306..4e9d510646abbc2d2b6f2d935f7416b6 @Override protected void removeAfterChangingDimensions() { super.removeAfterChangingDimensions(); -@@ -1752,12 +1781,7 @@ public abstract class Mob extends LivingEntity implements Targeting { +@@ -1754,12 +1783,7 @@ public abstract class Mob extends LivingEntity implements Targeting { this.level().getCraftServer().getPluginManager().callEvent(event); // CraftBukkit this.dropLeash(true, event.isDropLeash()); // Paper end @@ -17818,10 +17880,10 @@ index 12a7aaeaa8b4b788b620b1985591c3b93253ccd5..5150d447c9dc2f539446749c8bee1020 @Override diff --git a/src/main/java/net/minecraft/world/entity/animal/Bee.java b/src/main/java/net/minecraft/world/entity/animal/Bee.java -index 9a7956befc346e1b58f064213800fd099a052fc6..25fd3aea2d66503018637781ccb8b5690c02e57b 100644 +index a87a34b0c4c8e5d0cf079025c230b1434c919b54..cbb0ebf003f5d832be1937aa886802df3f06b12a 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Bee.java +++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java -@@ -1036,6 +1036,11 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -1043,6 +1043,11 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { @Override public boolean canBeeUse() { @@ -17833,7 +17895,7 @@ index 9a7956befc346e1b58f064213800fd099a052fc6..25fd3aea2d66503018637781ccb8b569 return Bee.this.hivePos != null && !Bee.this.hasRestriction() && Bee.this.wantsToEnterHive() && !this.hasReachedTarget(Bee.this.hivePos) && Bee.this.level().getBlockState(Bee.this.hivePos).is(BlockTags.BEEHIVES); } -@@ -1152,6 +1157,11 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -1159,6 +1164,11 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { @Override public boolean canBeeUse() { @@ -17859,10 +17921,10 @@ index de51ce9875e12961e6e549e87d76f492d2f19787..8c9470bc0dd2d1a5bfbdc4921f4063bd this.setPersistenceRequired(); } diff --git a/src/main/java/net/minecraft/world/entity/animal/Turtle.java b/src/main/java/net/minecraft/world/entity/animal/Turtle.java -index 490472bb618e9ac07da5883a71dff8920525b1e2..28b4be002978f26a3ff9901e9d3dbe860a7d7665 100644 +index d8056421249c8e75e96a55ec07dce84d2bba9c5c..68e8e82f4c3406b1ed5c079e68806f893e5f3e5e 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Turtle.java +++ b/src/main/java/net/minecraft/world/entity/animal/Turtle.java -@@ -341,9 +341,9 @@ public class Turtle extends Animal { +@@ -336,9 +336,9 @@ public class Turtle extends Animal { @Override public void thunderHit(ServerLevel world, LightningBolt lightning) { @@ -17875,10 +17937,10 @@ index 490472bb618e9ac07da5883a71dff8920525b1e2..28b4be002978f26a3ff9901e9d3dbe86 @Override diff --git a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java -index 759ecd79534a7706f7d4a63eb9dacbefcfe54674..0344b1f77f23274c2932b5dce01b0ea6887078cf 100644 +index 69912c5b300b67394dce3876d2d96872033cf156..19e8b2d13c627281be3b66ecc56194b3fbc9a39d 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java -@@ -303,8 +303,10 @@ public class ItemFrame extends HangingEntity { +@@ -298,8 +298,10 @@ public class ItemFrame extends HangingEntity { MapItemSavedData worldmap = MapItem.getSavedData(i, this.level()); if (worldmap != null) { @@ -17890,7 +17952,7 @@ index 759ecd79534a7706f7d4a63eb9dacbefcfe54674..0344b1f77f23274c2932b5dce01b0ea6 }); diff --git a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java -index e6f75a9cac46c8e3ddba664a9d5b27b665a94cb4..8e348099d6b3eb4510405d76453d70e7cadeebf6 100644 +index 45c07733f03b5c11f6d8e820f65dc950c70d9a67..acf2bfe7421774c1a8d8ac1a23b34880df6cab6a 100644 --- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java @@ -295,9 +295,9 @@ public class FallingBlockEntity extends Entity { @@ -17906,10 +17968,10 @@ index e6f75a9cac46c8e3ddba664a9d5b27b665a94cb4..8e348099d6b3eb4510405d76453d70e7 boolean flag = this.blockState.is(BlockTags.ANVIL); diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -index eb0351aa12eebcefab1d1d14641fc3c60cbbcab8..ff4d2676a0833977dd8406d49dc0b5035c468b2d 100644 +index a39db702063887cf530f272deaf4f334047cc7d4..f640dca8837496f9603d6d3115dd1d935bd692fd 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -@@ -52,7 +52,7 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -54,7 +54,7 @@ public class ItemEntity extends Entity implements TraceableEntity { @Nullable public UUID target; public final float bobOffs; @@ -17918,7 +17980,7 @@ index eb0351aa12eebcefab1d1d14641fc3c60cbbcab8..ff4d2676a0833977dd8406d49dc0b503 public boolean canMobPickup = true; // Paper private int despawnRate = -1; // Paper public net.kyori.adventure.util.TriState frictionState = net.kyori.adventure.util.TriState.NOT_SET; // Paper -@@ -126,13 +126,11 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -144,13 +144,11 @@ public class ItemEntity extends Entity implements TraceableEntity { this.discard(); } else { super.tick(); @@ -17937,7 +17999,7 @@ index eb0351aa12eebcefab1d1d14641fc3c60cbbcab8..ff4d2676a0833977dd8406d49dc0b503 this.xo = this.getX(); this.yo = this.getY(); -@@ -186,11 +184,11 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -204,11 +202,11 @@ public class ItemEntity extends Entity implements TraceableEntity { this.mergeWithNeighbours(); } @@ -17951,7 +18013,7 @@ index eb0351aa12eebcefab1d1d14641fc3c60cbbcab8..ff4d2676a0833977dd8406d49dc0b503 this.hasImpulse |= this.updateInWaterStateAndDoFluidPushing(); if (!this.level().isClientSide) { -@@ -217,13 +215,14 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -235,13 +233,14 @@ public class ItemEntity extends Entity implements TraceableEntity { // Spigot start - copied from above @Override public void inactiveTick() { @@ -17973,7 +18035,7 @@ index eb0351aa12eebcefab1d1d14641fc3c60cbbcab8..ff4d2676a0833977dd8406d49dc0b503 if (!this.level().isClientSide && this.age >= this.despawnRate) { // Spigot // Paper // CraftBukkit start - fire ItemDespawnEvent -@@ -529,14 +528,20 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -548,14 +547,20 @@ public class ItemEntity extends Entity implements TraceableEntity { return false; } @@ -17998,10 +18060,10 @@ index eb0351aa12eebcefab1d1d14641fc3c60cbbcab8..ff4d2676a0833977dd8406d49dc0b503 return entity; } diff --git a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java -index 4ce3e69970dd9eb251d0538a2d233ca30e9e5e47..acb7545a3346758c7a598b104ea7ae43ce4263d2 100644 +index c3e47426382296d650fa00ce0bc1a82bf23c7877..3163a74e8225a64d763e5a8f0787240280a5116c 100644 --- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java +++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java -@@ -63,7 +63,7 @@ public class PrimedTnt extends Entity implements TraceableEntity { +@@ -71,7 +71,7 @@ public class PrimedTnt extends Entity implements TraceableEntity { @Override public void tick() { @@ -18010,7 +18072,7 @@ index 4ce3e69970dd9eb251d0538a2d233ca30e9e5e47..acb7545a3346758c7a598b104ea7ae43 if (!this.isNoGravity()) { this.setDeltaMovement(this.getDeltaMovement().add(0.0D, -0.04D, 0.0D)); } -@@ -105,7 +105,7 @@ public class PrimedTnt extends Entity implements TraceableEntity { +@@ -113,7 +113,7 @@ public class PrimedTnt extends Entity implements TraceableEntity { */ // Send position and velocity updates to nearby players on every tick while the TNT is in water. // This does pretty well at keeping their clients in sync with the server. @@ -18020,10 +18082,10 @@ index 4ce3e69970dd9eb251d0538a2d233ca30e9e5e47..acb7545a3346758c7a598b104ea7ae43 net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket velocityPacket = new net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket(this); net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket positionPacket = new net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket(this); diff --git a/src/main/java/net/minecraft/world/entity/monster/Vex.java b/src/main/java/net/minecraft/world/entity/monster/Vex.java -index 90e577b1a89b02c38daff2845a63dafe5ed929e1..150fb1fc4d70330a4c56ff5847792a1eb84af633 100644 +index 30ea3f64234fd1fda8dada3c7fb12be0730322a8..395c7763db5f748911639336e3274d4cb16d66f8 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Vex.java +++ b/src/main/java/net/minecraft/world/entity/monster/Vex.java -@@ -359,7 +359,7 @@ public class Vex extends Monster implements TraceableEntity { +@@ -370,7 +370,7 @@ public class Vex extends Monster implements TraceableEntity { public void tick() { BlockPos blockposition = Vex.this.getBoundOrigin(); @@ -18033,7 +18095,7 @@ index 90e577b1a89b02c38daff2845a63dafe5ed929e1..150fb1fc4d70330a4c56ff5847792a1e } diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java -index 5fdad1600cc7a7c22d1d9a58b6b2dda605521b97..e2b9a18fd4a573aa2b3299a2e19afc07cc747366 100644 +index 753defa8f8b48d004a2a53b2fc322fd9c083d95e..07025fb304b5ac3ae7c4362fe61560d22caabf1b 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java +++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java @@ -95,7 +95,7 @@ public class Zombie extends Monster { @@ -18162,7 +18224,7 @@ index 5f407535298a31a34cfe114dd863fd6a9b977707..cb0f75fb32836efa50f0a86dfae7907b return 0; } else { diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java -index cbe2a37f74f4fb2abd0b3297699e54335aaed64f..4e9ccc518f37755e86687653f7724240db754682 100644 +index 11935e5b16324af572b07c5b173708f5a91f8289..c8de034a2bf4654bad9a6e8a9aa831b2f90fad14 100644 --- a/src/main/java/net/minecraft/world/entity/npc/Villager.java +++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java @@ -203,7 +203,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler @@ -18285,10 +18347,10 @@ index 8385eb1d60f377da94e3178ab506feefb43563fd..2f57e5025d0a0e720f49da1e5231a7d9 entityvillagertrader.setWanderTarget(blockposition1); entityvillagertrader.restrictTo(blockposition1, 16); diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java -index 481c3e321cfc0f20bb1c4c6942b8bdbd23c06339..51c31ac3d54996a6e2d870d8215546fdcf5ee506 100644 +index 7f3466340891b4409d1399ebeb2ca865d77841cd..4269226b2bea166599934a25d70376f905f33db6 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java -@@ -1508,6 +1508,14 @@ public abstract class Player extends LivingEntity { +@@ -1503,6 +1503,14 @@ public abstract class Player extends LivingEntity { } @@ -18304,10 +18366,10 @@ index 481c3e321cfc0f20bb1c4c6942b8bdbd23c06339..51c31ac3d54996a6e2d870d8215546fd return false; } diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java -index 6c176933967f6ee98da3026f16a10efe4c3842fe..1b919bda12fb6c4bbad8cd477dbcbe520655b346 100644 +index 42ebd91196ae420eee57f4380abc558555457163..f7cc9b8b4fbdaeb48c45eaa574e79e4796007b61 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java +++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java -@@ -149,6 +149,11 @@ public abstract class AbstractArrow extends Projectile { +@@ -156,6 +156,11 @@ public abstract class AbstractArrow extends Projectile { @Override public void tick() { super.tick(); @@ -18320,10 +18382,10 @@ index 6c176933967f6ee98da3026f16a10efe4c3842fe..1b919bda12fb6c4bbad8cd477dbcbe52 Vec3 vec3d = this.getDeltaMovement(); diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java -index 6c9a8f062f989db022154155e8a05b334a0510da..77f55bcb120295fa11140681f63175d37d8a78e2 100644 +index c4ecc5faa4f61e7974e8c475762924a89615b377..40489886060782681f960d1c4eab36981279b76b 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java -@@ -77,6 +77,11 @@ public abstract class AbstractHurtingProjectile extends Projectile { +@@ -88,6 +88,11 @@ public abstract class AbstractHurtingProjectile extends Projectile { this.discard(); } else { super.tick(); @@ -18461,10 +18523,10 @@ index 0bbe853f7df93f9dcd2b21d762939f8b6be069aa..4f4d6dedb99feac995e9b5bdf1d5c9f1 HitResult movingobjectposition = ProjectileUtil.getHitResultOnMoveVector(this, this::canHitEntity); diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index a90317100d32974e481e14476843f66997a2cf3a..0c8f90a904c01105ba5fa6a8037150697bc2621e 100644 +index 2f058cec80c6ef7a5a5ca065dc6c9fe353c521de..dd204b547ea0981cf82c567cc497364ee221f09b 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -@@ -69,9 +69,20 @@ public abstract class Projectile extends Entity implements TraceableEntity { +@@ -70,9 +70,20 @@ public abstract class Projectile extends Entity implements TraceableEntity { } // Paper end @@ -18485,14 +18547,15 @@ index a90317100d32974e481e14476843f66997a2cf3a..0c8f90a904c01105ba5fa6a803715069 if (this.cachedOwner != null && !this.cachedOwner.isRemoved()) { this.refreshProjectileSource(false); // Paper return this.cachedOwner; -@@ -296,6 +307,6 @@ public abstract class Projectile extends Entity implements TraceableEntity { +@@ -304,7 +315,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { public boolean mayInteract(Level world, BlockPos pos) { Entity entity = this.getOwner(); - return entity instanceof Player ? entity.mayInteract(world, pos) : entity == null || world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); + return entity instanceof Player && io.papermc.paper.util.TickThread.isTickThreadFor(entity) ? entity.mayInteract(world, pos) : entity == null || world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // Folia - region threading } - } + + public boolean mayBreak(Level world) { diff --git a/src/main/java/net/minecraft/world/entity/projectile/SmallFireball.java b/src/main/java/net/minecraft/world/entity/projectile/SmallFireball.java index 9d43c8520953d6fe0d0948f9dbe14e0650ee01c2..c7713583930240512cd94f2a6bd1ff819ca6cd48 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/SmallFireball.java @@ -18523,10 +18586,10 @@ index ab777952bda1651796ed41e8a7fc6621f27db9aa..6b9365eba3339578ee2984605240b74d boolean flag = false; diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java -index f5db60cbecbe69941873e064315931089fe0e48a..39bb4ec91e096cf84221a3bddbf7425023f0f609 100644 +index af4da25c9b13c114179fab3254aea5323210d7da..79c175cbcde3f19854b0221791a6624e75562697 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java +++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java -@@ -42,6 +42,62 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { +@@ -45,6 +45,62 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { entityHitResult.getEntity().hurt(this.damageSources().thrown(this, this.getOwner()), 0.0F); } @@ -18589,7 +18652,7 @@ index f5db60cbecbe69941873e064315931089fe0e48a..39bb4ec91e096cf84221a3bddbf74250 @Override protected void onHit(HitResult hitResult) { super.onHit(hitResult); -@@ -51,6 +107,20 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { +@@ -54,6 +110,20 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { } if (!this.level().isClientSide && !this.isRemoved()) { @@ -18610,7 +18673,7 @@ index f5db60cbecbe69941873e064315931089fe0e48a..39bb4ec91e096cf84221a3bddbf74250 Entity entity = this.getOwner(); if (entity instanceof ServerPlayer) { -@@ -82,9 +152,9 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { +@@ -85,9 +155,9 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { entityplayer.connection.teleport(teleEvent.getTo()); entity.resetFallDistance(); @@ -18621,8 +18684,8 @@ index f5db60cbecbe69941873e064315931089fe0e48a..39bb4ec91e096cf84221a3bddbf74250 + CraftEventFactory.entityDamageRT.set(null); // Folia - region threading } // CraftBukkit end - } -@@ -110,6 +180,14 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { + this.level().playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_TELEPORT, SoundSource.PLAYERS); +@@ -114,6 +184,14 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { } @@ -18851,10 +18914,10 @@ index 42d87800a328f71c5127ce5599ca4c71cc9bb1cd..4b08175b71e7f92e9bb578f9f6c2c0ef } diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index 4697df75fdee2023c41260bed211e3e3d90d2b9b..1a0618422675cbe4ab55a03c85c7bc383efa5cee 100644 +index de277d61b718fe07a87d75a2547bb1c7f8553aa1..5289239d64f1081086d864d047ab688dc3fda924 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -357,31 +357,32 @@ public final class ItemStack { +@@ -378,31 +378,32 @@ public final class ItemStack { CompoundTag oldData = this.getTagClone(); int oldCount = this.getCount(); ServerLevel world = (ServerLevel) context.getLevel(); @@ -18896,7 +18959,7 @@ index 4697df75fdee2023c41260bed211e3e3d90d2b9b..1a0618422675cbe4ab55a03c85c7bc38 StructureGrowEvent structureEvent = null; if (treeType != null) { boolean isBonemeal = this.getItem() == Items.BONE_MEAL; -@@ -410,13 +411,13 @@ public final class ItemStack { +@@ -431,13 +432,13 @@ public final class ItemStack { SignItem.openSign = null; // SPIGOT-6758 - Reset on early return return enuminteractionresult; } @@ -18913,7 +18976,7 @@ index 4697df75fdee2023c41260bed211e3e3d90d2b9b..1a0618422675cbe4ab55a03c85c7bc38 if (blocks.size() > 1) { placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockMultiPlaceEvent(world, entityhuman, enumhand, blocks, blockposition.getX(), blockposition.getY(), blockposition.getZ()); } else if (blocks.size() == 1 && item != Items.POWDER_SNOW_BUCKET) { // Paper - don't call event twice for snow buckets -@@ -427,13 +428,13 @@ public final class ItemStack { +@@ -448,13 +449,13 @@ public final class ItemStack { enuminteractionresult = InteractionResult.FAIL; // cancel placement // PAIL: Remove this when MC-99075 fixed placeEvent.getPlayer().updateInventory(); @@ -18929,8 +18992,8 @@ index 4697df75fdee2023c41260bed211e3e3d90d2b9b..1a0618422675cbe4ab55a03c85c7bc38 + worldData.preventPoiUpdated = false; // Folia - region threading // Brute force all possible updates - BlockPos placedPos = ((CraftBlock) placeEvent.getBlock()).getPosition(); -@@ -448,7 +449,7 @@ public final class ItemStack { + // Paper start - don't resync blocks +@@ -471,7 +472,7 @@ public final class ItemStack { this.setCount(newCount); } @@ -18939,7 +19002,7 @@ index 4697df75fdee2023c41260bed211e3e3d90d2b9b..1a0618422675cbe4ab55a03c85c7bc38 world.setBlockEntity(e.getValue()); } -@@ -535,8 +536,8 @@ public final class ItemStack { +@@ -558,8 +559,8 @@ public final class ItemStack { entityhuman.awardStat(Stats.ITEM_USED.get(item)); } } @@ -18951,10 +19014,10 @@ index 4697df75fdee2023c41260bed211e3e3d90d2b9b..1a0618422675cbe4ab55a03c85c7bc38 return enuminteractionresult; diff --git a/src/main/java/net/minecraft/world/item/MapItem.java b/src/main/java/net/minecraft/world/item/MapItem.java -index c368b437597edf7e165326727ae778a69c3fcc83..efa947cbd9b5f98ceb6a782a6fd39884e2f0fa8c 100644 +index 797415866a7f182d804f6b8e57ceb07a6ac2a20a..a6269b362964857ad3f97e6e6c2f7574d92d67e3 100644 --- a/src/main/java/net/minecraft/world/item/MapItem.java +++ b/src/main/java/net/minecraft/world/item/MapItem.java -@@ -103,6 +103,7 @@ public class MapItem extends ComplexItem { +@@ -95,6 +95,7 @@ public class MapItem extends ComplexItem { } public void update(Level world, Entity entity, MapItemSavedData state) { @@ -18962,7 +19025,7 @@ index c368b437597edf7e165326727ae778a69c3fcc83..efa947cbd9b5f98ceb6a782a6fd39884 if (world.dimension() == state.dimension && entity instanceof Player) { int i = 1 << state.scale; int j = state.centerX; -@@ -134,9 +135,9 @@ public class MapItem extends ComplexItem { +@@ -126,9 +127,9 @@ public class MapItem extends ComplexItem { int j2 = (j / i + k1 - 64) * i; int k2 = (k / i + l1 - 64) * i; Multiset multiset = LinkedHashMultiset.create(); @@ -18974,7 +19037,7 @@ index c368b437597edf7e165326727ae778a69c3fcc83..efa947cbd9b5f98ceb6a782a6fd39884 int l2 = 0; double d1 = 0.0D; int i3; -@@ -227,6 +228,7 @@ public class MapItem extends ComplexItem { +@@ -219,6 +220,7 @@ public class MapItem extends ComplexItem { } } @@ -18982,7 +19045,7 @@ index c368b437597edf7e165326727ae778a69c3fcc83..efa947cbd9b5f98ceb6a782a6fd39884 } private BlockState getCorrectStateForFluidBlock(Level world, BlockState state, BlockPos pos) { -@@ -243,6 +245,7 @@ public class MapItem extends ComplexItem { +@@ -235,6 +237,7 @@ public class MapItem extends ComplexItem { MapItemSavedData worldmap = MapItem.getSavedData(map, world); if (worldmap != null) { @@ -18990,7 +19053,7 @@ index c368b437597edf7e165326727ae778a69c3fcc83..efa947cbd9b5f98ceb6a782a6fd39884 if (world.dimension() == worldmap.dimension) { int i = 1 << worldmap.scale; int j = worldmap.centerX; -@@ -317,6 +320,7 @@ public class MapItem extends ComplexItem { +@@ -309,6 +312,7 @@ public class MapItem extends ComplexItem { } } @@ -18998,7 +19061,7 @@ index c368b437597edf7e165326727ae778a69c3fcc83..efa947cbd9b5f98ceb6a782a6fd39884 } } -@@ -326,6 +330,7 @@ public class MapItem extends ComplexItem { +@@ -318,6 +322,7 @@ public class MapItem extends ComplexItem { MapItemSavedData worldmap = MapItem.getSavedData(stack, world); if (worldmap != null) { @@ -19006,7 +19069,7 @@ index c368b437597edf7e165326727ae778a69c3fcc83..efa947cbd9b5f98ceb6a782a6fd39884 if (entity instanceof Player) { Player entityhuman = (Player) entity; -@@ -335,6 +340,7 @@ public class MapItem extends ComplexItem { +@@ -327,6 +332,7 @@ public class MapItem extends ComplexItem { if (!worldmap.locked && (selected || entity instanceof Player && ((Player) entity).getOffhandItem() == stack)) { this.update(world, entity, worldmap); } @@ -19015,10 +19078,10 @@ index c368b437597edf7e165326727ae778a69c3fcc83..efa947cbd9b5f98ceb6a782a6fd39884 } } diff --git a/src/main/java/net/minecraft/world/item/MinecartItem.java b/src/main/java/net/minecraft/world/item/MinecartItem.java -index a33395dc5a94d89b5ab273c7832813b6ff9ea3b7..310c8ebcf05cf5755db1baca8c585eb9a07c7f32 100644 +index 3aa73cd44aa8c86b78c35bc1788e4f83018c49ed..cfead7686da25d2cd9203256962170d7a2d77289 100644 --- a/src/main/java/net/minecraft/world/item/MinecartItem.java +++ b/src/main/java/net/minecraft/world/item/MinecartItem.java -@@ -69,7 +69,7 @@ public class MinecartItem extends Item { +@@ -70,7 +70,7 @@ public class MinecartItem extends Item { CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); BlockDispenseEvent event = new BlockDispenseEvent(block2, craftItem.clone(), new org.bukkit.util.Vector(d0, d1 + d3, d2)); @@ -19028,7 +19091,7 @@ index a33395dc5a94d89b5ab273c7832813b6ff9ea3b7..310c8ebcf05cf5755db1baca8c585eb9 } diff --git a/src/main/java/net/minecraft/world/level/BaseCommandBlock.java b/src/main/java/net/minecraft/world/level/BaseCommandBlock.java -index ceeedbd88c56c08ec8b047c9ca2f14cc581e12ad..19cb22df8eb29d1708e3da2124de3b43378b575a 100644 +index d4ff8c6b7801e33be4ff69b8bae13c09f4872c4b..b7ee6b31d03cd554b229b440b1d5ef6c9ddd2fb5 100644 --- a/src/main/java/net/minecraft/world/level/BaseCommandBlock.java +++ b/src/main/java/net/minecraft/world/level/BaseCommandBlock.java @@ -20,7 +20,7 @@ import net.minecraft.world.phys.Vec3; @@ -19158,28 +19221,28 @@ index aaa07fcd4b32fe0de88142ab30378327a01f1729..08884cc7d787887b470e90897838969d return player; } diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java -index 45243249a561440512ef2a620c60b02e159c80e2..f875a15db0d437a32062c626fb7e42fdcc6cbfde 100644 +index 9442f58dff89ec843c321533965fbee2727d02f8..2a2ea56384bbbd5d7800c3f4c1eb56cd03ef0ec1 100644 --- a/src/main/java/net/minecraft/world/level/Explosion.java +++ b/src/main/java/net/minecraft/world/level/Explosion.java -@@ -566,7 +566,7 @@ public class Explosion { - continue; - } +@@ -584,7 +584,7 @@ public class Explosion { + continue; + } -- CraftEventFactory.entityDamage = this.source; -+ CraftEventFactory.entityDamageRT.set(this.source); // Folia - region threading - entity.lastDamageCancelled = false; +- CraftEventFactory.entityDamage = this.source; ++ CraftEventFactory.entityDamageRT.set(this.source); // Folia - region threading + entity.lastDamageCancelled = false; - if (entity instanceof EnderDragon) { -@@ -582,7 +582,7 @@ public class Explosion { - entity.hurt(this.getDamageSource(), (float) ((int) ((d13 * d13 + d13) / 2.0D * 7.0D * (double) f2 + 1.0D))); - } + if (entity instanceof EnderDragon) { +@@ -598,7 +598,7 @@ public class Explosion { + entity.hurt(this.damageSource, this.damageCalculator.getEntityDamageAmount(this, entity, getSeenFraction(vec3d, entity, blockCache, blockPos))); // Paper - actually optimise explosions + } -- CraftEventFactory.entityDamage = null; -+ CraftEventFactory.entityDamageRT.set(null); // Folia - region threading - if (entity.lastDamageCancelled) { // SPIGOT-5339, SPIGOT-6252, SPIGOT-6777: Skip entity if damage event was cancelled - continue; - } -@@ -852,17 +852,18 @@ public class Explosion { +- CraftEventFactory.entityDamage = null; ++ CraftEventFactory.entityDamageRT.set(null); // Folia - region threading + if (entity.lastDamageCancelled) { // SPIGOT-5339, SPIGOT-6252, SPIGOT-6777: Skip entity if damage event was cancelled + continue; + } +@@ -854,17 +854,18 @@ public class Explosion { if (!this.level.paperConfig().environment.optimizeExplosions) { return this.getSeenFraction(vec3d, entity, blockCache, blockPos); // Paper - optimise explosions } @@ -19202,10 +19265,10 @@ index 45243249a561440512ef2a620c60b02e159c80e2..f875a15db0d437a32062c626fb7e42fd private final double posX, posY, posZ; private final double minX, minY, minZ; diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dce6840a31 100644 +index 0b56e5f7f18fc4286992af22d402205b771165a3..91f17ee2b6c9e1413b5bef62adcfe2a0d9537fef 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -117,10 +117,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -120,10 +120,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public static final int TICKS_PER_DAY = 24000; public static final int MAX_ENTITY_SPAWN_Y = 20000000; public static final int MIN_ENTITY_SPAWN_Y = -20000000; @@ -19220,7 +19283,7 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dc public final Thread thread; private final boolean isDebug; private int skyDarken; -@@ -130,7 +130,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -133,7 +133,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public float rainLevel; protected float oThunderLevel; public float thunderLevel; @@ -19229,7 +19292,7 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dc /** @deprecated */ @Deprecated private final RandomSource threadSafeRandom = RandomSource.createThreadSafe(); -@@ -144,7 +144,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -147,7 +147,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { private final ResourceKey dimension; private final RegistryAccess registryAccess; private final DamageSources damageSources; @@ -19238,7 +19301,7 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dc // CraftBukkit start Added the following private final CraftWorld world; -@@ -153,20 +153,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -156,20 +156,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public org.bukkit.generator.ChunkGenerator generator; public static final boolean DEBUG_ENTITIES = Boolean.getBoolean("debug.entities"); // Paper @@ -19262,7 +19325,7 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dc public final org.spigotmc.SpigotWorldConfig spigotConfig; // Spigot // Paper start private final io.papermc.paper.configuration.WorldConfiguration paperConfig; -@@ -180,9 +170,9 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -183,9 +173,9 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public static BlockPos lastPhysicsProblem; // Spigot private org.spigotmc.TickLimiter entityLimiter; private org.spigotmc.TickLimiter tileLimiter; @@ -19275,7 +19338,7 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dc // Paper start - fix and optimise world upgrading // copied from below -@@ -210,6 +200,33 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -213,6 +203,33 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public abstract ResourceKey getTypeKey(); @@ -19309,7 +19372,7 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dc protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, Supplier supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator, java.util.concurrent.Executor executor) { // Paper - Async-Anti-Xray - Pass executor this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper -@@ -253,7 +270,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -256,7 +273,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { this.thread = Thread.currentThread(); this.biomeManager = new BiomeManager(this, i); this.isDebug = flag1; @@ -19318,7 +19381,7 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dc this.registryAccess = iregistrycustom; this.damageSources = new DamageSources(iregistrycustom); // CraftBukkit start -@@ -846,8 +863,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -849,8 +866,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @Nullable public final BlockState getBlockStateIfLoaded(BlockPos pos) { // CraftBukkit start - tree generation @@ -19329,7 +19392,7 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dc if (previous != null) { return previous.getHandle(); } -@@ -909,16 +926,18 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -912,16 +929,18 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @Override public boolean setBlock(BlockPos pos, BlockState state, int flags, int maxUpdateDepth) { @@ -19351,7 +19414,7 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dc } blockstate.setFlag(flags); // Paper - update the flag also blockstate.setData(state); -@@ -935,10 +954,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -938,10 +957,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // CraftBukkit start - capture blockstates boolean captured = false; @@ -19364,7 +19427,7 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dc captured = true; } // CraftBukkit end -@@ -948,8 +967,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -951,8 +970,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { if (iblockdata1 == null) { // CraftBukkit start - remove blockstate if failed (or the same) @@ -19375,7 +19438,7 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dc } // CraftBukkit end return false; -@@ -986,7 +1005,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -989,7 +1008,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { */ // CraftBukkit start @@ -19384,7 +19447,7 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dc // Modularize client and physic updates // Spigot start try { -@@ -1036,7 +1055,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1039,7 +1058,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { iblockdata1.updateIndirectNeighbourShapes(this, blockposition, k, j - 1); // Don't call an event for the old block to limit event spam CraftWorld world = ((ServerLevel) this).getWorld(); boolean cancelledUpdates = false; // Paper @@ -19393,7 +19456,7 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dc BlockPhysicsEvent event = new BlockPhysicsEvent(world.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), CraftBlockData.fromData(iblockdata)); this.getCraftServer().getPluginManager().callEvent(event); -@@ -1050,7 +1069,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1053,7 +1072,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } // CraftBukkit start - SPIGOT-5710 @@ -19402,7 +19465,7 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dc this.onBlockStateChange(blockposition, iblockdata1, iblockdata2); } // CraftBukkit end -@@ -1129,7 +1148,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1132,7 +1151,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @Override public void neighborShapeChanged(Direction direction, BlockState neighborState, BlockPos pos, BlockPos neighborPos, int flags, int maxUpdateDepth) { @@ -19411,7 +19474,7 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dc } @Override -@@ -1154,11 +1173,34 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1157,11 +1176,34 @@ public abstract class Level implements LevelAccessor, AutoCloseable { return this.getChunkSource().getLightEngine(); } @@ -19448,7 +19511,7 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dc if (previous != null) { return previous.getHandle(); } -@@ -1249,7 +1291,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1258,7 +1300,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } public void addBlockEntityTicker(TickingBlockEntity ticker) { @@ -19457,7 +19520,7 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dc } protected void tickBlockEntities() { -@@ -1257,11 +1299,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1266,11 +1308,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable { gameprofilerfiller.push("blockEntities"); this.timings.tileEntityPending.startTiming(); // Spigot @@ -19473,9 +19536,9 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dc this.timings.tileEntityPending.stopTiming(); // Spigot this.timings.tileEntityTick.startTiming(); // Spigot -@@ -1270,9 +1311,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1281,9 +1322,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { int tilesThisCycle = 0; - var toRemove = new it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet(net.minecraft.Util.identityStrategy()); // Paper - use removeAll + var toRemove = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet(); // Paper - use removeAll toRemove.add(null); - for (tileTickPosition = 0; tileTickPosition < this.blockEntityTickers.size(); tileTickPosition++) { // Paper - Disable tick limiters - this.tileTickPosition = (this.tileTickPosition < this.blockEntityTickers.size()) ? this.tileTickPosition : 0; @@ -19485,8 +19548,8 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dc // Spigot start if (tickingblockentity == null) { this.getCraftServer().getLogger().severe("Spigot has detected a null entity and has removed it, preventing a crash"); -@@ -1289,19 +1329,19 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - } else if (this.shouldTickBlocksAt(tickingblockentity.getPos())) { +@@ -1300,19 +1340,19 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + } else if (flag && this.shouldTickBlocksAt(tickingblockentity.getPos())) { tickingblockentity.tick(); // Paper start - execute chunk tasks during tick - if ((this.tileTickPosition & 7) == 0) { @@ -19510,7 +19573,7 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dc } public void guardEntityTick(Consumer tickConsumer, T entity) { -@@ -1314,7 +1354,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1325,7 +1365,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { final String msg = String.format("Entity threw exception at %s:%s,%s,%s", entity.level().getWorld().getName(), entity.getX(), entity.getY(), entity.getZ()); MinecraftServer.LOGGER.error(msg, throwable); getCraftServer().getPluginManager().callEvent(new ServerExceptionEvent(new ServerInternalException(msg, throwable))); @@ -19520,7 +19583,7 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dc // Paper end } } -@@ -1407,9 +1448,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1425,9 +1466,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @Nullable public BlockEntity getBlockEntity(BlockPos blockposition, boolean validate) { @@ -19536,7 +19599,7 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dc return blockEntity; } // Paper end -@@ -1422,8 +1468,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1440,8 +1486,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { if (!this.isOutsideBuildHeight(blockposition)) { // CraftBukkit start @@ -19547,7 +19610,7 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dc return; } // CraftBukkit end -@@ -1503,6 +1549,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1521,6 +1567,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @Override public List getEntities(@Nullable Entity except, AABB box, Predicate predicate) { @@ -19555,7 +19618,7 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dc this.getProfiler().incrementCounter("getEntities"); List list = Lists.newArrayList(); ((ServerLevel)this).getEntityLookup().getEntities(except, box, list, predicate); // Paper - optimise this call -@@ -1522,6 +1569,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1540,6 +1587,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } public void getEntities(EntityTypeTest filter, AABB box, Predicate predicate, List result, int limit) { @@ -19563,7 +19626,7 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dc this.getProfiler().incrementCounter("getEntities"); // Paper start - optimise this call //TODO use limit -@@ -1559,13 +1607,30 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1577,13 +1625,30 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public void disconnect() {} @@ -19596,7 +19659,7 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dc public boolean mayInteract(Player player, BlockPos pos) { return true; -@@ -1767,8 +1832,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1787,8 +1852,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } public final BlockPos.MutableBlockPos getRandomBlockPosition(int x, int y, int z, int l, BlockPos.MutableBlockPos out) { // Paper end @@ -19606,7 +19669,7 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dc out.set(x + (i1 & 15), y + (i1 >> 16 & l), z + (i1 >> 8 & 15)); // Paper - change to setValues call return out; // Paper -@@ -1799,7 +1863,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1819,7 +1883,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @Override public long nextSubTickCount() { @@ -19616,7 +19679,7 @@ index 2354a0e5d15e9be633d9fe3a1a9feefe7b9b7782..2329d08c736ab04f640b0baef3a0d3dc @Override diff --git a/src/main/java/net/minecraft/world/level/LevelAccessor.java b/src/main/java/net/minecraft/world/level/LevelAccessor.java -index 73d1adc5ddf0363966eac0c77c8dfbbb20a2b6a3..375a2b57bcb29458443c1a4e2be3c0e5f4e6019c 100644 +index bd9ac874b2d4333bc5c3a79657d63f1bd41fd8c8..f706159a85fe463806b44c768dc9d438a6a1d958 100644 --- a/src/main/java/net/minecraft/world/level/LevelAccessor.java +++ b/src/main/java/net/minecraft/world/level/LevelAccessor.java @@ -35,12 +35,22 @@ public interface LevelAccessor extends CommonLevelAccessor, LevelTimeAccess { @@ -19753,10 +19816,10 @@ index 09c85ed428b8eaf51f8b3c6e45cce925f05ab354..3d797880b5964dd07f3757495ea1255a } diff --git a/src/main/java/net/minecraft/world/level/block/BedBlock.java b/src/main/java/net/minecraft/world/level/block/BedBlock.java -index d40500f9a807cab0b2fb6fa9032f33f4fb74c895..824d89c2c70c64f6b37155dcc2aa0f7bd34d0303 100644 +index 04b1aa22ac1df39d274f27d9c93e0492a8a673f8..2599e0f62ef172340c54c80c997f7a652faddedb 100644 --- a/src/main/java/net/minecraft/world/level/block/BedBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BedBlock.java -@@ -357,7 +357,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock +@@ -367,7 +367,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock world.setBlock(blockposition1, (BlockState) state.setValue(BedBlock.PART, BedPart.HEAD), 3); // CraftBukkit start - SPIGOT-7315: Don't updated if we capture block states @@ -19766,10 +19829,10 @@ index d40500f9a807cab0b2fb6fa9032f33f4fb74c895..824d89c2c70c64f6b37155dcc2aa0f7b } // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java -index d4cbff18adb62073a1dceb189043789620af6877..4ddc3484311f9c83a6f8aecb89188195ab281742 100644 +index 4d50dd92a7f3187ee1d8edb926e7c273c8156549..c98a6875f72d067de65f4cff05818ee3f0b3d90f 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java -@@ -382,8 +382,8 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -389,8 +389,8 @@ public class Block extends BlockBehaviour implements ItemLike { entityitem.setDefaultPickUpDelay(); // CraftBukkit start @@ -19781,10 +19844,10 @@ index d4cbff18adb62073a1dceb189043789620af6877..4ddc3484311f9c83a6f8aecb89188195 world.addFreshEntity(entityitem); } diff --git a/src/main/java/net/minecraft/world/level/block/BushBlock.java b/src/main/java/net/minecraft/world/level/block/BushBlock.java -index 03fde6e47c4a347c62fe9b4a3351769aedf874f6..d2e3e1d20d60f5edd0d93709b808f812c31e7491 100644 +index bed3d9c781c7d3ca260027b4737970889a54689c..46c81d73813c6607d95062358e6e3cd05ffe3192 100644 --- a/src/main/java/net/minecraft/world/level/block/BushBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BushBlock.java -@@ -24,7 +24,7 @@ public class BushBlock extends Block { +@@ -28,7 +28,7 @@ public abstract class BushBlock extends Block { public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { // CraftBukkit start if (!state.canSurvive(world, pos)) { @@ -19794,10 +19857,10 @@ index 03fde6e47c4a347c62fe9b4a3351769aedf874f6..d2e3e1d20d60f5edd0d93709b808f812 } } diff --git a/src/main/java/net/minecraft/world/level/block/CactusBlock.java b/src/main/java/net/minecraft/world/level/block/CactusBlock.java -index 0003fb51ae3a6575575e10b4c86719f3061e2577..362aab7977f636fa8a8548a01ab333da066fbc76 100644 +index a9629a102c4fa4e5720e63fcf4590e9231426c62..5ae6509b3f4d66fece987bd5c39426c402dcca74 100644 --- a/src/main/java/net/minecraft/world/level/block/CactusBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CactusBlock.java -@@ -115,9 +115,9 @@ public class CactusBlock extends Block { +@@ -122,9 +122,9 @@ public class CactusBlock extends Block { @Override public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper @@ -19810,10 +19873,10 @@ index 0003fb51ae3a6575575e10b4c86719f3061e2577..362aab7977f636fa8a8548a01ab333da @Override diff --git a/src/main/java/net/minecraft/world/level/block/CampfireBlock.java b/src/main/java/net/minecraft/world/level/block/CampfireBlock.java -index 7700461b8cd0bde1bf6c0d5e4b73184bed1adc4e..479f571152ebb17315b294469658665b6a4e0c12 100644 +index 7302d07c6ff69608e75ac52fdb19f2ec1d105129..cdd0c10fea2684c70bb2295ff6bc2ea8f303cc58 100644 --- a/src/main/java/net/minecraft/world/level/block/CampfireBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CampfireBlock.java -@@ -95,9 +95,9 @@ public class CampfireBlock extends BaseEntityBlock implements SimpleWaterloggedB +@@ -110,9 +110,9 @@ public class CampfireBlock extends BaseEntityBlock implements SimpleWaterloggedB public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper if ((Boolean) state.getValue(CampfireBlock.LIT) && entity instanceof LivingEntity && !EnchantmentHelper.hasFrostWalker((LivingEntity) entity)) { @@ -19826,10 +19889,10 @@ index 7700461b8cd0bde1bf6c0d5e4b73184bed1adc4e..479f571152ebb17315b294469658665b super.entityInside(state, world, pos, entity); diff --git a/src/main/java/net/minecraft/world/level/block/DaylightDetectorBlock.java b/src/main/java/net/minecraft/world/level/block/DaylightDetectorBlock.java -index c98a7d0cc2fcf993ab05dc9347bfb34a7e1bdde5..db3060021f9e024a6dba93498422d41e9662f68a 100644 +index de6f00d03223939386aa2ccfdec1e696a68313d7..eb7c2c5b762dbadbe9ccbddc37757bdf97ea4bfe 100644 --- a/src/main/java/net/minecraft/world/level/block/DaylightDetectorBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DaylightDetectorBlock.java -@@ -113,7 +113,7 @@ public class DaylightDetectorBlock extends BaseEntityBlock { +@@ -120,7 +120,7 @@ public class DaylightDetectorBlock extends BaseEntityBlock { } private static void tickEntity(Level world, BlockPos pos, BlockState state, DaylightDetectorBlockEntity blockEntity) { @@ -19839,19 +19902,19 @@ index c98a7d0cc2fcf993ab05dc9347bfb34a7e1bdde5..db3060021f9e024a6dba93498422d41e } diff --git a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java -index 9b1e51c1d95da885c80c6d05000d83436b7bcfb4..5ff51a42415306907045452c9feff62afe02898e 100644 +index 52e92ffd6bf5d3d721807a0b3a8e2d301951f934..ed6c84ba826ead1071c56923e457aa6e3c26a66b 100644 --- a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java -@@ -48,7 +48,7 @@ public class DispenserBlock extends BaseEntityBlock { +@@ -49,7 +49,7 @@ public class DispenserBlock extends BaseEntityBlock { object2objectopenhashmap.defaultReturnValue(new DefaultDispenseItemBehavior()); }); private static final int TRIGGER_DURATION = 4; - public static boolean eventFired = false; // CraftBukkit + public static ThreadLocal eventFired = ThreadLocal.withInitial(() -> Boolean.FALSE); // CraftBukkit // Folia - region threading - public static void registerBehavior(ItemLike provider, DispenseItemBehavior behavior) { - DispenserBlock.DISPENSER_REGISTRY.put(provider.asItem(), behavior); -@@ -99,7 +99,7 @@ public class DispenserBlock extends BaseEntityBlock { + @Override + public MapCodec codec() { +@@ -105,7 +105,7 @@ public class DispenserBlock extends BaseEntityBlock { if (idispensebehavior != DispenseItemBehavior.NOOP) { if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockPreDispenseEvent(world, pos, itemstack, i)) return; // Paper - BlockPreDispenseEvent is called here @@ -19861,12 +19924,12 @@ index 9b1e51c1d95da885c80c6d05000d83436b7bcfb4..5ff51a42415306907045452c9feff62a } diff --git a/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java b/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java -index 030b38d5d5d2578d6ef482a239ef58787efa3b08..c93a125445107d97db2a647d7b57b5f871d7e97a 100644 +index 81d2140351775ad55546af52eb635ccdc8509d89..c4a5f7af76f60dd708d1ad7b384ec55a2ea7ec76 100644 --- a/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java -@@ -95,7 +95,7 @@ public class DoublePlantBlock extends BushBlock { +@@ -102,7 +102,7 @@ public class DoublePlantBlock extends BushBlock { - protected static void preventCreativeDropFromBottomPart(Level world, BlockPos pos, BlockState state, Player player) { + protected static void preventDropFromBottomPart(Level world, BlockPos pos, BlockState state, Player player) { // CraftBukkit start - if (((net.minecraft.server.level.ServerLevel)world).hasPhysicsEvent && org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(world, pos).isCancelled()) { // Paper + if (((net.minecraft.server.level.ServerLevel)world).getCurrentWorldData().hasPhysicsEvent && org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(world, pos).isCancelled()) { // Paper // Folia - region threading @@ -19874,10 +19937,10 @@ index 030b38d5d5d2578d6ef482a239ef58787efa3b08..c93a125445107d97db2a647d7b57b5f8 } // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/level/block/FungusBlock.java b/src/main/java/net/minecraft/world/level/block/FungusBlock.java -index 17e9e2efc78cfe8577dbf4e1d6096543ad8b8ac4..37b0f51eb93a331f2d3b33deb4467f65c474b92c 100644 +index 50d7235cf2ef036451db708c45a063d037051ae9..c0433491be43bb8cc6d00e32edf7699a79f7a251 100644 --- a/src/main/java/net/minecraft/world/level/block/FungusBlock.java +++ b/src/main/java/net/minecraft/world/level/block/FungusBlock.java -@@ -61,9 +61,9 @@ public class FungusBlock extends BushBlock implements BonemealableBlock { +@@ -76,9 +76,9 @@ public class FungusBlock extends BushBlock implements BonemealableBlock { this.getFeature(world).ifPresent((holder) -> { // CraftBukkit start if (this == Blocks.WARPED_FUNGUS) { @@ -19890,10 +19953,10 @@ index 17e9e2efc78cfe8577dbf4e1d6096543ad8b8ac4..37b0f51eb93a331f2d3b33deb4467f65 // CraftBukkit end ((ConfiguredFeature) holder.value()).place(world, world.getChunkSource().getGenerator(), random, pos); diff --git a/src/main/java/net/minecraft/world/level/block/HoneyBlock.java b/src/main/java/net/minecraft/world/level/block/HoneyBlock.java -index 745f33ce496a7ce8c788f24c093b37933a74148a..b81b43635dcf516492ec5edfa385efcdea4f7534 100644 +index b9d89cce40e4cbeaf98eeb85c254db353e573c95..cfdc8a8337053ddef92b572109256d592160d3ae 100644 --- a/src/main/java/net/minecraft/world/level/block/HoneyBlock.java +++ b/src/main/java/net/minecraft/world/level/block/HoneyBlock.java -@@ -80,7 +80,7 @@ public class HoneyBlock extends HalfTransparentBlock { +@@ -87,7 +87,7 @@ public class HoneyBlock extends HalfTransparentBlock { } private void maybeDoSlideAchievement(Entity entity, BlockPos pos) { @@ -19903,10 +19966,10 @@ index 745f33ce496a7ce8c788f24c093b37933a74148a..b81b43635dcf516492ec5edfa385efcd } diff --git a/src/main/java/net/minecraft/world/level/block/LightningRodBlock.java b/src/main/java/net/minecraft/world/level/block/LightningRodBlock.java -index da3b301a42a93c891d083a6e02d1be8ed35adf1d..f354981843868bf938be0b5ac1ef2ce39fb067ef 100644 +index ec4aaaca2160312452d724dc6639ac8c4fa42ae4..e1f67599724f67f4f1321f219af8099e8c54e9e7 100644 --- a/src/main/java/net/minecraft/world/level/block/LightningRodBlock.java +++ b/src/main/java/net/minecraft/world/level/block/LightningRodBlock.java -@@ -112,7 +112,7 @@ public class LightningRodBlock extends RodBlock implements SimpleWaterloggedBloc +@@ -119,7 +119,7 @@ public class LightningRodBlock extends RodBlock implements SimpleWaterloggedBloc @Override public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource random) { @@ -19916,10 +19979,10 @@ index da3b301a42a93c891d083a6e02d1be8ed35adf1d..f354981843868bf938be0b5ac1ef2ce3 } } diff --git a/src/main/java/net/minecraft/world/level/block/MagmaBlock.java b/src/main/java/net/minecraft/world/level/block/MagmaBlock.java -index 1b766045687e4dcded5cbcc50b746c55b9a34e22..a8270d65c22fa979ce53ffeeeadce8d61db397e1 100644 +index 10f5ffacc72a5e0116e2599ca83ee57a5b1ce0eb..64253e85e87c823d5ead285587496f6f8d825a43 100644 --- a/src/main/java/net/minecraft/world/level/block/MagmaBlock.java +++ b/src/main/java/net/minecraft/world/level/block/MagmaBlock.java -@@ -23,9 +23,9 @@ public class MagmaBlock extends Block { +@@ -30,9 +30,9 @@ public class MagmaBlock extends Block { @Override public void stepOn(Level world, BlockPos pos, BlockState state, Entity entity) { if (!entity.isSteppingCarefully() && entity instanceof LivingEntity && !EnchantmentHelper.hasFrostWalker((LivingEntity) entity)) { @@ -19932,10 +19995,10 @@ index 1b766045687e4dcded5cbcc50b746c55b9a34e22..a8270d65c22fa979ce53ffeeeadce8d6 super.stepOn(world, pos, state, entity); diff --git a/src/main/java/net/minecraft/world/level/block/MushroomBlock.java b/src/main/java/net/minecraft/world/level/block/MushroomBlock.java -index 302c5a6401facf192677b89cc0e9190bb35b1229..63a51676162d8e658cf10f63ff91d450850a4b86 100644 +index 7368c76a01275223a7bd3df1d36e80a15f66edbb..da1444e6ac3dd5d785763126b1e2ab2b96de7ff6 100644 --- a/src/main/java/net/minecraft/world/level/block/MushroomBlock.java +++ b/src/main/java/net/minecraft/world/level/block/MushroomBlock.java -@@ -93,7 +93,7 @@ public class MushroomBlock extends BushBlock implements BonemealableBlock { +@@ -105,7 +105,7 @@ public class MushroomBlock extends BushBlock implements BonemealableBlock { return false; } else { world.removeBlock(pos, false); @@ -19945,10 +20008,10 @@ index 302c5a6401facf192677b89cc0e9190bb35b1229..63a51676162d8e658cf10f63ff91d450 return true; } else { diff --git a/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java b/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java -index cd943997f11f5ea5c600fdc6db96043fb0fa713c..7039b27f74b7898e7028cbd67184c6e9ba213e39 100644 +index bd22d3fdecbc992b11073a74d854b7d1b43c3f6a..999e601a369ca6817ea21286d439ffd724a2f769 100644 --- a/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java +++ b/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java -@@ -141,9 +141,9 @@ public class PointedDripstoneBlock extends Block implements Fallable, SimpleWate +@@ -150,9 +150,9 @@ public class PointedDripstoneBlock extends Block implements Fallable, SimpleWate @Override public void fallOn(Level world, BlockState state, BlockPos pos, Entity entity, float fallDistance) { if (state.getValue(PointedDripstoneBlock.TIP_DIRECTION) == Direction.UP && state.getValue(PointedDripstoneBlock.THICKNESS) == DripstoneThickness.TIP) { @@ -19961,19 +20024,19 @@ index cd943997f11f5ea5c600fdc6db96043fb0fa713c..7039b27f74b7898e7028cbd67184c6e9 super.fallOn(world, state, pos, entity, fallDistance); } diff --git a/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java b/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java -index 2b054439b7a763d5a3fbb5dbfe197cb9a9a3525c..f695d81a646307846abb490b484f166be2993382 100644 +index 507be06ad51b7a212e28d3ca6680e0e4b00f4233..bf0e67921d96edde46a97543099f9c03634fca11 100644 --- a/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java +++ b/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java -@@ -67,7 +67,7 @@ public class RedStoneWireBlock extends Block { +@@ -69,7 +69,7 @@ public class RedStoneWireBlock extends Block { }); private static final float PARTICLE_DENSITY = 0.2F; private final BlockState crossState; - public boolean shouldSignal = true; + //public boolean shouldSignal = true; // Folia - region threading - move to regionised world data - public RedStoneWireBlock(BlockBehaviour.Properties settings) { - super(settings); -@@ -262,7 +262,7 @@ public class RedStoneWireBlock extends Block { + @Override + public MapCodec codec() { +@@ -269,7 +269,7 @@ public class RedStoneWireBlock extends Block { * Note: Added 'source' argument so as to help determine direction of information flow */ private void updateSurroundingRedstone(Level worldIn, BlockPos pos, BlockState state, BlockPos source) { @@ -19982,7 +20045,7 @@ index 2b054439b7a763d5a3fbb5dbfe197cb9a9a3525c..f695d81a646307846abb490b484f166b turbo.updateSurroundingRedstone(worldIn, pos, state, source); return; } -@@ -282,11 +282,11 @@ public class RedStoneWireBlock extends Block { +@@ -289,11 +289,11 @@ public class RedStoneWireBlock extends Block { int i = state.getValue(POWER); int j = 0; j = this.getPower(j, worldIn.getBlockState(pos2)); @@ -19997,7 +20060,7 @@ index 2b054439b7a763d5a3fbb5dbfe197cb9a9a3525c..f695d81a646307846abb490b484f166b // This code is totally redundant to if statements just below the loop. if (k > 0 && k > j - 1) { j = k; -@@ -300,7 +300,7 @@ public class RedStoneWireBlock extends Block { +@@ -307,7 +307,7 @@ public class RedStoneWireBlock extends Block { // redstone wire will be set to 'k'. If 'k' is already 15, then nothing inside the // following loop can affect the power level of the wire. Therefore, the loop is // skipped if k is already 15. @@ -20006,7 +20069,7 @@ index 2b054439b7a763d5a3fbb5dbfe197cb9a9a3525c..f695d81a646307846abb490b484f166b for (Direction enumfacing : Direction.Plane.HORIZONTAL) { BlockPos blockpos = pos1.relative(enumfacing); boolean flag = blockpos.getX() != pos2.getX() || blockpos.getZ() != pos2.getZ(); -@@ -319,7 +319,7 @@ public class RedStoneWireBlock extends Block { +@@ -326,7 +326,7 @@ public class RedStoneWireBlock extends Block { } } @@ -20015,7 +20078,7 @@ index 2b054439b7a763d5a3fbb5dbfe197cb9a9a3525c..f695d81a646307846abb490b484f166b // The old code would decrement the wire value only by 1 at a time. if (l > j) { j = l - 1; -@@ -403,10 +403,10 @@ public class RedStoneWireBlock extends Block { +@@ -410,10 +410,10 @@ public class RedStoneWireBlock extends Block { } private int calculateTargetStrength(Level world, BlockPos pos) { @@ -20028,7 +20091,7 @@ index 2b054439b7a763d5a3fbb5dbfe197cb9a9a3525c..f695d81a646307846abb490b484f166b int j = 0; if (i < 15) { -@@ -455,7 +455,7 @@ public class RedStoneWireBlock extends Block { +@@ -462,7 +462,7 @@ public class RedStoneWireBlock extends Block { public void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) { if (!oldState.is(state.getBlock()) && !world.isClientSide) { // Paper start - optimize redstone - replace call to updatePowerStrength @@ -20037,7 +20100,7 @@ index 2b054439b7a763d5a3fbb5dbfe197cb9a9a3525c..f695d81a646307846abb490b484f166b world.getWireHandler().onWireAdded(pos); // Alternate Current } else { this.updateSurroundingRedstone(world, pos, state, null); // vanilla/Eigencraft -@@ -488,7 +488,7 @@ public class RedStoneWireBlock extends Block { +@@ -495,7 +495,7 @@ public class RedStoneWireBlock extends Block { } // Paper start - optimize redstone - replace call to updatePowerStrength @@ -20046,7 +20109,7 @@ index 2b054439b7a763d5a3fbb5dbfe197cb9a9a3525c..f695d81a646307846abb490b484f166b world.getWireHandler().onWireRemoved(pos, state); // Alternate Current } else { this.updateSurroundingRedstone(world, pos, state, null); // vanilla/Eigencraft -@@ -529,7 +529,7 @@ public class RedStoneWireBlock extends Block { +@@ -536,7 +536,7 @@ public class RedStoneWireBlock extends Block { if (!world.isClientSide) { // Paper start - optimize redstone (Alternate Current) // Alternate Current handles breaking of redstone wires in the WireHandler. @@ -20055,7 +20118,7 @@ index 2b054439b7a763d5a3fbb5dbfe197cb9a9a3525c..f695d81a646307846abb490b484f166b world.getWireHandler().onWireUpdated(pos); } else // Paper end -@@ -545,12 +545,12 @@ public class RedStoneWireBlock extends Block { +@@ -552,12 +552,12 @@ public class RedStoneWireBlock extends Block { @Override public int getDirectSignal(BlockState state, BlockGetter world, BlockPos pos, Direction direction) { @@ -20070,7 +20133,7 @@ index 2b054439b7a763d5a3fbb5dbfe197cb9a9a3525c..f695d81a646307846abb490b484f166b int i = (Integer) state.getValue(RedStoneWireBlock.POWER); return i == 0 ? 0 : (direction != Direction.UP && !((RedstoneSide) this.getConnectionState(world, state, pos).getValue((Property) RedStoneWireBlock.PROPERTY_BY_DIRECTION.get(direction.getOpposite()))).isConnected() ? 0 : i); -@@ -577,7 +577,7 @@ public class RedStoneWireBlock extends Block { +@@ -584,7 +584,7 @@ public class RedStoneWireBlock extends Block { @Override public boolean isSignalSource(BlockState state) { @@ -20080,10 +20143,10 @@ index 2b054439b7a763d5a3fbb5dbfe197cb9a9a3525c..f695d81a646307846abb490b484f166b public static int getColorForPower(int powerLevel) { diff --git a/src/main/java/net/minecraft/world/level/block/RedstoneTorchBlock.java b/src/main/java/net/minecraft/world/level/block/RedstoneTorchBlock.java -index c91535f6c0bbc870fad7e04b9d341783cfcbbd63..660ade166edf1750247e6a02134581de4225f338 100644 +index 6c49962e8f9e2a5fca50b33f3e3fff76fa36f907..aebb26f379cd3bdb39432c8b70c6d382e02070c7 100644 --- a/src/main/java/net/minecraft/world/level/block/RedstoneTorchBlock.java +++ b/src/main/java/net/minecraft/world/level/block/RedstoneTorchBlock.java -@@ -74,10 +74,10 @@ public class RedstoneTorchBlock extends TorchBlock { +@@ -81,10 +81,10 @@ public class RedstoneTorchBlock extends BaseTorchBlock { public void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { boolean flag = this.hasNeighborSignal(world, pos, state); // Paper start @@ -20096,7 +20159,7 @@ index c91535f6c0bbc870fad7e04b9d341783cfcbbd63..660ade166edf1750247e6a02134581de redstoneUpdateInfos.poll(); } } -@@ -158,14 +158,14 @@ public class RedstoneTorchBlock extends TorchBlock { +@@ -165,14 +165,14 @@ public class RedstoneTorchBlock extends BaseTorchBlock { private static boolean isToggledTooFrequently(Level world, BlockPos pos, boolean addNew) { // Paper start @@ -20114,7 +20177,7 @@ index c91535f6c0bbc870fad7e04b9d341783cfcbbd63..660ade166edf1750247e6a02134581de } int i = 0; -@@ -187,12 +187,18 @@ public class RedstoneTorchBlock extends TorchBlock { +@@ -194,12 +194,18 @@ public class RedstoneTorchBlock extends BaseTorchBlock { public static class Toggle { @@ -20136,19 +20199,19 @@ index c91535f6c0bbc870fad7e04b9d341783cfcbbd63..660ade166edf1750247e6a02134581de } } diff --git a/src/main/java/net/minecraft/world/level/block/SaplingBlock.java b/src/main/java/net/minecraft/world/level/block/SaplingBlock.java -index 53ac4e618fec3fe384d8a106c521f3eace0b5b35..2724793d0e2e455f81393775adc6ddceb2319fbc 100644 +index 836c86104ed4f0d375330c9123af5d502efefa4d..68bd6dfb3b99b8e524f808effd1299278a9be23c 100644 --- a/src/main/java/net/minecraft/world/level/block/SaplingBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SaplingBlock.java -@@ -27,7 +27,7 @@ public class SaplingBlock extends BushBlock implements BonemealableBlock { +@@ -34,7 +34,7 @@ public class SaplingBlock extends BushBlock implements BonemealableBlock { protected static final float AABB_OFFSET = 6.0F; protected static final VoxelShape SHAPE = Block.box(2.0D, 0.0D, 2.0D, 14.0D, 12.0D, 14.0D); - private final AbstractTreeGrower treeGrower; + protected final TreeGrower treeGrower; - public static TreeType treeType; // CraftBukkit + public static final ThreadLocal treeTypeRT = new ThreadLocal<>(); // CraftBukkit // Folia - region threading - protected SaplingBlock(AbstractTreeGrower generator, BlockBehaviour.Properties settings) { - super(settings); -@@ -53,18 +53,19 @@ public class SaplingBlock extends BushBlock implements BonemealableBlock { + @Override + public MapCodec codec() { +@@ -65,18 +65,19 @@ public class SaplingBlock extends BushBlock implements BonemealableBlock { world.setBlock(pos, (net.minecraft.world.level.block.state.BlockState) state.cycle(SaplingBlock.STAGE), 4); } else { // CraftBukkit start @@ -20177,10 +20240,10 @@ index 53ac4e618fec3fe384d8a106c521f3eace0b5b35..2724793d0e2e455f81393775adc6ddce if (treeType != null) { event = new StructureGrowEvent(location, treeType, false, null, blocks); diff --git a/src/main/java/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java b/src/main/java/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java -index 9bbb9f8e917288bb0d11661a1399a05631ebcce0..8d57dc0aa214e14690880f9a58234fff134cf1f1 100644 +index 1acdf9dad2621a20b077c5f88dab5e0f8688a38f..8db4aab2ca8b0f6b5d9c58bea17d2394a7f460d8 100644 --- a/src/main/java/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java -@@ -51,7 +51,7 @@ public abstract class SpreadingSnowyDirtBlock extends SnowyDirtBlock { +@@ -55,7 +55,7 @@ public abstract class SpreadingSnowyDirtBlock extends SnowyDirtBlock { @Override public void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { @@ -20190,10 +20253,10 @@ index 9bbb9f8e917288bb0d11661a1399a05631ebcce0..8d57dc0aa214e14690880f9a58234fff net.minecraft.world.level.chunk.ChunkAccess cachedBlockChunk = world.getChunkIfLoaded(pos); if (cachedBlockChunk == null) { // Is this needed? diff --git a/src/main/java/net/minecraft/world/level/block/SweetBerryBushBlock.java b/src/main/java/net/minecraft/world/level/block/SweetBerryBushBlock.java -index 34eb7ba1adb51e394bf46a6f643db3529626d9ec..c9c544f6db4a24d66e81d9ba2929a41507c5d4af 100644 +index f474ae7b3121de701f371b7d88e80086ec07d03d..ce8253c5b9253e5743478c9c75006868dca9cb78 100644 --- a/src/main/java/net/minecraft/world/level/block/SweetBerryBushBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SweetBerryBushBlock.java -@@ -85,9 +85,9 @@ public class SweetBerryBushBlock extends BushBlock implements BonemealableBlock +@@ -92,9 +92,9 @@ public class SweetBerryBushBlock extends BushBlock implements BonemealableBlock double d1 = Math.abs(entity.getZ() - entity.zOld); if (d0 >= 0.003000000026077032D || d1 >= 0.003000000026077032D) { @@ -20206,10 +20269,10 @@ index 34eb7ba1adb51e394bf46a6f643db3529626d9ec..c9c544f6db4a24d66e81d9ba2929a415 } diff --git a/src/main/java/net/minecraft/world/level/block/WitherSkullBlock.java b/src/main/java/net/minecraft/world/level/block/WitherSkullBlock.java -index 1aa0e921890d600c9274deb923da04e72b12bcc6..daca759793b4a22406fb9c75b5ac9814920d3ac0 100644 +index fb180f0bcd20e51d41cfc924029c0b23d3d26258..3db0727cd8d835e8d1b7b3fab93613d2e97b95ab 100644 --- a/src/main/java/net/minecraft/world/level/block/WitherSkullBlock.java +++ b/src/main/java/net/minecraft/world/level/block/WitherSkullBlock.java -@@ -51,7 +51,7 @@ public class WitherSkullBlock extends SkullBlock { +@@ -58,7 +58,7 @@ public class WitherSkullBlock extends SkullBlock { } public static void checkSpawn(Level world, BlockPos pos, SkullBlockEntity blockEntity) { @@ -20481,7 +20544,7 @@ index 65112ec3a6ea1c27f032477720ae74395523012b..7f9022a271e29d0b47bef15359f1b2dc @Override diff --git a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java -index 1ec80f9c901dff1c9f29befa5a8e3c3f6f37aaf7..53f70401fbed7f60507559a8e3d6dcd2400a1179 100644 +index 7491e075baebc7d412d35593bb844b200e304447..4e78efa752b18f68f6edf43cef3bc7bee79bb570 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java @@ -50,9 +50,12 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity { @@ -20785,13 +20848,13 @@ index 28e3b73507b988f7234cbf29c4024c88180d0aef..c8facee29ee08e0975528083f89b64f0 + + BlockEntity getTileEntity(); // Folia - region threading } -diff --git a/src/main/java/net/minecraft/world/level/block/grower/AbstractTreeGrower.java b/src/main/java/net/minecraft/world/level/block/grower/AbstractTreeGrower.java -index a743f36f2682a6b72ffa6644782fc081d1479eb7..f5263a71d97f404c6f6dbd3354a5ed2e98bb71db 100644 ---- a/src/main/java/net/minecraft/world/level/block/grower/AbstractTreeGrower.java -+++ b/src/main/java/net/minecraft/world/level/block/grower/AbstractTreeGrower.java -@@ -75,51 +75,53 @@ public abstract class AbstractTreeGrower { +diff --git a/src/main/java/net/minecraft/world/level/block/grower/TreeGrower.java b/src/main/java/net/minecraft/world/level/block/grower/TreeGrower.java +index 8cb822fed0cda4268f288feae1079a3dc4dc103e..3f53d51960ded5df3b8be12362110f22b3c495b8 100644 +--- a/src/main/java/net/minecraft/world/level/block/grower/TreeGrower.java ++++ b/src/main/java/net/minecraft/world/level/block/grower/TreeGrower.java +@@ -175,51 +175,53 @@ public final class TreeGrower { // CraftBukkit start - protected void setTreeType(Holder> holder) { + private void setTreeType(Holder> holder) { ResourceKey> worldgentreeabstract = holder.unwrapKey().get(); + TreeType treeType; // Folia - region threading if (worldgentreeabstract == TreeFeatures.OAK || worldgentreeabstract == TreeFeatures.OAK_BEES_005) { @@ -20863,7 +20926,7 @@ index a743f36f2682a6b72ffa6644782fc081d1479eb7..f5263a71d97f404c6f6dbd3354a5ed2e + SaplingBlock.treeTypeRT.set(treeType); // Folia - region threading } // CraftBukkit end - } + diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java b/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java index 1ef87580574919796dbba707f44a413ee5c5781b..a595abb43853cd4c3f5886a83527c6cbe4a3e8f7 100644 --- a/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java @@ -21285,7 +21348,7 @@ index 598dc0d3a2b9387e76d7e4e19e54c4573a24bc54..8a139bcfc9c3de5793b1b590be6cafaa boolean bl2 = this.maxChainedNeighborUpdates >= 0 && this.count >= this.maxChainedNeighborUpdates; ++this.count; diff --git a/src/main/java/net/minecraft/world/level/saveddata/SavedData.java b/src/main/java/net/minecraft/world/level/saveddata/SavedData.java -index f9e3a10f91b7b22604cf13d9e7ebdca460aa39ca..92fe26539027ee57b134c1cf3c0686d7182b6fea 100644 +index 697df9a9f050c0130246ce2b08a859965bddf184..6cd6e83e56cd315cf40fce23318df9e07576a8e5 100644 --- a/src/main/java/net/minecraft/world/level/saveddata/SavedData.java +++ b/src/main/java/net/minecraft/world/level/saveddata/SavedData.java @@ -13,7 +13,7 @@ import org.slf4j.Logger; @@ -21506,10 +21569,10 @@ index e4c4948e076cd64686dfd16ae0568fafc1437140..ba531fcd90df266d8d0c2de907fefe99 } } diff --git a/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java b/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java -index f921f55e815a4da01828e025881a7a03591c3978..844226e119a9277741972cddf340bceb59b6cda7 100644 +index d051e8c1db6b5c42b8df0be54d9d48ba0e7b0077..c5650a1a5a728a4b632e03852f7c8262b9e5b491 100644 --- a/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java +++ b/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java -@@ -35,6 +35,7 @@ public class DimensionDataStorage { +@@ -36,6 +36,7 @@ public class DimensionDataStorage { } public T computeIfAbsent(SavedData.Factory type, String id) { @@ -21517,7 +21580,7 @@ index f921f55e815a4da01828e025881a7a03591c3978..844226e119a9277741972cddf340bceb T savedData = this.get(type, id); if (savedData != null) { return savedData; -@@ -43,10 +44,12 @@ public class DimensionDataStorage { +@@ -44,10 +45,12 @@ public class DimensionDataStorage { this.set(id, savedData2); return savedData2; } @@ -21525,12 +21588,12 @@ index f921f55e815a4da01828e025881a7a03591c3978..844226e119a9277741972cddf340bceb } @Nullable - public T get(SavedData.Factory type, String id) { + public T get(SavedData.Factory type, String id) { + synchronized (this.cache) { // Folia - make map data thread-safe SavedData savedData = this.cache.get(id); if (savedData == null && !this.cache.containsKey(id)) { savedData = this.readSavedData(type.deserializer(), type.type(), id); -@@ -54,6 +57,7 @@ public class DimensionDataStorage { +@@ -55,6 +58,7 @@ public class DimensionDataStorage { } return (T)savedData; @@ -21538,7 +21601,7 @@ index f921f55e815a4da01828e025881a7a03591c3978..844226e119a9277741972cddf340bceb } @Nullable -@@ -72,7 +76,9 @@ public class DimensionDataStorage { +@@ -73,7 +77,9 @@ public class DimensionDataStorage { } public void set(String id, SavedData state) { @@ -21680,10 +21743,10 @@ index 1d7c663fa0e550bd0cfb9a4b83ccd7e2968666f0..f3df9c9b6cff85565514f990597f3fe5 LevelChunkTicks levelChunkTicks = this.allContainers.get(l); if (levelChunkTicks == null) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index bbc51ebf0dc0801ace9d5e7875fb2fe100b286bc..541915675dd3ad832992360283e3ba1b3cc62e27 100644 +index f4ba1b9adbd0e526421a755fd6c536fe20ffa716..d2c8ad04c59035449dc798a637acc6e809d35fc4 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -311,7 +311,7 @@ public final class CraftServer implements Server { +@@ -312,7 +312,7 @@ public final class CraftServer implements Server { private final CraftPotionBrewer potionBrewer = new CraftPotionBrewer(); // Paper // Paper start - Folia region threading API @@ -21692,7 +21755,7 @@ index bbc51ebf0dc0801ace9d5e7875fb2fe100b286bc..541915675dd3ad832992360283e3ba1b private final io.papermc.paper.threadedregions.scheduler.FoliaAsyncScheduler asyncScheduler = new io.papermc.paper.threadedregions.scheduler.FoliaAsyncScheduler(); private final io.papermc.paper.threadedregions.scheduler.FoliaGlobalRegionScheduler globalRegionScheduler = new io.papermc.paper.threadedregions.scheduler.FoliaGlobalRegionScheduler(); -@@ -379,6 +379,12 @@ public final class CraftServer implements Server { +@@ -380,6 +380,12 @@ public final class CraftServer implements Server { return io.papermc.paper.util.TickThread.isTickThreadFor(((org.bukkit.craftbukkit.entity.CraftEntity) entity).getHandleRaw()); } // Paper end - Folia reagion threading API @@ -21705,7 +21768,7 @@ index bbc51ebf0dc0801ace9d5e7875fb2fe100b286bc..541915675dd3ad832992360283e3ba1b static { ConfigurationSerialization.registerClass(CraftOfflinePlayer.class); -@@ -963,6 +969,9 @@ public final class CraftServer implements Server { +@@ -958,6 +964,9 @@ public final class CraftServer implements Server { // NOTE: Should only be called from DedicatedServer.ah() public boolean dispatchServerCommand(CommandSender sender, ConsoleInput serverCommand) { @@ -21715,7 +21778,7 @@ index bbc51ebf0dc0801ace9d5e7875fb2fe100b286bc..541915675dd3ad832992360283e3ba1b if (sender instanceof Conversable) { Conversable conversable = (Conversable) sender; -@@ -982,12 +991,44 @@ public final class CraftServer implements Server { +@@ -977,12 +986,44 @@ public final class CraftServer implements Server { } } @@ -21760,7 +21823,7 @@ index bbc51ebf0dc0801ace9d5e7875fb2fe100b286bc..541915675dd3ad832992360283e3ba1b if (this.commandMap.dispatch(sender, commandLine)) { return true; } -@@ -3171,7 +3212,7 @@ public final class CraftServer implements Server { +@@ -3203,7 +3244,7 @@ public final class CraftServer implements Server { @Override public int getCurrentTick() { @@ -21770,10 +21833,10 @@ index bbc51ebf0dc0801ace9d5e7875fb2fe100b286bc..541915675dd3ad832992360283e3ba1b @Override diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb80dd15c5 100644 +index e1fad381b861471a17529c246bb8a4a9c7646420..a0eeba6f3b55e5fc0f5f92a1b7bee4f721910f63 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -184,7 +184,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -187,7 +187,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public int getTickableTileEntityCount() { @@ -21782,7 +21845,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb } @Override -@@ -240,7 +240,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -249,7 +249,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { // Paper start - per world spawn limits for (SpawnCategory spawnCategory : SpawnCategory.values()) { if (CraftSpawnCategory.isValidForLimits(spawnCategory)) { @@ -21791,7 +21854,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb } } // Paper end -@@ -327,6 +327,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -336,6 +336,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public Chunk getChunkAt(int x, int z) { @@ -21799,7 +21862,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb warnUnsafeChunk("getting a faraway chunk", x, z); // Paper // Paper start - add ticket to hold chunk for a little while longer if plugin accesses it net.minecraft.world.level.chunk.LevelChunk chunk = this.world.getChunkSource().getChunkAtIfLoadedImmediately(x, z); -@@ -350,7 +351,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -359,7 +360,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { // Paper start private void addTicket(int x, int z) { @@ -21808,7 +21871,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb } // Paper end -@@ -369,10 +370,10 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -378,10 +379,10 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public boolean isChunkGenerated(int x, int z) { // Paper start - Fix this method @@ -21821,7 +21884,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb } ChunkAccess chunk = world.getChunkSource().getChunkAtImmediately(x, z); if (chunk == null) { -@@ -426,7 +427,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -435,7 +436,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { } private boolean unloadChunk0(int x, int z, boolean save) { @@ -21830,7 +21893,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb if (!this.isChunkLoaded(x, z)) { return true; } -@@ -441,7 +442,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -450,7 +451,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public boolean regenerateChunk(int x, int z) { @@ -21839,7 +21902,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb warnUnsafeChunk("regenerating a faraway chunk", x, z); // Paper // Paper start - implement regenerateChunk method final ServerLevel serverLevel = this.world; -@@ -502,6 +503,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -511,6 +512,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public boolean refreshChunk(int x, int z) { @@ -21847,7 +21910,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb ChunkHolder playerChunk = this.world.getChunkSource().chunkMap.getVisibleChunkIfPresent(ChunkPos.asLong(x, z)); if (playerChunk == null) return false; -@@ -537,7 +539,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -546,7 +548,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public boolean loadChunk(int x, int z, boolean generate) { @@ -21856,7 +21919,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb warnUnsafeChunk("loading a faraway chunk", x, z); // Paper // Paper start - Optimize this method ChunkPos chunkPos = new ChunkPos(x, z); -@@ -609,7 +611,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -618,7 +620,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { DistanceManager chunkDistanceManager = this.world.getChunkSource().chunkMap.distanceManager; if (chunkDistanceManager.addRegionTicketAtDistance(TicketType.PLUGIN_TICKET, new ChunkPos(x, z), 2, plugin)) { // keep in-line with force loading, add at level 31 @@ -21865,7 +21928,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb return true; } -@@ -800,13 +802,15 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -809,13 +811,15 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public boolean generateTree(Location loc, TreeType type, BlockChangeDelegate delegate) { @@ -21886,7 +21949,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb BlockPos position = ((CraftBlockState) blockstate).getPosition(); net.minecraft.world.level.block.state.BlockState oldBlock = this.world.getBlockState(position); int flag = ((CraftBlockState) blockstate).getFlag(); -@@ -814,10 +818,10 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -823,10 +827,10 @@ public class CraftWorld extends CraftRegionAccessor implements World { net.minecraft.world.level.block.state.BlockState newBlock = this.world.getBlockState(position); this.world.notifyAndUpdatePhysics(position, null, oldBlock, newBlock, newBlock, flag, 512); } @@ -21899,7 +21962,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb return false; } } -@@ -851,6 +855,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -860,6 +864,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void setTime(long time) { @@ -21907,7 +21970,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb long margin = (time - this.getFullTime()) % 24000; if (margin < 0) margin += 24000; this.setFullTime(this.getFullTime() + margin); -@@ -863,6 +868,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -872,6 +877,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void setFullTime(long time) { @@ -21915,7 +21978,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb // Notify anyone who's listening TimeSkipEvent event = new TimeSkipEvent(this, TimeSkipEvent.SkipReason.CUSTOM, time - this.world.getDayTime()); this.server.getPluginManager().callEvent(event); -@@ -890,7 +896,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -899,7 +905,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public long getGameTime() { @@ -21924,7 +21987,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb } @Override -@@ -910,11 +916,13 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -919,11 +925,13 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public boolean createExplosion(double x, double y, double z, float power, boolean setFire, boolean breakBlocks, Entity source) { @@ -21938,7 +22001,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb return !world.explode(source != null ? ((org.bukkit.craftbukkit.entity.CraftEntity) source).getHandle() : null, loc.getX(), loc.getY(), loc.getZ(), power, setFire, breakBlocks ? net.minecraft.world.level.Level.ExplosionInteraction.MOB : net.minecraft.world.level.Level.ExplosionInteraction.NONE).wasCanceled; } // Paper end -@@ -984,6 +992,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -993,6 +1001,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public int getHighestBlockYAt(int x, int z, org.bukkit.HeightMap heightMap) { @@ -21946,7 +22009,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb warnUnsafeChunk("getting a faraway chunk", x >> 4, z >> 4); // Paper // Transient load for this tick return this.world.getChunk(x >> 4, z >> 4).getHeight(CraftHeightMap.toNMS(heightMap), x, z); -@@ -1014,6 +1023,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1023,6 +1032,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void setBiome(int x, int y, int z, Holder bb) { BlockPos pos = new BlockPos(x, 0, z); @@ -21954,7 +22017,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb if (this.world.hasChunkAt(pos)) { net.minecraft.world.level.chunk.LevelChunk chunk = this.world.getChunkAt(pos); -@@ -1309,6 +1319,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1323,6 +1333,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void setStorm(boolean hasStorm) { @@ -21962,7 +22025,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb this.world.serverLevelData.setRaining(hasStorm, org.bukkit.event.weather.WeatherChangeEvent.Cause.PLUGIN); // Paper this.setWeatherDuration(0); // Reset weather duration (legacy behaviour) this.setClearWeatherDuration(0); // Reset clear weather duration (reset "/weather clear" commands) -@@ -1321,6 +1332,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1335,6 +1346,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void setWeatherDuration(int duration) { @@ -21970,7 +22033,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb this.world.serverLevelData.setRainTime(duration); } -@@ -1331,6 +1343,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1345,6 +1357,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void setThundering(boolean thundering) { @@ -21978,7 +22041,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb this.world.serverLevelData.setThundering(thundering, org.bukkit.event.weather.ThunderChangeEvent.Cause.PLUGIN); // Paper this.setThunderDuration(0); // Reset weather duration (legacy behaviour) this.setClearWeatherDuration(0); // Reset clear weather duration (reset "/weather clear" commands) -@@ -1343,6 +1356,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1357,6 +1370,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void setThunderDuration(int duration) { @@ -21986,7 +22049,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb this.world.serverLevelData.setThunderTime(duration); } -@@ -1353,6 +1367,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1367,6 +1381,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void setClearWeatherDuration(int duration) { @@ -21994,7 +22057,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb this.world.serverLevelData.setClearWeatherTime(duration); } -@@ -1547,6 +1562,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1561,6 +1576,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void setKeepSpawnInMemory(boolean keepLoaded) { @@ -22002,7 +22065,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb // Paper start - Configurable spawn radius if (keepLoaded == this.world.keepSpawnInMemory) { // do nothing, nothing has changed -@@ -1625,6 +1641,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1639,6 +1655,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void setHardcore(boolean hardcore) { @@ -22010,7 +22073,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb this.world.serverLevelData.settings.hardcore = hardcore; } -@@ -1637,6 +1654,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1651,6 +1668,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override @Deprecated public void setTicksPerAnimalSpawns(int ticksPerAnimalSpawns) { @@ -22018,7 +22081,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb this.setTicksPerSpawns(SpawnCategory.ANIMAL, ticksPerAnimalSpawns); } -@@ -1649,6 +1667,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1663,6 +1681,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override @Deprecated public void setTicksPerMonsterSpawns(int ticksPerMonsterSpawns) { @@ -22026,7 +22089,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb this.setTicksPerSpawns(SpawnCategory.MONSTER, ticksPerMonsterSpawns); } -@@ -1661,6 +1680,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1675,6 +1694,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override @Deprecated public void setTicksPerWaterSpawns(int ticksPerWaterSpawns) { @@ -22034,7 +22097,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb this.setTicksPerSpawns(SpawnCategory.WATER_ANIMAL, ticksPerWaterSpawns); } -@@ -1673,6 +1693,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1687,6 +1707,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override @Deprecated public void setTicksPerWaterAmbientSpawns(int ticksPerWaterAmbientSpawns) { @@ -22042,7 +22105,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb this.setTicksPerSpawns(SpawnCategory.WATER_AMBIENT, ticksPerWaterAmbientSpawns); } -@@ -1685,6 +1706,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1699,6 +1720,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override @Deprecated public void setTicksPerWaterUndergroundCreatureSpawns(int ticksPerWaterUndergroundCreatureSpawns) { @@ -22050,7 +22113,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb this.setTicksPerSpawns(SpawnCategory.WATER_UNDERGROUND_CREATURE, ticksPerWaterUndergroundCreatureSpawns); } -@@ -1697,11 +1719,13 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1711,11 +1733,13 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override @Deprecated public void setTicksPerAmbientSpawns(int ticksPerAmbientSpawns) { @@ -22064,7 +22127,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb Preconditions.checkArgument(spawnCategory != null, "SpawnCategory cannot be null"); Preconditions.checkArgument(CraftSpawnCategory.isValidForLimits(spawnCategory), "SpawnCategory.%s are not supported", spawnCategory); -@@ -1718,21 +1742,25 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1732,21 +1756,25 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void setMetadata(String metadataKey, MetadataValue newMetadataValue) { @@ -22090,7 +22153,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb this.server.getWorldMetadata().removeMetadata(this, metadataKey, owningPlugin); } -@@ -1745,6 +1773,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1759,6 +1787,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override @Deprecated public void setMonsterSpawnLimit(int limit) { @@ -22098,7 +22161,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb this.setSpawnLimit(SpawnCategory.MONSTER, limit); } -@@ -1757,6 +1786,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1771,6 +1800,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override @Deprecated public void setAnimalSpawnLimit(int limit) { @@ -22106,7 +22169,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb this.setSpawnLimit(SpawnCategory.ANIMAL, limit); } -@@ -1769,6 +1799,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1783,6 +1813,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override @Deprecated public void setWaterAnimalSpawnLimit(int limit) { @@ -22114,7 +22177,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb this.setSpawnLimit(SpawnCategory.WATER_ANIMAL, limit); } -@@ -1781,6 +1812,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1795,6 +1826,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override @Deprecated public void setWaterAmbientSpawnLimit(int limit) { @@ -22122,7 +22185,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb this.setSpawnLimit(SpawnCategory.WATER_AMBIENT, limit); } -@@ -1793,6 +1825,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1807,6 +1839,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override @Deprecated public void setWaterUndergroundCreatureSpawnLimit(int limit) { @@ -22130,7 +22193,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb this.setSpawnLimit(SpawnCategory.WATER_UNDERGROUND_CREATURE, limit); } -@@ -1805,6 +1838,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1819,6 +1852,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override @Deprecated public void setAmbientSpawnLimit(int limit) { @@ -22138,7 +22201,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb this.setSpawnLimit(SpawnCategory.AMBIENT, limit); } -@@ -1827,6 +1861,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1841,6 +1875,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void setSpawnLimit(SpawnCategory spawnCategory, int limit) { @@ -22146,25 +22209,25 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb Preconditions.checkArgument(spawnCategory != null, "SpawnCategory cannot be null"); Preconditions.checkArgument(CraftSpawnCategory.isValidForLimits(spawnCategory), "SpawnCategory.%s are not supported", spawnCategory); -@@ -1881,7 +1916,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1920,7 +1955,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { if (!(entity instanceof CraftEntity craftEntity) || entity.getWorld() != this || sound == null || category == null) return; - ClientboundSoundEntityPacket packet = new ClientboundSoundEntityPacket(CraftSound.bukkitToMinecraftHolder(sound), net.minecraft.sounds.SoundSource.valueOf(category.name()), craftEntity.getHandle(), volume, pitch, this.getHandle().getRandom().nextLong()); + ClientboundSoundEntityPacket packet = new ClientboundSoundEntityPacket(CraftSound.bukkitToMinecraftHolder(sound), net.minecraft.sounds.SoundSource.valueOf(category.name()), craftEntity.getHandle(), volume, pitch, seed); - ChunkMap.TrackedEntity entityTracker = this.getHandle().getChunkSource().chunkMap.entityMap.get(entity.getEntityId()); + ChunkMap.TrackedEntity entityTracker = ((CraftEntity) entity).getHandle().tracker; // Folia - region threading if (entityTracker != null) { entityTracker.broadcastAndSend(packet); } -@@ -1892,7 +1927,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1931,7 +1966,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { if (!(entity instanceof CraftEntity craftEntity) || entity.getWorld() != this || sound == null || category == null) return; - ClientboundSoundEntityPacket packet = new ClientboundSoundEntityPacket(Holder.direct(SoundEvent.createVariableRangeEvent(new ResourceLocation(sound))), net.minecraft.sounds.SoundSource.valueOf(category.name()), craftEntity.getHandle(), volume, pitch, this.getHandle().getRandom().nextLong()); + ClientboundSoundEntityPacket packet = new ClientboundSoundEntityPacket(Holder.direct(SoundEvent.createVariableRangeEvent(new ResourceLocation(sound))), net.minecraft.sounds.SoundSource.valueOf(category.name()), craftEntity.getHandle(), volume, pitch, seed); - ChunkMap.TrackedEntity entityTracker = this.getHandle().getChunkSource().chunkMap.entityMap.get(entity.getEntityId()); + ChunkMap.TrackedEntity entityTracker = ((CraftEntity)entity).getHandle().tracker; // Folia - region threading if (entityTracker != null) { entityTracker.broadcastAndSend(packet); } -@@ -1978,6 +2013,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -2017,6 +2052,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public boolean setGameRuleValue(String rule, String value) { @@ -22172,7 +22235,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb // No null values allowed if (rule == null || value == null) return false; -@@ -2020,6 +2056,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -2059,6 +2095,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public boolean setGameRule(GameRule rule, T newValue) { @@ -22180,7 +22243,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb Preconditions.checkArgument(rule != null, "GameRule cannot be null"); Preconditions.checkArgument(newValue != null, "GameRule value cannot be null"); -@@ -2272,6 +2309,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -2311,6 +2348,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void sendGameEvent(Entity sourceEntity, org.bukkit.GameEvent gameEvent, Vector position) { @@ -22193,7 +22256,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb getHandle().gameEvent(sourceEntity != null ? ((CraftEntity) sourceEntity).getHandle(): null, net.minecraft.core.registries.BuiltInRegistries.GAME_EVENT.get(org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(gameEvent.getKey())), org.bukkit.craftbukkit.util.CraftVector.toBlockPos(position)); } // Paper end -@@ -2426,7 +2469,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -2465,7 +2508,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { // Paper start public java.util.concurrent.CompletableFuture getChunkAtAsync(int x, int z, boolean gen, boolean urgent) { warnUnsafeChunk("getting a faraway chunk async", x, z); // Paper @@ -22202,7 +22265,7 @@ index c3060d1d4d0caf369c6ab516cb424f45eb851019..bcbf7ba7c687ecaa530d4de3af45ebeb net.minecraft.world.level.chunk.LevelChunk immediate = this.world.getChunkSource().getChunkAtIfLoadedImmediately(x, z); if (immediate != null) { return java.util.concurrent.CompletableFuture.completedFuture(new CraftChunk(immediate)); -@@ -2443,7 +2486,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -2482,7 +2525,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { java.util.concurrent.CompletableFuture ret = new java.util.concurrent.CompletableFuture<>(); io.papermc.paper.chunk.system.ChunkSystem.scheduleChunkLoad(this.getHandle(), x, z, gen, ChunkStatus.FULL, true, priority, (c) -> { @@ -22224,10 +22287,10 @@ index a8760f015b9ee3ee408c3b9220266eb76b313ba0..fadf10c6a7fabde2c13f3aff00739a21 tileentitybeehive.addOccupantWithPresetTicks(entitybee, false, random.nextInt(599)); } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -index bec8e6b62dba2bd0e4e85a7d1fb51287384f1290..6c91ee8b61cca34bd9e251076d8e9881729526da 100644 +index e5506a7d074a9f89d41f4d5d7549a458779bef20..1849c13df615dc736c22cbb58d92ddaac51db2e4 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -@@ -74,6 +74,11 @@ public class CraftBlock implements Block { +@@ -75,6 +75,11 @@ public class CraftBlock implements Block { } public net.minecraft.world.level.block.state.BlockState getNMS() { @@ -22239,7 +22302,7 @@ index bec8e6b62dba2bd0e4e85a7d1fb51287384f1290..6c91ee8b61cca34bd9e251076d8e9881 return this.world.getBlockState(this.position); } -@@ -150,6 +155,11 @@ public class CraftBlock implements Block { +@@ -151,6 +156,11 @@ public class CraftBlock implements Block { } private void setData(final byte data, int flag) { @@ -22251,7 +22314,7 @@ index bec8e6b62dba2bd0e4e85a7d1fb51287384f1290..6c91ee8b61cca34bd9e251076d8e9881 this.world.setBlock(this.position, CraftMagicNumbers.getBlock(this.getType(), data), flag); } -@@ -191,6 +201,11 @@ public class CraftBlock implements Block { +@@ -192,6 +202,11 @@ public class CraftBlock implements Block { } public static boolean setTypeAndData(LevelAccessor world, BlockPos position, net.minecraft.world.level.block.state.BlockState old, net.minecraft.world.level.block.state.BlockState blockData, boolean applyPhysics) { @@ -22263,7 +22326,7 @@ index bec8e6b62dba2bd0e4e85a7d1fb51287384f1290..6c91ee8b61cca34bd9e251076d8e9881 // SPIGOT-611: need to do this to prevent glitchiness. Easier to handle this here (like /setblock) than to fix weirdness in tile entity cleanup if (old.hasBlockEntity() && blockData.getBlock() != old.getBlock()) { // SPIGOT-3725 remove old tile entity if block changes // SPIGOT-4612: faster - just clear tile -@@ -336,18 +351,33 @@ public class CraftBlock implements Block { +@@ -337,18 +352,33 @@ public class CraftBlock implements Block { @Override public Biome getBiome() { @@ -22297,7 +22360,7 @@ index bec8e6b62dba2bd0e4e85a7d1fb51287384f1290..6c91ee8b61cca34bd9e251076d8e9881 this.getWorld().setBiome(this.getX(), this.getY(), this.getZ(), bio); } -@@ -395,6 +425,11 @@ public class CraftBlock implements Block { +@@ -396,6 +426,11 @@ public class CraftBlock implements Block { @Override public boolean isBlockFaceIndirectlyPowered(BlockFace face) { @@ -22309,7 +22372,7 @@ index bec8e6b62dba2bd0e4e85a7d1fb51287384f1290..6c91ee8b61cca34bd9e251076d8e9881 int power = this.world.getMinecraftWorld().getSignal(this.position, CraftBlock.blockFaceToNotch(face)); Block relative = this.getRelative(face); -@@ -407,6 +442,11 @@ public class CraftBlock implements Block { +@@ -408,6 +443,11 @@ public class CraftBlock implements Block { @Override public int getBlockPower(BlockFace face) { @@ -22321,7 +22384,7 @@ index bec8e6b62dba2bd0e4e85a7d1fb51287384f1290..6c91ee8b61cca34bd9e251076d8e9881 int power = 0; net.minecraft.world.level.Level world = this.world.getMinecraftWorld(); int x = this.getX(); -@@ -493,6 +533,11 @@ public class CraftBlock implements Block { +@@ -494,6 +534,11 @@ public class CraftBlock implements Block { @Override public boolean breakNaturally(ItemStack item, boolean triggerEffect, boolean dropExperience) { @@ -22333,7 +22396,7 @@ index bec8e6b62dba2bd0e4e85a7d1fb51287384f1290..6c91ee8b61cca34bd9e251076d8e9881 // Paper end // Order matters here, need to drop before setting to air so skulls can get their data net.minecraft.world.level.block.state.BlockState iblockdata = this.getNMS(); -@@ -536,21 +581,27 @@ public class CraftBlock implements Block { +@@ -537,21 +582,27 @@ public class CraftBlock implements Block { @Override public boolean applyBoneMeal(BlockFace face) { @@ -22368,7 +22431,7 @@ index bec8e6b62dba2bd0e4e85a7d1fb51287384f1290..6c91ee8b61cca34bd9e251076d8e9881 StructureGrowEvent structureEvent = null; if (treeType != null) { -@@ -637,6 +688,11 @@ public class CraftBlock implements Block { +@@ -638,6 +689,11 @@ public class CraftBlock implements Block { @Override public RayTraceResult rayTrace(Location start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode) { @@ -22380,7 +22443,7 @@ index bec8e6b62dba2bd0e4e85a7d1fb51287384f1290..6c91ee8b61cca34bd9e251076d8e9881 Preconditions.checkArgument(start != null, "Location start cannot be null"); Preconditions.checkArgument(this.getWorld().equals(start.getWorld()), "Location start cannot be a different world"); start.checkFinite(); -@@ -678,6 +734,11 @@ public class CraftBlock implements Block { +@@ -679,6 +735,11 @@ public class CraftBlock implements Block { @Override public boolean canPlace(BlockData data) { @@ -22392,7 +22455,7 @@ index bec8e6b62dba2bd0e4e85a7d1fb51287384f1290..6c91ee8b61cca34bd9e251076d8e9881 Preconditions.checkArgument(data != null, "BlockData cannot be null"); net.minecraft.world.level.block.state.BlockState iblockdata = ((CraftBlockData) data).getState(); net.minecraft.world.level.Level world = this.world.getMinecraftWorld(); -@@ -712,6 +773,11 @@ public class CraftBlock implements Block { +@@ -713,6 +774,11 @@ public class CraftBlock implements Block { @Override public void tick() { @@ -22404,7 +22467,7 @@ index bec8e6b62dba2bd0e4e85a7d1fb51287384f1290..6c91ee8b61cca34bd9e251076d8e9881 net.minecraft.world.level.block.state.BlockState blockData = this.getNMS(); net.minecraft.server.level.ServerLevel level = this.world.getMinecraftWorld(); -@@ -720,6 +786,11 @@ public class CraftBlock implements Block { +@@ -721,6 +787,11 @@ public class CraftBlock implements Block { @Override public void randomTick() { @@ -22466,10 +22529,10 @@ index 12eeabafbad9da8796dc6fc383b732cf75bb7ddb..6ede423639c8e2012da897f517e8f7c9 List offers = waitable.get(); if (offers == null) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 0e6c7284b9aee6c5f2454a3a095ebf349f887740..690e57b55adb53d56d874cbddec6226a515f43a2 100644 +index aa4dbf91cf6da329fdcacbde98bb870eb48e8f5c..cd29fa29fa65060c21c715bd756c5a35429eeb96 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -581,6 +581,11 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -588,6 +588,11 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { @Override public boolean teleport(Location location, TeleportCause cause, io.papermc.paper.entity.TeleportFlag... flags) { @@ -22481,7 +22544,7 @@ index 0e6c7284b9aee6c5f2454a3a095ebf349f887740..690e57b55adb53d56d874cbddec6226a // Paper end Preconditions.checkArgument(location != null, "location cannot be null"); location.checkFinite(); -@@ -1035,7 +1040,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -1054,7 +1059,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { ImmutableSet.Builder players = ImmutableSet.builder(); ServerLevel world = ((CraftWorld) this.getWorld()).getHandle(); @@ -22490,7 +22553,7 @@ index 0e6c7284b9aee6c5f2454a3a095ebf349f887740..690e57b55adb53d56d874cbddec6226a if (entityTracker != null) { for (ServerPlayerConnection connection : entityTracker.seenBy) { -@@ -1293,7 +1298,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -1348,7 +1353,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { } ServerLevel world = ((CraftWorld) this.getWorld()).getHandle(); @@ -22499,7 +22562,7 @@ index 0e6c7284b9aee6c5f2454a3a095ebf349f887740..690e57b55adb53d56d874cbddec6226a if (entityTracker == null) { return; -@@ -1361,30 +1366,43 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -1416,30 +1421,43 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { Preconditions.checkArgument(location != null, "location"); location.checkFinite(); Location locationClone = location.clone(); // clone so we don't need to worry about mutations after this call. @@ -22564,10 +22627,10 @@ index 0e6c7284b9aee6c5f2454a3a095ebf349f887740..690e57b55adb53d56d874cbddec6226a @Override diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 83aaf3e6e377d731ce02f779f80b7bf5db46f89f..249887106315ed0625b08bc8b2a74404cf0a418b 100644 +index fd84786f3e72875e79df46416f47f3403876cef3..374a845acc6b12eb82af4282d52e22f1291f77f7 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -591,7 +591,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -599,7 +599,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void kickPlayer(String message) { @@ -22576,7 +22639,7 @@ index 83aaf3e6e377d731ce02f779f80b7bf5db46f89f..249887106315ed0625b08bc8b2a74404 if (this.getHandle().connection == null) return; this.getHandle().connection.disconnect(message == null ? "" : message, org.bukkit.event.player.PlayerKickEvent.Cause.PLUGIN); // Paper - kick event cause -@@ -1298,6 +1298,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1322,6 +1322,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public boolean teleport(Location location, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause cause, io.papermc.paper.entity.TeleportFlag... flags) { @@ -22588,7 +22651,7 @@ index 83aaf3e6e377d731ce02f779f80b7bf5db46f89f..249887106315ed0625b08bc8b2a74404 java.util.Set relativeArguments; java.util.Set allFlags; if (flags.length == 0) { -@@ -1880,7 +1885,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1904,7 +1909,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { private void unregisterEntity(Entity other) { // Paper end ChunkMap tracker = ((ServerLevel) this.getHandle().level()).getChunkSource().chunkMap; @@ -22597,7 +22660,7 @@ index 83aaf3e6e377d731ce02f779f80b7bf5db46f89f..249887106315ed0625b08bc8b2a74404 if (entry != null) { entry.removePlayer(this.getHandle()); } -@@ -1977,7 +1982,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2001,7 +2006,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { if (original != null) otherPlayer.setUUID(original); // Paper - uuid override } @@ -22607,7 +22670,7 @@ index 83aaf3e6e377d731ce02f779f80b7bf5db46f89f..249887106315ed0625b08bc8b2a74404 entry.updatePlayer(this.getHandle()); } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 5dc160b743534665c6b3efb10b10f7c36e2da5ab..606551330859fd423b31d246bc14891d1236ba42 100644 +index f5a5ae30dfba21d5cf3990c046cfe41547e8a87a..43ed483add05ddeafdc5a3595a212aaeab128b26 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -246,8 +246,8 @@ import org.bukkit.potion.PotionEffect; @@ -22639,7 +22702,7 @@ index 5dc160b743534665c6b3efb10b10f7c36e2da5ab..606551330859fd423b31d246bc14891d Bukkit.getPluginManager().callEvent(event); if (!event.isCancelled()) { -@@ -1047,8 +1047,8 @@ public class CraftEventFactory { +@@ -1059,8 +1059,8 @@ public class CraftEventFactory { private static EntityDamageEvent handleEntityDamageEvent(Entity entity, DamageSource source, Map modifiers, Map> modifierFunctions, boolean cancelled) { if (source.is(DamageTypeTags.IS_EXPLOSION)) { DamageCause damageCause; @@ -22650,7 +22713,7 @@ index 5dc160b743534665c6b3efb10b10f7c36e2da5ab..606551330859fd423b31d246bc14891d EntityDamageEvent event; if (damager == null) { event = new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.BLOCK_EXPLOSION, modifiers, modifierFunctions, source.explodedBlockState); // Paper - handle block state in damage -@@ -1109,13 +1109,13 @@ public class CraftEventFactory { +@@ -1121,13 +1121,13 @@ public class CraftEventFactory { } return event; } else if (source.is(DamageTypes.LAVA)) { @@ -22668,7 +22731,7 @@ index 5dc160b743534665c6b3efb10b10f7c36e2da5ab..606551330859fd423b31d246bc14891d if (!event.isCancelled()) { event.getEntity().setLastDamageCause(event); -@@ -1123,9 +1123,9 @@ public class CraftEventFactory { +@@ -1135,9 +1135,9 @@ public class CraftEventFactory { entity.lastDamageCancelled = true; // SPIGOT-5339, SPIGOT-6252, SPIGOT-6777: Keep track if the event was canceled } return event; @@ -22680,7 +22743,7 @@ index 5dc160b743534665c6b3efb10b10f7c36e2da5ab..606551330859fd423b31d246bc14891d if (source.is(DamageTypes.CACTUS) || source.is(DamageTypes.SWEET_BERRY_BUSH) || source.is(DamageTypes.STALAGMITE) || source.is(DamageTypes.FALLING_STALACTITE) || source.is(DamageTypes.FALLING_ANVIL)) { cause = DamageCause.CONTACT; } else if (source.is(DamageTypes.HOT_FLOOR)) { -@@ -1140,9 +1140,9 @@ public class CraftEventFactory { +@@ -1152,9 +1152,9 @@ public class CraftEventFactory { EntityDamageEvent event = new EntityDamageByBlockEvent(damager, entity.getBukkitEntity(), cause, modifiers, modifierFunctions); event.setCancelled(cancelled); @@ -22692,7 +22755,7 @@ index 5dc160b743534665c6b3efb10b10f7c36e2da5ab..606551330859fd423b31d246bc14891d if (!event.isCancelled()) { event.getEntity().setLastDamageCause(event); -@@ -1150,10 +1150,10 @@ public class CraftEventFactory { +@@ -1162,10 +1162,10 @@ public class CraftEventFactory { entity.lastDamageCancelled = true; // SPIGOT-5339, SPIGOT-6252, SPIGOT-6777: Keep track if the event was canceled } return event; @@ -22706,7 +22769,7 @@ index 5dc160b743534665c6b3efb10b10f7c36e2da5ab..606551330859fd423b31d246bc14891d if (source.is(DamageTypes.FALLING_STALACTITE) || source.is(DamageTypes.FALLING_BLOCK) || source.is(DamageTypes.FALLING_ANVIL)) { cause = DamageCause.FALLING_BLOCK; } else if (damager instanceof LightningStrike) { -@@ -2123,7 +2123,7 @@ public class CraftEventFactory { +@@ -2134,7 +2134,7 @@ public class CraftEventFactory { CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemStack.copyWithCount(1)); org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(to.getX(), to.getY(), to.getZ())); @@ -22716,7 +22779,7 @@ index 5dc160b743534665c6b3efb10b10f7c36e2da5ab..606551330859fd423b31d246bc14891d return itemStack; } diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java -index 3ceb5d83be20183da907915f70ba9e64369373a9..b23e43f7ac22bc106a0bcde4a8bca9ecba1a9ae4 100644 +index 700932b65e4fda560d684b0aa079bcee3923f73e..2c3e1b420303a3c3a9315983fbc7e47423f7d9e4 100644 --- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java +++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java @@ -530,6 +530,7 @@ public class CraftScheduler implements BukkitScheduler { @@ -22728,10 +22791,10 @@ index 3ceb5d83be20183da907915f70ba9e64369373a9..b23e43f7ac22bc106a0bcde4a8bca9ec if (!this.isAsyncScheduler && !task.isSync()) { this.asyncScheduler.handle(task, delay); diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 548c77592a3520e8053483644eba805079a14f1a..73c395cd5fd3dc07640cdc06e174cd99de43df4c 100644 +index ec2396f0e5d62b10450eaa7239a8c5479638b3c3..baf5605f31d3c24441da7e2fe13c923ba6ae1199 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -380,6 +380,12 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -377,6 +377,12 @@ public final class CraftMagicNumbers implements UnsafeValues { String minimumVersion = MinecraftServer.getServer().server.minimumAPI; int minimumIndex = CraftMagicNumbers.SUPPORTED_API.indexOf(minimumVersion); @@ -22745,7 +22808,7 @@ index 548c77592a3520e8053483644eba805079a14f1a..73c395cd5fd3dc07640cdc06e174cd99 int pluginIndex = CraftMagicNumbers.SUPPORTED_API.indexOf(pdf.getAPIVersion()); diff --git a/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java b/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java -index cbedb6f002bc01daa16d349421c4ef04d4bcbcb2..2d708bb11f841bb265d12a025dbaa657b0b4d08a 100644 +index a650411e3fa7e2a045ac55502c77028be348acf1..b5760a68ee09494fa5c522f5785c23f8c46cd687 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java +++ b/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java @@ -69,6 +69,13 @@ public abstract class DelegatedGeneratorAccess implements WorldGenLevel { @@ -22948,10 +23011,10 @@ index 68602dfb171d47e47fd0710b4324013ef05214d0..2d75cefc69ea1da96a99370aef3df7bd public static int playerSample; diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java -index f9b8e2bc039f1a37e47f84909c8785f3ef530284..315b860807bed537f8dbd85c9a053e39216e7b71 100644 +index 1cf6d4f854d89c515e48e1fb365eb95ff9340765..efe5b848a8e3645cae10c435196c8189b7422f45 100644 --- a/src/main/java/org/spigotmc/SpigotWorldConfig.java +++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java -@@ -433,7 +433,7 @@ public class SpigotWorldConfig +@@ -435,7 +435,7 @@ public class SpigotWorldConfig this.otherMultiplier = (float) this.getDouble( "hunger.other-multiplier", 0.0 ); } diff --git a/patches/server/0004-Max-pending-logins.patch b/patches/server/0004-Max-pending-logins.patch index 1339701..63f3146 100644 --- a/patches/server/0004-Max-pending-logins.patch +++ b/patches/server/0004-Max-pending-logins.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Max pending logins Should help the floodgates on launch diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index 6f483c6581daeaf68f85e3b730d31c5b7a6ae001..f7c2d6d82ee1b5975cd114934b7beaec3d5d490d 100644 +index d0f7434164f6241ec81c990c7a127f504e019291..8586df59afd0af51721a0950c7bf4582092417fc 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -@@ -88,7 +88,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, +@@ -89,7 +89,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, if (this.server.getPlayerList().pushPendingJoin(name, uniqueId, this.connection)) { // Folia end - region threading - rewrite login process this.verifyLoginAndFinishConnectionSetup((GameProfile) Objects.requireNonNull(this.authenticatedProfile)); @@ -19,10 +19,10 @@ index 6f483c6581daeaf68f85e3b730d31c5b7a6ae001..f7c2d6d82ee1b5975cd114934b7beaec if (this.state == ServerLoginPacketListenerImpl.State.WAITING_FOR_DUPE_DISCONNECT && !this.isPlayerAlreadyInWorld((GameProfile) Objects.requireNonNull(this.authenticatedProfile))) { diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 6cce2a9bc9beeeef25b7bacd2ad307ed3ae44432..41ba8950b3aada5eea55a0db841c6b9291262bf2 100644 +index 0fa69640a699e1c33cb307366b0335ac9bac4282..bc31d4dfd6fca354c093f552901a59e5b83c92d7 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -173,6 +173,17 @@ public abstract class PlayerList { +@@ -171,6 +171,17 @@ public abstract class PlayerList { conflictingId = this.connectionById.get(byId); if (conflictingName == null && conflictingId == null) { diff --git a/patches/server/0006-Make-CraftEntity-getHandle-and-overrides-perform-thr.patch b/patches/server/0006-Make-CraftEntity-getHandle-and-overrides-perform-thr.patch index 00ca31c..044ac10 100644 --- a/patches/server/0006-Make-CraftEntity-getHandle-and-overrides-perform-thr.patch +++ b/patches/server/0006-Make-CraftEntity-getHandle-and-overrides-perform-thr.patch @@ -29,10 +29,10 @@ index 41bf71d116ffc5431586ce54abba7f8def6c1dcf..519da6886613b8460e989767b1a21e31 } diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index dd18591d7928ab04f6f7c09aa89a26ccbe20c323..385d5bc08928dd990b690b926e174af86f178c64 100644 +index 9f38cec134dfd476d0a8d56b628238d2d27baf83..65ae803da6fa395c9ad031460fc76077da62aeec 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -2863,6 +2863,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -2918,6 +2918,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S if (!force && (!this.canRide(entity) || !entity.canAddPassenger(this))) { return false; } else { @@ -40,7 +40,7 @@ index dd18591d7928ab04f6f7c09aa89a26ccbe20c323..385d5bc08928dd990b690b926e174af8 // CraftBukkit start if (entity.getBukkitEntity() instanceof Vehicle && this.getBukkitEntity() instanceof LivingEntity) { VehicleEnterEvent event = new VehicleEnterEvent((Vehicle) entity.getBukkitEntity(), this.getBukkitEntity()); -@@ -2884,6 +2885,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -2939,6 +2940,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S if (event.isCancelled()) { return false; } @@ -48,7 +48,7 @@ index dd18591d7928ab04f6f7c09aa89a26ccbe20c323..385d5bc08928dd990b690b926e174af8 // Spigot end if (this.isPassenger()) { this.stopRiding(); -@@ -2962,6 +2964,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3017,6 +3019,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S throw new IllegalStateException("Use x.stopRiding(y), not y.removePassenger(x)"); } else { // CraftBukkit start @@ -56,7 +56,7 @@ index dd18591d7928ab04f6f7c09aa89a26ccbe20c323..385d5bc08928dd990b690b926e174af8 CraftEntity craft = (CraftEntity) entity.getBukkitEntity().getVehicle(); Entity orig = craft == null ? null : craft.getHandle(); if (this.getBukkitEntity() instanceof Vehicle && entity.getBukkitEntity() instanceof LivingEntity) { -@@ -2989,6 +2992,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3044,6 +3047,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S if (event.isCancelled()) { return false; } @@ -456,10 +456,10 @@ index 80e571c977db5cdf43bfbfce035f37a3fa325c95..6fafba37dd7128a397ba046be7b33067 } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftCat.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftCat.java -index 6c9531c018be29b5794d047b50007fde1b50b494..cb2f710a48c1e42cf800f657befaac4e2b8a82ff 100644 +index 0ccc20157fb9fdb9c99b942dcb4675db5f928b23..aa9881552e0ba78d844de105184953c487ad426b 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftCat.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftCat.java -@@ -15,8 +15,16 @@ public class CraftCat extends CraftTameableAnimal implements Cat { +@@ -16,8 +16,16 @@ public class CraftCat extends CraftTameableAnimal implements Cat { super(server, entity); } @@ -897,10 +897,10 @@ index d657fd2c507a5b215aeab0a5f3e9c2ee892a27c8..9fc90b162aab15a9cd60b02aba563181 } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 690e57b55adb53d56d874cbddec6226a515f43a2..9f070a9f0894d88688ff50efc3f4dba8188c3885 100644 +index cd29fa29fa65060c21c715bd756c5a35429eeb96..c46d00843f4a1a1c482f18856a846c09eff30293 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -826,7 +826,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -845,7 +845,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { @Override public UUID getUniqueId() { @@ -909,7 +909,7 @@ index 690e57b55adb53d56d874cbddec6226a515f43a2..9f070a9f0894d88688ff50efc3f4dba8 } @Override -@@ -841,6 +841,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -860,6 +860,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { } public Entity getHandle() { @@ -1359,10 +1359,10 @@ index 8746f80d08df5501b32958eb123aa7d814573ddf..c6c6eb55f4649e18beef9832c2ea7b9d } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -index aefb9879b2edadfb4b21d80135d713b9d34c9941..320b69a62a01d54d116115cc6b571ad63558befd 100644 +index 8a1e765363aeb61078fd23980d3856dc680cb05e..98f2be104eb2882f8c841a637ba821d96e0bf6bd 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -@@ -291,8 +291,16 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { +@@ -292,8 +292,16 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { this.mode = mode; } @@ -1464,7 +1464,7 @@ index 63cae1a2e95d8da17c45c4404a8dd0ca6a413c39..f57139f03da9519802ee156f37691d08 } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java -index f444e843535ec68ede0f05e7e7ef182ce872342b..c8fdfb3ee9ad5ca1853ac2ec3a7ff04ce8081dbb 100644 +index 81498941748d646ebe6495f4a7ce6953532144c6..23ff09abb5f99b0cee2375769004c4f709257e39 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java @@ -18,8 +18,16 @@ public class CraftItem extends CraftEntity implements Item { @@ -1590,10 +1590,10 @@ index 70b377c03346cb8573827aeb493f3b6eb8efb1f8..b2e8c26162dd5782a0447cd03ca00fb4 } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index 1992bd985d1beae77b88d71c5fa551a277943fdb..abc18d0e52d1e6ab4d04a9d8b97f91c9d6c4c02e 100644 +index ba2cd9c4cdbd5ddab1300320d7e0ede4d4b7a31a..66edfd724275c06b58d0a4a5fb5e484257850e36 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -417,6 +417,13 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -418,6 +418,13 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { this.getHandle().invulnerableTime = ticks; } @@ -1607,7 +1607,7 @@ index 1992bd985d1beae77b88d71c5fa551a277943fdb..abc18d0e52d1e6ab4d04a9d8b97f91c9 @Override public int getNoActionTicks() { return this.getHandle().getNoActionTime(); -@@ -430,6 +437,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -431,6 +438,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { @Override public net.minecraft.world.entity.LivingEntity getHandle() { @@ -1878,7 +1878,7 @@ index 706c74c832f6893df3797023f68add31139c7d57..80a612f16669e571e336dd6369a968b4 } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java -index 7ee489da5963fd722fc2531fef14911447a16557..f07b07805ce0b168e945c81ae82b690db0ba79e5 100644 +index e5df527d3f0b82327bcd4cb66c12baa439b4cec6..3ca3c62485e5701c76e4fbfac853ed128194e0ce 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java @@ -10,8 +10,16 @@ public class CraftMushroomCow extends CraftCow implements MushroomCow, io.paperm @@ -2130,10 +2130,10 @@ index 2638c341bc02f201f7ab17fdebcdbdf3a7ec05bf..0f5c2d31a2dea13a46ba81e353393633 } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 249887106315ed0625b08bc8b2a74404cf0a418b..6c8f6e26687b557fcdcd65c657d8b35d3fde805e 100644 +index 374a845acc6b12eb82af4282d52e22f1291f77f7..7a8762a35cb47f86c64be00c220a997c8f9f5108 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -611,7 +611,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -619,7 +619,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void kick(net.kyori.adventure.text.Component message, org.bukkit.event.player.PlayerKickEvent.Cause cause) { @@ -2142,7 +2142,7 @@ index 249887106315ed0625b08bc8b2a74404cf0a418b..6c8f6e26687b557fcdcd65c657d8b35d final ServerGamePacketListenerImpl connection = this.getHandle().connection; if (connection != null) { connection.disconnect(message == null ? net.kyori.adventure.text.Component.empty() : message, cause); -@@ -2138,9 +2138,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2162,9 +2162,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return this; } @@ -2160,7 +2160,7 @@ index 249887106315ed0625b08bc8b2a74404cf0a418b..6c8f6e26687b557fcdcd65c657d8b35d } public void setHandle(final ServerPlayer entity) { -@@ -3156,7 +3163,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3162,7 +3169,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { { if ( CraftPlayer.this.getHealth() <= 0 && CraftPlayer.this.isOnline() ) { @@ -2865,7 +2865,7 @@ index 4b3a764114c8372e1549dadeeced26dc7727f2d1..04cbe165b99d348a864da5d342225fc9 } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java -index c8b65210d2416b5a293cb4bcc1b71f56ed365cd7..0e3045647382111066000fc03925596c1d757e6b 100644 +index 8a6af0db8e0aa0cffbf19584be747076c2c8ee44..b7c639a027001a064333fb4e8feb0e049e8cabbd 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java @@ -12,8 +12,16 @@ public class CraftTrident extends CraftArrow implements Trident { diff --git a/patches/server/0007-Disable-mid-tick-task-execution.patch b/patches/server/0007-Disable-mid-tick-task-execution.patch index 13acb65..e803629 100644 --- a/patches/server/0007-Disable-mid-tick-task-execution.patch +++ b/patches/server/0007-Disable-mid-tick-task-execution.patch @@ -10,11 +10,11 @@ the impact from scaling the region threads, but is not a fix to the underlying issue. diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 75d5e7f1b247e27f526a3f76fa7df7aeca4e90ac..5ded3dbc379f199ed735b6ce0ebf6a2e3485f93b 100644 +index 99a086ed2c0d5615a55539a31b8cd8483569e9c0..844424e7488eb42753f50e0e998aebf93c912877 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -2877,6 +2877,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0 && io.papermc.paper.threadedregions.RegionizedServer.getCurrentTick() % autosavePeriod == 0; // Folia - region threading @@ -1428,7 +1428,7 @@ index 5ded3dbc379f199ed735b6ce0ebf6a2e3485f93b..4b189b54c8f326939a7b9ffdfb35edfb try { this.isSaving = true; if (playerSaveInterval > 0) { -@@ -1541,6 +1554,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { // Folia - region threading entityplayer.connection.suspendFlushing(); -@@ -1664,12 +1679,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop iterator = this.level.needsChangeBroadcasting.iterator(); iterator.hasNext();) { ChunkHolder holder = iterator.next(); if (!io.papermc.paper.util.TickThread.isTickThreadFor(holder.newChunkHolder.world, holder.pos)) { -@@ -637,6 +658,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -666,6 +687,7 @@ public class ServerChunkCache extends ChunkSource { iterator.remove(); } } @@ -1629,10 +1629,10 @@ index 4ed40924942bc3252fb1a533190765fbfdb2ba72..b9b1dfe04eda8498f0ceff0aee66489d // Folia end - region threading // Paper end - optimise chunk tick iteration diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 10cf0ffb2cf519f0904dbe709b9042d30d5fd827..724aa1d8147ea2fb5e46d291adacfb7e1f5b5f62 100644 +index 72af30b281f2bb1dd4beee746a1b3f7bebbc7260..8cf413e42d560d90dfcbcb1d61ed410e992a8f4c 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -891,6 +891,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -893,6 +893,7 @@ public class ServerLevel extends Level implements WorldGenLevel { public void tick(BooleanSupplier shouldKeepTicking, io.papermc.paper.threadedregions.TickRegions.TickRegionData region) { // Folia - regionised ticking final io.papermc.paper.threadedregions.RegionizedWorldData regionizedWorldData = this.getCurrentWorldData(); // Folia - regionised ticking @@ -1640,8 +1640,8 @@ index 10cf0ffb2cf519f0904dbe709b9042d30d5fd827..724aa1d8147ea2fb5e46d291adacfb7e ProfilerFiller gameprofilerfiller = this.getProfiler(); regionizedWorldData.setHandlingTick(true); // Folia - regionised ticking -@@ -910,24 +911,34 @@ public class ServerLevel extends Level implements WorldGenLevel { - if (!this.isDebug()) { +@@ -921,9 +922,13 @@ public class ServerLevel extends Level implements WorldGenLevel { + if (!this.isDebug() && flag) { j = regionizedWorldData.getRedstoneGameTime(); // Folia - region threading gameprofilerfiller.push("blockTicks"); + profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.BLOCK_TICK); try { // Folia - profiler @@ -1654,13 +1654,16 @@ index 10cf0ffb2cf519f0904dbe709b9042d30d5fd827..724aa1d8147ea2fb5e46d291adacfb7e gameprofilerfiller.pop(); } this.timings.scheduledBlocks.stopTiming(); // Paper - +@@ -931,18 +936,24 @@ public class ServerLevel extends Level implements WorldGenLevel { gameprofilerfiller.popPush("raid"); - this.timings.raids.startTiming(); // Paper - timings -+ profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.RAIDS_TICK); try { // Folia - profiler - this.raids.tick(); -+ } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.RAIDS_TICK); } // Folia - profiler - this.timings.raids.stopTiming(); // Paper - timings + if (flag) { + this.timings.raids.startTiming(); // Paper - timings ++ profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.RAIDS_TICK); try { // Folia - profiler + this.raids.tick(); ++ } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.RAIDS_TICK); } // Folia - profiler + this.timings.raids.stopTiming(); // Paper - timings + } + gameprofilerfiller.popPush("chunkSource"); this.timings.chunkProviderTick.startTiming(); // Paper - timings + profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.CHUNK_PROVIDER_TICK); try { // Folia - profiler @@ -1668,22 +1671,23 @@ index 10cf0ffb2cf519f0904dbe709b9042d30d5fd827..724aa1d8147ea2fb5e46d291adacfb7e + } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.CHUNK_PROVIDER_TICK); } // Folia - profiler this.timings.chunkProviderTick.stopTiming(); // Paper - timings gameprofilerfiller.popPush("blockEvents"); - this.timings.doSounds.startTiming(); // Spigot -+ profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.BLOCK_EVENT_TICK); try { // Folia - profiler - this.runBlockEvents(); -+ } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.BLOCK_EVENT_TICK); } // Folia - profiler - this.timings.doSounds.stopTiming(); // Spigot - regionizedWorldData.setHandlingTick(false); // Folia - regionised ticking - gameprofilerfiller.pop(); -@@ -941,6 +952,7 @@ public class ServerLevel extends Level implements WorldGenLevel { + if (flag) { + this.timings.doSounds.startTiming(); // Spigot ++ profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.BLOCK_EVENT_TICK); try { // Folia - profiler + this.runBlockEvents(); ++ } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.BLOCK_EVENT_TICK); } // Folia - profiler + this.timings.doSounds.stopTiming(); // Spigot + } + +@@ -958,6 +969,7 @@ public class ServerLevel extends Level implements WorldGenLevel { gameprofilerfiller.push("entities"); this.timings.tickEntities.startTiming(); // Spigot - if (this.dragonFight != null) { + if (this.dragonFight != null && flag) { + profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.DRAGON_FIGHT_TICK); try { // Folia - profiler if (io.papermc.paper.util.TickThread.isTickThreadFor(this, this.dragonFight.origin)) { // Folia - region threading gameprofilerfiller.push("dragonFight"); this.dragonFight.tick(); -@@ -953,10 +965,12 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -970,10 +982,12 @@ public class ServerLevel extends Level implements WorldGenLevel { fightCenter ); } // Folia end - region threading @@ -1696,7 +1700,7 @@ index 10cf0ffb2cf519f0904dbe709b9042d30d5fd827..724aa1d8147ea2fb5e46d291adacfb7e regionizedWorldData.forEachTickingEntity((entity) -> { // Folia - regionised ticking if (!entity.isRemoved()) { if (false && this.shouldDiscardEntity(entity)) { // CraftBukkit - We prevent spawning in general, so this butchering is not needed -@@ -984,10 +998,13 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1001,10 +1015,13 @@ public class ServerLevel extends Level implements WorldGenLevel { } } }); @@ -1710,7 +1714,7 @@ index 10cf0ffb2cf519f0904dbe709b9042d30d5fd827..724aa1d8147ea2fb5e46d291adacfb7e } gameprofilerfiller.push("entityManagement"); -@@ -1047,12 +1064,15 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1064,12 +1081,15 @@ public class ServerLevel extends Level implements WorldGenLevel { } public void tickCustomSpawners(boolean spawnMonsters, boolean spawnAnimals) { @@ -1726,7 +1730,7 @@ index 10cf0ffb2cf519f0904dbe709b9042d30d5fd827..724aa1d8147ea2fb5e46d291adacfb7e } } -@@ -1495,6 +1515,11 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1519,6 +1539,11 @@ public class ServerLevel extends Level implements WorldGenLevel { // Paper start- timings final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(entity); timer = isActive ? entity.getType().tickTimer.startTiming() : entity.getType().inactiveTickTimer.startTiming(); // Paper @@ -1738,7 +1742,7 @@ index 10cf0ffb2cf519f0904dbe709b9042d30d5fd827..724aa1d8147ea2fb5e46d291adacfb7e try { // Paper end - timings entity.setOldPosAndRot(); -@@ -1520,7 +1545,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1544,7 +1569,7 @@ public class ServerLevel extends Level implements WorldGenLevel { // Folia end - region threading } else { entity.inactiveTick(); } // Paper - EAR 2 this.getProfiler().pop(); @@ -1747,7 +1751,7 @@ index 10cf0ffb2cf519f0904dbe709b9042d30d5fd827..724aa1d8147ea2fb5e46d291adacfb7e Iterator iterator = entity.getPassengers().iterator(); while (iterator.hasNext()) { -@@ -1544,6 +1569,11 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1568,6 +1593,11 @@ public class ServerLevel extends Level implements WorldGenLevel { // Paper - EAR 2 final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(passenger); co.aikar.timings.Timing timer = isActive ? passenger.getType().passengerTickTimer.startTiming() : passenger.getType().passengerInactiveTickTimer.startTiming(); // Paper @@ -1759,7 +1763,7 @@ index 10cf0ffb2cf519f0904dbe709b9042d30d5fd827..724aa1d8147ea2fb5e46d291adacfb7e try { // Paper end passenger.setOldPosAndRot(); -@@ -1583,7 +1613,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1607,7 +1637,7 @@ public class ServerLevel extends Level implements WorldGenLevel { this.tickPassenger(passenger, entity2); } @@ -1769,10 +1773,10 @@ index 10cf0ffb2cf519f0904dbe709b9042d30d5fd827..724aa1d8147ea2fb5e46d291adacfb7e } else { passenger.stopRiding(); diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 4b1ee6b9351aeb96ac7a3c2aaa8c464bbca91e22..7edaa7558e40942f94c459e9b480ef640146ec6b 100644 +index 72c32a9b4b0606162a0f994b3d8170f0fe4d5022..dfc0e3ce3ba88c3dbff909524de348fbe76de3a9 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -1325,6 +1325,7 @@ public abstract class PlayerList { +@@ -1323,6 +1323,7 @@ public abstract class PlayerList { public void saveAll(int interval) { io.papermc.paper.util.MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main @@ -1780,7 +1784,7 @@ index 4b1ee6b9351aeb96ac7a3c2aaa8c464bbca91e22..7edaa7558e40942f94c459e9b480ef64 MinecraftTimings.savePlayers.startTiming(); // Paper int numSaved = 0; long now = System.nanoTime(); // Folia - region threading -@@ -1336,7 +1337,9 @@ public abstract class PlayerList { +@@ -1334,7 +1335,9 @@ public abstract class PlayerList { } // Folia end - region threading if (interval == -1 || now - entityplayer.lastSave >= timeInterval) { // Folia - region threading @@ -1791,10 +1795,10 @@ index 4b1ee6b9351aeb96ac7a3c2aaa8c464bbca91e22..7edaa7558e40942f94c459e9b480ef64 if (interval != -1 && max != -1 && ++numSaved >= max) { break; diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index 73871f456a85bda1e51f54986d0e61fb629822e8..3f3494c20cd15a721090f1b36293562a6b834b14 100644 +index 940b8d0b89d7e55c938aefbe80ee71b0db3dacb8..a3a6c10f5b4157062a8a8d5ee4638c4e9d6fcf62 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java -@@ -322,6 +322,13 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -326,6 +326,13 @@ public class EntityType implements FeatureElement, EntityTypeT return BuiltInRegistries.ENTITY_TYPE.getOptional(ResourceLocation.tryParse(id)); } @@ -1808,7 +1812,7 @@ index 73871f456a85bda1e51f54986d0e61fb629822e8..3f3494c20cd15a721090f1b36293562a public EntityType(EntityType.EntityFactory factory, MobCategory spawnGroup, boolean saveable, boolean summonable, boolean fireImmune, boolean spawnableFarFromPlayer, ImmutableSet canSpawnInside, EntityDimensions dimensions, int maxTrackDistance, int trackTickInterval, FeatureFlagSet requiredFeatures) { // Paper start this(factory, spawnGroup, saveable, summonable, fireImmune, spawnableFarFromPlayer, canSpawnInside, dimensions, maxTrackDistance, trackTickInterval, requiredFeatures, "custom"); -@@ -332,6 +339,12 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -336,6 +343,12 @@ public class EntityType implements FeatureElement, EntityTypeT this.passengerTickTimer = co.aikar.timings.MinecraftTimings.getEntityTimings(id, "passengerTick"); this.passengerInactiveTickTimer = co.aikar.timings.MinecraftTimings.getEntityTimings(id, "passengerInactiveTick"); // Paper end @@ -1822,10 +1826,10 @@ index 73871f456a85bda1e51f54986d0e61fb629822e8..3f3494c20cd15a721090f1b36293562a this.factory = factory; this.category = spawnGroup; diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 1480ddf3a1cc3164571a867be1f5aa02f4c66864..c58ca3dd28b9c113a26feb1a7f05bd78c0dbd678 100644 +index 474757fe16986d84f84302a22441c332d622d038..9244aaa1be1a4ba2c6eec5bcaeea7c5c0081ac39 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -226,6 +226,9 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -229,6 +229,9 @@ public abstract class Level implements LevelAccessor, AutoCloseable { return this.getCurrentWorldData().getLocalPlayers(); } // Folia end - region ticking @@ -1835,7 +1839,7 @@ index 1480ddf3a1cc3164571a867be1f5aa02f4c66864..c58ca3dd28b9c113a26feb1a7f05bd78 protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, Supplier supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator, java.util.concurrent.Executor executor) { // Paper - Async-Anti-Xray - Pass executor this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot -@@ -318,6 +321,9 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -321,6 +324,9 @@ public abstract class Level implements LevelAccessor, AutoCloseable { this.minSection = io.papermc.paper.util.WorldUtil.getMinSection(this); this.maxSection = io.papermc.paper.util.WorldUtil.getMaxSection(this); // Paper end - optimise collisions @@ -1845,7 +1849,7 @@ index 1480ddf3a1cc3164571a867be1f5aa02f4c66864..c58ca3dd28b9c113a26feb1a7f05bd78 } // Paper start -@@ -1295,17 +1301,21 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1304,17 +1310,21 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } protected void tickBlockEntities() { @@ -1865,9 +1869,9 @@ index 1480ddf3a1cc3164571a867be1f5aa02f4c66864..c58ca3dd28b9c113a26feb1a7f05bd78 this.timings.tileEntityTick.startTiming(); // Spigot + profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.TILE_ENTITY_TICK); try { // Folia - profiler // Spigot start - // Iterator iterator = this.blockEntityTickers.iterator(); - int tilesThisCycle = 0; -@@ -1336,6 +1346,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + // Iterator iterator = this.blockEntityTickers.iterator(); + boolean flag = this.tickRateManager().runsNormally(); +@@ -1347,6 +1357,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } } blockEntityTickers.removeAll(toRemove); // Folia - regionised ticking @@ -1876,10 +1880,10 @@ index 1480ddf3a1cc3164571a867be1f5aa02f4c66864..c58ca3dd28b9c113a26feb1a7f05bd78 this.timings.tileEntityTick.stopTiming(); // Spigot regionizedWorldData.seTtickingBlockEntities(false); // Folia - regionised ticking diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntityType.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntityType.java -index 2c1bc515468e2ba99d463021758fb72ef160fbe9..93cc5523a1c3637bf4f04ff4ef0f8ef6e1050a59 100644 +index 2e110da3502a7ac5ec4cc20510a3fac933569895..5aac65f37a0190c5d6a7175073fb0cc0f129de11 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntityType.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntityType.java -@@ -78,10 +78,17 @@ public class BlockEntityType { +@@ -80,10 +80,17 @@ public class BlockEntityType { } Type type = Util.fetchChoiceType(References.BLOCK_ENTITY, id); @@ -1898,7 +1902,7 @@ index 2c1bc515468e2ba99d463021758fb72ef160fbe9..93cc5523a1c3637bf4f04ff4ef0f8ef6 this.factory = factory; this.validBlocks = blocks; this.dataType = type; -@@ -126,7 +133,12 @@ public class BlockEntityType { +@@ -128,7 +135,12 @@ public class BlockEntityType { } public BlockEntityType build(Type type) { diff --git a/update.txt b/update.txt new file mode 100644 index 0000000..cbbafad --- /dev/null +++ b/update.txt @@ -0,0 +1,2 @@ +- Fix compile +- Tick rate manager - what to do with you (also: check tickChunks [specifically inhabited time] with respect to how this works now) \ No newline at end of file