diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5f1d385c..7a5ff719 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,7 +13,7 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Get JDK 17 + - name: Get JDK 21 uses: actions/setup-java@v4 with: java-version: "21" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 06224b3c..63bb000c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,9 +12,7 @@ jobs: steps: - name: Get repository uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Get JDK 17 + - name: Get JDK 21 uses: actions/setup-java@v4 with: java-version: "21" @@ -29,18 +27,19 @@ jobs: run: | git config --global user.email "ci@leavesmc.org" git config --global user.name "LeavesMC CI" - - name: Get Build Number - run: bash scripts/GetBuildNumber.sh - name: Apply Patches run: ./gradlew applyPatches - name: Create Leavesclip Jar run: ./gradlew createMojmapLeavesclipJar - env: - BUILD_NUMBER: ${{ env.BUILD_NUMBER }} - - name: Get Release Info - run: sh scripts/GetReleaseInfo.sh - env: - BUILD_NUMBER: ${{ env.BUILD_NUMBER }} + - name: Move Jar + run: | + prop() { + grep "${1}" gradle.properties | cut -d'=' -f2 | sed 's/\r//' + } + + jarName="leaves-$(prop mcVersion).jar" + mv build/libs/Leaves-leavesclip-"$(prop version)"-mojmap.jar "$jarName" + echo "jar=$jarName" >> "$GITHUB_ENV" - name: Upload Artifact uses: actions/upload-artifact@v4 with: diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 00000000..cf7c19fd --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,19 @@ +Leaves inherits its licensing from upstream projects. + +As such, Leaves is licensed under the +[GNU General Public License version 3](licenses/GPL.md); as it inherits it from Paper, +who in turn inherits it from the original Spigot, Bukkit and Craftbukkit projects. + +Any author who is _not_ listed below should be presumed to have released their work +under the original [GPL](licenses/GPL.md) license. + +In the interest of promoting a better Minecraft platform for everyone, contributors +may choose to release their code under the more permissive [MIT License](licenses/MIT.md). + +The authors listed below have chosen to release their code under that more permissive +[MIT License](licenses/MIT.md). Any contributor who wants their name added below +should submit a pull request to this project to add their name. + +```text +LittleChest +``` diff --git a/PATCHES-LICENSE b/PATCHES-LICENSE deleted file mode 100644 index 810fce6e..00000000 --- a/PATCHES-LICENSE +++ /dev/null @@ -1,621 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS diff --git a/README.md b/README.md index a14bfc73..990e21af 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,23 @@ Leaves =========== -[![Leaves CI](https://github.com/LeavesMC/Leaves/actions/workflows/leaves.yml/badge.svg)](https://github.com/LeavesMC/Leaves/actions/workflows/leaves.yml) +[![Leaves CI](https://github.com/LeavesMC/Leaves/actions/workflows/build.yml/badge.svg)](https://github.com/LeavesMC/Leaves/actions/workflows/leaves.yml) [![Leaves Download](https://img.shields.io/github/downloads/LeavesMC/Leaves/total?color=0&logo=github)](https://github.com/LeavesMC/Leaves/releases/latest) [![Discord](https://badgen.net/discord/online-members/5hgtU72w33?icon=discord&label=Discord&list=what)](https://discord.gg/5hgtU72w33) [![QQ](https://img.shields.io/badge/QQ_Unofficial-815857713-blue)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=nisbmnCFeEJCcYWBQ10th4Fu99XWklH4&authKey=8VlUxSdrFCIwmIpxFQIGR8%2BXvIQ2II%2Bx2JfxuQ8amr9UKgINh%2BdXjudQfc%2FIeTO5&noverify=0&group_code=815857713) -**English** | [中文](https://github.com/LeavesMC/Leaves/blob/master/README_cn.md) +**English** | [中文](README_cn.md) > Fork of [Paper](https://github.com/PaperMC/Paper) aims at repairing broken vanilla properties. -> You can see what we modify and fix at [here](https://github.com/LeavesMC/Leaves/blob/master/docs/MODIFICATION.md) +> You can see what we modify and fix at [here](https://docs.leavesmc.org/en/leaves/reference/configuration) ## How To (Server Admins) -Leaves use the same paperclip jar system that Paper uses. +Leaves use the same leavesclip(paperclip fork) jar system that Paper uses. -You can download the latest build (1.20.x) of Leaves by going [here](https://github.com/LeavesMC/Leaves/releases/latest) +You can download the latest build (1.21.x) of Leaves by going [here](https://github.com/LeavesMC/Leaves/releases/latest) -You can also [build it yourself](https://github.com/LeavesMC/Leaves#building). +You can also [build it yourself](#building). You can visit our [documentation](https://docs.leavesmc.org/leaves/guides/getting-started) for more information. @@ -25,22 +25,22 @@ You can visit our [documentation](https://docs.leavesmc.org/leaves/guides/gettin Leaves-API: ```kotlin maven { - name = 'leavesmc-repo' - url = 'https://repo.leavesmc.org/snapshots/' + name = "leavesmc-repo" + url = "https://repo.leavesmc.org/snapshots/" } dependencies { - compileOnly("org.leavesmc.leaves:leaves-api:1.20.6-R0.1-SNAPSHOT") + compileOnly("org.leavesmc.leaves:leaves-api:1.21-R0.1-SNAPSHOT") } ``` -In order to use Leaves as a dependency you must [build it yourself](https://github.com/LeavesMC/Leaves#building). +In order to use Leaves as a dependency you must [build it yourself](#building). Each time you want to update your dependency, you must re-build Leaves. Leaves-Server: ```kotlin dependencies { - compileOnly("org.leavesmc.leaves:leaves:1.20.6-R0.1-SNAPSHOT") + compileOnly("org.leavesmc.leaves:leaves:1.21-R0.1-SNAPSHOT") } ``` @@ -54,10 +54,10 @@ You can find the jars in the `build/libs` directory. ## Pull Requests -See [Contributing](https://github.com/LeavesMC/Leaves/blob/master/docs/CONTRIBUTING.md) +See [Contributing](docs/CONTRIBUTING.md) ## Special Thanks To: [](https://www.jetbrains.com) -[JetBrains](https://www.jetbrains.com/), creators of the IntelliJ IDEA, supports We with one of their [Open Source Licenses](https://www.jetbrains.com/opensource/). We recommend using IntelliJ IDEA as your IDE. +[JetBrains](https://www.jetbrains.com/), creators of the IntelliJ IDEA, supports Leaves with one of their [Open Source Licenses](https://www.jetbrains.com/opensource/). Leaves recommend using IntelliJ IDEA as your IDE. diff --git a/README_cn.md b/README_cn.md index b3a5455d..b6c0187a 100644 --- a/README_cn.md +++ b/README_cn.md @@ -6,18 +6,18 @@ Leaves [![Discord](https://badgen.net/discord/online-members/5hgtU72w33?icon=discord&label=Discord&list=what)](https://discord.gg/5hgtU72w33) [![QQ](https://img.shields.io/badge/QQ_Unofficial-815857713-blue)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=nisbmnCFeEJCcYWBQ10th4Fu99XWklH4&authKey=8VlUxSdrFCIwmIpxFQIGR8%2BXvIQ2II%2Bx2JfxuQ8amr9UKgINh%2BdXjudQfc%2FIeTO5&noverify=0&group_code=815857713) -[English](https://github.com/LeavesMC/Leaves/blob/master/README.md) | **中文** +[English](README.md) | **中文** > 一个致力于修复原版服务端被破坏特性的 [Paper](https://github.com/PaperMC/Paper) 分支 -> 你可以在 [这里](https://github.com/LeavesMC/Leaves/blob/master/docs/MODIFICATION_cn.md) 查看所有的修改和修复内容 +> 你可以在 [这里](https://docs.leavesmc.org/zh_Hans/leaves/reference/configuration) 查看所有的修改和修复内容 ## 对于服务器管理员 -此分支使用与 Paper 一致的 paperclip 分发 +此分支使用与 Paper 一致的 leavesclip(paperclip的分支) 分发 -你可以从 [此处](https://github.com/LeavesMC/Leaves/releases/latest) 下载最新的构建结果 (1.20.x) +你可以从 [此处](https://github.com/LeavesMC/Leaves/releases/latest) 下载最新的构建结果 (1.21.x) -也可以通过 [此处](https://github.com/LeavesMC/Leaves/blob/master/README_cn.md#自行构建) 的指南自行构建 +也可以通过 [此处](#自行构建) 的指南自行构建 如果你想要获得更多信息,那么你可以访问我们的 [文档](https://docs.leavesmc.org/zh_Hans/leaves/guides/getting-started) @@ -25,21 +25,21 @@ Leaves Leaves-API: ```kotlin maven { - name = 'leavesmc-repo' - url = 'https://repo.leavesmc.org/snapshots/' + name = "leavesmc-repo" + url = "https://repo.leavesmc.org/snapshots/" } dependencies { - compileOnly("org.leavesmc.leaves:leaves-api:1.20.6-R0.1-SNAPSHOT") + compileOnly("org.leavesmc.leaves:leaves-api:1.21-R0.1-SNAPSHOT") } ``` -如果你要将 Leaves 作为依赖,那么你必须进行 [自行构建](https://github.com/LeavesMC/Leaves/blob/master/README_cn.md#自行构建) +如果你要将 Leaves 作为依赖,那么你必须进行 [自行构建](#自行构建) Leaves-Server: ```kotlin dependencies { - compileOnly("org.leavesmc.leaves:leaves:1.20.6-R0.1-SNAPSHOT") + compileOnly("org.leavesmc.leaves:leaves:1.21R0.1-SNAPSHOT") } ``` @@ -53,10 +53,10 @@ dependencies { ## 对于想要出一份力的开发者 -可查看 [Contributing](https://github.com/LeavesMC/Leaves/blob/master/docs/CONTRIBUTING_cn.md) +可查看 [贡献须知](docs/CONTRIBUTING_cn.md) ## 特别感谢 [](https://www.jetbrains.com) -[JetBrains](https://www.jetbrains.com/),IntelliJ IDEA的创造者,为Leaves提供了 [开源许可证](https://www.jetbrains.com/opensource/)。我们极力推荐使用IntelliJ IDEA作为你的IDE。 +[JetBrains](https://www.jetbrains.com/),IntelliJ IDEA 的创造者,为 Leaves 提供了 [开源许可证](https://www.jetbrains.com/opensource/)。我们极力推荐使用 IntelliJ IDEA 作为你的 IDE。 diff --git a/build.gradle.kts b/build.gradle.kts index 97f4581d..72909bb4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,10 +1,7 @@ -import io.papermc.paperweight.util.* -import kotlin.io.path.* - plugins { java `maven-publish` - id("io.papermc.paperweight.patcher") version "1.7.1" + id("org.leavesmc.leavesweight.patcher") version "1.0.0-SNAPSHOT" } allprojects { @@ -54,14 +51,14 @@ subprojects { repositories { mavenCentral() maven("https://repo.leavesmc.org/releases") { - content { onlyForConfigurations("paperclip") } + content { onlyForConfigurations("leavesclip") } } } dependencies { - remapper("net.fabricmc:tiny-remapper:0.10.2:fat") + remapper("net.fabricmc:tiny-remapper:0.10.3:fat") decompiler("org.vineflower:vineflower:1.10.1") - paperclip("org.leavesmc:leavesclip:2.0.0") + leavesclip("org.leavesmc:leavesclip:2.0.0") } paperweight { @@ -100,37 +97,4 @@ allprojects { } } } -} - -if (providers.gradleProperty("updatingMinecraft").getOrElse("false").toBoolean()) { - - tasks.withType().configureEach { - val dir = layout.projectDirectory.dir("patches/unapplied") - if (dir.path.isDirectory()) { - extraPatchDir = dir - } - } - tasks.withType().configureEach { - filterPatches = false - } -} - -tasks.register("createMojmapLeavesclipJar") { - group = "paperweight" - dependsOn("createMojmapPaperclipJar") - doLast { - file("build/libs/Leaves-paperclip-${project.version}-mojmap.jar").renameTo( - file("build/libs/Leaves-leavesclip-${project.version}-mojmap.jar") - ) - } -} - -tasks.register("createReobfLeavesclipJar") { - group = "paperweight" - dependsOn("createReobfPaperclipJar") - doLast { - file("build/libs/Leaves-paperclip-${project.version}-reobf.jar").renameTo( - file("build/libs/Leaves-leavesclip-${project.version}-reobf.jar") - ) - } } \ No newline at end of file diff --git a/docs/MODIFICATION.md b/docs/MODIFICATION.md deleted file mode 100644 index 86b8f022..00000000 --- a/docs/MODIFICATION.md +++ /dev/null @@ -1,97 +0,0 @@ -Leaves Modification -=========== - -**English** | [中文](https://github.com/LeavesMC/Leaves/blob/master/docs/MODIFICATION_cn.md) - -## Fix (Makes it usable) - -> All of them won't have configurations - -- Gravity block duper -- Trading with the void -- Tripwire updates when it being removed and not disarmed - -## Modify - -> All of them will have configuration - -- Player can edit sign -- Snowball and egg can knockback player -- Fakeplayer support (like carpet) (command: `/bot`, permission: `bukkit.command.bot`) -- Shears in dispenser can unlimited use -- Shears can rotate redstone equipment (like debug-stick) -- Budding Amethyst can push by piston -- Spectators don't get Advancement -- Use stick and shift to ArmorStand can modify ArmorStand's arm status -- Remove Player Chat sign (NoChatReport Mod server side) -- Instant BlockUpdater reintroduced -- Random flatten triangular distribution (like Carpet-TIS-Addition) -- Player operation limiter (can make auto break bedrock mod unusable) -- Renewable Elytra (when shulker kill phantom) -- Stackable Empty Shulker Boxes -- MC Technical Survival Mode -- Return nether portal fix -- Extra Yggdrasil support -- Whether use Vanilla random -- Update suppression crash fixed -- Bedrock break list -- No feather falling trample -- Shared villager discounts -- Redstone wire doesn't connect if on trapdoor (as 1.20-) -- Despawn enderman with block in hand -- Creative fly no clip (need carpet mod and leaves-carpet protocol) -- Enchantment mending compatibility with infinity -- Shave snow layers -- Mob spawn ignores lc - -## Performance - -> All of it will have configuration - -> Powered by [Pufferfish](https://github.com/pufferfish-gg/Pufferfish) - -- Optimize mob spawning (updating, unavailable yet) -- Multithreaded Tracker (updating, unavailable yet) -- Fix Paper#6045 -- Optimize entity coordinate key -- Optimize suffocation -- Strip raytracing for entity -- Optimize Spooky Season check -- Optimize Chunk ticking -- Skip POI finding in vehicle -- Optimize entity target finding -- Use more thread Unsafe random -- Disable method profiler -- Disable inactive goal selector -- Skip clone loot parameters -- Reduce entity allocations -- Remove lambda from ticking guard -- Remove iterators from inventory contains -- Remove streams from getting nearby players -- Remove streams and iterators from range check -- Async Pathfinding (updating) -- Cache climbing check for activation -- Use aging cache for biome temperatures -- Reduce entity fluid lookups if no fluids -- Reduce chunk loading & lookups -- Simpler Vanilla ShapelessRecipes comparison -- Improve fluid direction caching - -> Powered by [Purpur](https://github.com/PurpurMC/Purpur) -- Don't send useless entity packets - -> Powered by [Carpet-AMS-Addition](https://github.com/Minecraft-AMS/Carpet-AMS-Addition) -- Optimized dragon respawn - -## Extra Protocol Support - -> All of it will have configuration - -- PCA sync protocol -- BBOR protocol -- Jade protocol -- Carpet alternative block placement (carpet-extra) -- Appleskin protocol -- Xaero Map protocol -- [Syncmatica](https://github.com/End-Tech/syncmatica) protocol -- Leaves-Carpet protocol diff --git a/docs/MODIFICATION_cn.md b/docs/MODIFICATION_cn.md deleted file mode 100644 index 10d7a5ca..00000000 --- a/docs/MODIFICATION_cn.md +++ /dev/null @@ -1,96 +0,0 @@ -Leaves Modification -=========== - -[English](https://github.com/LeavesMC/Leaves/blob/master/docs/MODIFICATION.md) | **中文** - -## 修复(使可用) - -> 所有的修复内容都不会存在配置项 - -- 重力方块复制 -- 虚空交易 -- 绊线钩即将被水破坏时亦然生成激活的绊线 - -## 修改 - -> 所有的修改内容都会存在配置项 - -- 玩家可以编辑已经放置的告示牌 -- 雪球和鸡蛋可以击退玩家 -- 假人支持 (类似carpet) (指令为 `/bot`,权限为 `bukkit.command.bot`) -- 发射器里的剪刀可以无限使用 -- 剪刀可以用来旋转红石原件 (类似调试棒) -- 紫水晶母岩可以被活塞推动 -- 观察者不会获得进度 -- 对盔甲架下蹲使用木棍可以修改盔甲架的手臂状态 -- 删除玩家聊天内的签名 (可以替代NoChatReportMod的服务器侧) -- 重新引入更新抑制机制 -- 扁平化随机数三角分布 (类似Carpet-TIS-Addition) -- 玩家操作限制器 (可禁止自动破基岩mod) -- 可再生鞘翅 (当潜影贝杀死幻翼时) -- 可堆叠空潜影箱 -- 生电模式 -- 返回传送门位置修复 -- 额外外置登录服务器支持 -- 原版随机数 (支持RNG控制) -- 更新抑制/跳略崩服修复 -- 破基岩榜 -- 有摔落缓冲不会踩坏田 -- 共享村民打折 -- 红石粉不会连接到活扳门 (恢复简易更新抑制) -- 手上有方块的末影人一样会被刷新 -- 创造飞行无碰撞箱 (需要配合carpet协议和客户端mod) -- 无限和精修不再冲突 -- 可以铲的雪 -- 怪物生成无视lc值 - -## 性能 - -> 所有的性能内容都会存在配置项 - -> Powered by [Pufferfish](https://github.com/pufferfish-gg/Pufferfish) -- 生物生成优化 (正在升级 暂不可用) -- 异步实体追踪 (正在升级 暂不可用) -- 修复Paper#6045 -- 实体坐标键优化 -- 窒息检测优化 -- 实体射线优化 -- 万圣节检测优化 -- 区块刻优化 -- 跳过矿车中实体的方块搜索 -- 实体目标检测优化 -- 使用更多的线程不安全随机数发生器 -- 关闭方法分析器 -- 禁用非活跃实体的目标选择器 -- 跳过战利品表参数复制 -- 减少实体分配 -- 删除部分lambda表达式 -- 删除容器检查中的iterators -- 删除玩家检测中的流 -- 删除范围检查中的流和iterators -- 异步实体寻路 (正在升级 暂不可用) -- 缓存实体攀爬检测 -- 使用更好的生物群系温度缓存 -- 优化实体流体检查 -- 优化末影人传送时的区块寻找 -- 更好的原版无序配方 -- 优化流体距离计算缓存 - -> Powered by [Purpur](https://github.com/PurpurMC/Purpur) -- 减少不必要包的发送 - -> Powered by [Carpet-AMS-Addition](https://github.com/Minecraft-AMS/Carpet-AMS-Addition) -- 龙战优化 - -## 额外协议支持 - -> 所有的协议内容都会存在配置项 - -- PCA同步协议 -- BBOR结构显示协议 -- Jade数据同步协议 -- Carpet精确放置协议 (carpet-extra) -- 苹果皮显示协议 -- Xaero服务器地图设置协议 -- 共享原理图协议 ([syncmatica](https://github.com/End-Tech/syncmatica)) -- Leaves-Carpet协议 仅用于同步设置 \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index eaf5a5b2..983d92b7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,8 +1,8 @@ group=org.leavesmc.leaves -version=1.20.6-R0.1-SNAPSHOT +version=1.21-R0.1-SNAPSHOT -mcVersion=1.20.6 +mcVersion=1.21 org.gradle.jvmargs=-Xmx2G -paperRef=79e2cb620ef03539390d97940824b38b707918f5 -preVersion=false +paperRef=be8ac7acc3ca286aac62c836db03d69b57f7b8fe +preVersion=true updatingMinecraft=true \ No newline at end of file diff --git a/patches/api/0001-Leaves-Server-Config.patch b/patches/api/0001-Leaves-Server-Config.patch index 50b4f4c3..e74cca79 100644 --- a/patches/api/0001-Leaves-Server-Config.patch +++ b/patches/api/0001-Leaves-Server-Config.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Leaves Server Config diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index 0614bd7e2d658172a7765925adf81b75b5620f11..4304649def2a4e00058e98e7b12b799f6e261325 100644 +index bbc4d7d3ca84642828f9a3f788ca26bba900d15b..f1163c857bc9012d1fc32ada575a5f6514e2c956 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java -@@ -2256,6 +2256,14 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi +@@ -2250,6 +2250,14 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi throw new UnsupportedOperationException("Not supported yet."); } // Paper end diff --git a/patches/api/0003-Add-fakeplayer-api.patch b/patches/api/0003-Add-fakeplayer-api.patch index 6430b8d2..dc36c496 100644 --- a/patches/api/0003-Add-fakeplayer-api.patch +++ b/patches/api/0003-Add-fakeplayer-api.patch @@ -14,10 +14,10 @@ index 97e78e27ee0eea2c8b24886eeb19164d552323fe..9764fa643039f215627c20a33ca70c9e /.factorypath + diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index 47039514503d99e84cb99f4941707a7726286516..345dbebf7a291d43f6f6ceccfba0184af86da531 100644 +index b9b751ea0d11381e846d5f35f39f285c075c171a..6610aa562f2eaf0e889406b395b1fad8deba8411 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java -@@ -2909,6 +2909,17 @@ public final class Bukkit { +@@ -2903,6 +2903,17 @@ public final class Bukkit { } // Paper end - Folia region threading API @@ -36,10 +36,10 @@ index 47039514503d99e84cb99f4941707a7726286516..345dbebf7a291d43f6f6ceccfba0184a public static Server.Spigot spigot() { return server.spigot(); diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index 4304649def2a4e00058e98e7b12b799f6e261325..1300fb43cf20f9400eb337d3104158383951eae8 100644 +index f1163c857bc9012d1fc32ada575a5f6514e2c956..d506fc269c666d847e4a8590c017bf91e2fcb6d6 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java -@@ -61,6 +61,7 @@ import org.bukkit.util.CachedServerIcon; +@@ -62,6 +62,7 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -47,7 +47,7 @@ index 4304649def2a4e00058e98e7b12b799f6e261325..1300fb43cf20f9400eb337d310415838 /** * Represents a server implementation. -@@ -2554,4 +2555,13 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi +@@ -2548,4 +2549,13 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi */ boolean isOwnedByCurrentRegion(@NotNull Entity entity); // Paper end - Folia region threading API @@ -120,20 +120,20 @@ index 0000000000000000000000000000000000000000..922ca5b27bc0dd443d635646f37f8795 +} diff --git a/src/main/java/org/leavesmc/leaves/entity/BotManager.java b/src/main/java/org/leavesmc/leaves/entity/BotManager.java new file mode 100644 -index 0000000000000000000000000000000000000000..7662b8bb1bb47f7a85705709548e00a3918d0502 +index 0000000000000000000000000000000000000000..ee6848b8990c516aa5c5490546dd16ae5c909740 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/entity/BotManager.java -@@ -0,0 +1,107 @@ +@@ -0,0 +1,124 @@ +package org.leavesmc.leaves.entity; + +import org.bukkit.Location; -+import org.bukkit.util.Consumer; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.leavesmc.leaves.entity.botaction.CustomBotAction; + +import java.util.Collection; +import java.util.UUID; ++import java.util.function.Consumer; + +/** + * Simple fakeplayer manager @@ -170,11 +170,28 @@ index 0000000000000000000000000000000000000000..7662b8bb1bb47f7a85705709548e00a3 + * @param location a location will create fakeplayer + * @return a fakeplayer if success, null otherwise + */ ++ @Deprecated(since = "1.21") + @Nullable + public Bot createBot(@NotNull String name, @NotNull String realName, @Nullable String[] skin, @Nullable String skinName, @NotNull Location location); + + /** + * Creates a fakeplayer with given param. ++ *

++ * prefix and suffix will not be added. ++ * ++ * @param name fakeplayer name ++ * @param realName fakeplayer real name ++ * @param skin fakeplayer skin arr ++ * @param skinName fakeplayer skin name ++ * @param location a location will create fakeplayer ++ * @param consumer a consumer after create fakeplayer success ++ * @return a fakeplayer if you support skin arr and the creation is success, null otherwise ++ */ ++ @Nullable ++ public Bot createBot(@NotNull String name, @NotNull String realName, @NotNull String[] skin, @Nullable String skinName, @NotNull Location location, @Nullable Consumer consumer); ++ ++ /** ++ * Creates a fakeplayer with given param. + * + * @param name fakeplayer name + * @param skinName fakeplayer skin name @@ -439,36 +456,46 @@ index 0000000000000000000000000000000000000000..5e55759fd3d7891e8e1d5d6a306dc814 +} diff --git a/src/main/java/org/leavesmc/leaves/event/bot/BotCreateEvent.java b/src/main/java/org/leavesmc/leaves/event/bot/BotCreateEvent.java new file mode 100644 -index 0000000000000000000000000000000000000000..c093f68e5f1749c792255220f39bdbdffb78f0f9 +index 0000000000000000000000000000000000000000..be510d565c5942efea3423190b06c01873a7abd2 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/event/bot/BotCreateEvent.java -@@ -0,0 +1,106 @@ +@@ -0,0 +1,118 @@ +package org.leavesmc.leaves.event.bot; + +import org.bukkit.Location; ++import org.bukkit.command.CommandSender; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + ++import java.util.Optional; ++ +/** + * Call when a fakeplayer creates a server + */ +public class BotCreateEvent extends Event implements Cancellable { ++ public enum CreateReason { ++ COMMAND, ++ PLUGIN, ++ INTERNAL ++ } + private static final HandlerList handlers = new HandlerList(); + + private final String bot; + private final String skin; -+ private String joinMessage; ++ private final CreateReason reason; ++ private final Optional creator; + private Location createLocation; + private boolean cancel = false; + -+ public BotCreateEvent(@NotNull final String who, @NotNull final String skin, @NotNull final Location createLocation, @Nullable final String joinMessage) { ++ public BotCreateEvent(@NotNull final String who, @NotNull final String skin, @NotNull final Location createLocation, @NotNull CreateReason reason, @Nullable CommandSender creator) { + this.bot = who; + this.skin = skin; -+ this.joinMessage = joinMessage; + this.createLocation = createLocation; ++ this.reason = reason; ++ this.creator = Optional.ofNullable(creator); + } + + /** @@ -481,25 +508,6 @@ index 0000000000000000000000000000000000000000..c093f68e5f1749c792255220f39bdbdf + } + + /** -+ * Gets the join message to send to all online players -+ * -+ * @return string join message. Can be null -+ */ -+ @Nullable -+ public String getJoinMessage() { -+ return joinMessage; -+ } -+ -+ /** -+ * Sets the join message to send to all online players -+ * -+ * @param joinMessage join message. If null, no message will be sent -+ */ -+ public void setJoinMessage(@Nullable String joinMessage) { -+ this.joinMessage = joinMessage; -+ } -+ -+ /** + * Gets the location to create the fakeplayer + * + * @return Location to create the fakeplayer @@ -528,6 +536,27 @@ index 0000000000000000000000000000000000000000..c093f68e5f1749c792255220f39bdbdf + return skin; + } + ++ /** ++ * Gets the create reason of the bot ++ * ++ * @return create reason ++ */ ++ @NotNull ++ public CreateReason getReason() { ++ return reason; ++ } ++ ++ /** ++ * Gets the creator of the bot ++ * if the create reason is not COMMAND, the creator might be Optional.empty() ++ * ++ * @return An optional of creator ++ */ ++ @NotNull ++ public Optional getCreator() { ++ return creator; ++ } ++ + @Override + public boolean isCancelled() { + return cancel; @@ -640,14 +669,15 @@ index 0000000000000000000000000000000000000000..a369b468d4793b36dd0944a1368a70e0 +} diff --git a/src/main/java/org/leavesmc/leaves/event/bot/BotJoinEvent.java b/src/main/java/org/leavesmc/leaves/event/bot/BotJoinEvent.java new file mode 100644 -index 0000000000000000000000000000000000000000..7500652b01a4ed3c8d59ca003a644a9e024f6512 +index 0000000000000000000000000000000000000000..e2e0b9fe697ab3b89373264d20d013cb9f65dd40 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/event/bot/BotJoinEvent.java -@@ -0,0 +1,27 @@ +@@ -0,0 +1,51 @@ +package org.leavesmc.leaves.event.bot; + +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Nullable; +import org.leavesmc.leaves.entity.Bot; + +/** @@ -656,8 +686,116 @@ index 0000000000000000000000000000000000000000..7500652b01a4ed3c8d59ca003a644a9e +public class BotJoinEvent extends BotEvent { + private static final HandlerList handlers = new HandlerList(); + -+ public BotJoinEvent(@NotNull Bot who) { ++ private String joinMessage; ++ ++ public BotJoinEvent(@NotNull Bot who, @Nullable final String joinMessage) { + super(who); ++ this.joinMessage = joinMessage; ++ } ++ ++ @Override ++ @NotNull ++ public HandlerList getHandlers() { ++ return handlers; ++ } ++ ++ @NotNull ++ public static HandlerList getHandlerList() { ++ return handlers; ++ } ++ ++ ++ /** ++ * Gets the join message to send to all online players ++ * ++ * @return string join message. Can be null ++ */ ++ @Nullable ++ public String getJoinMessage() { ++ return joinMessage; ++ } ++ ++ /** ++ * Sets the join message to send to all online players ++ * ++ * @param joinMessage join message. If null, no message will be sent ++ */ ++ public void setJoinMessage(@Nullable String joinMessage) { ++ this.joinMessage = joinMessage; ++ } ++} +diff --git a/src/main/java/org/leavesmc/leaves/event/bot/BotRemoveEvent.java b/src/main/java/org/leavesmc/leaves/event/bot/BotRemoveEvent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..6aee942d7db322196504d386a009e22e2aa16230 +--- /dev/null ++++ b/src/main/java/org/leavesmc/leaves/event/bot/BotRemoveEvent.java +@@ -0,0 +1,79 @@ ++package org.leavesmc.leaves.event.bot; ++ ++import org.bukkit.command.CommandSender; ++import org.bukkit.event.Cancellable; ++import org.bukkit.event.HandlerList; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Nullable; ++import org.leavesmc.leaves.entity.Bot; ++ ++import java.util.Optional; ++ ++/** ++ * Call when a fakeplayer creates a server ++ */ ++public class BotRemoveEvent extends BotEvent implements Cancellable { ++ public enum RemoveReason { ++ COMMAND, ++ PLUGIN, ++ DEATH, ++ INTERNAL ++ } ++ private static final HandlerList handlers = new HandlerList(); ++ ++ private final RemoveReason reason; ++ private final Optional remover; ++ private boolean cancel = false; ++ ++ public BotRemoveEvent(@NotNull final Bot who, @NotNull RemoveReason reason) { ++ this(who, reason, null); ++ } ++ ++ public BotRemoveEvent(@NotNull final Bot who, @NotNull RemoveReason reason, @Nullable CommandSender remover) { ++ super(who); ++ this.reason = reason; ++ this.remover = Optional.ofNullable(remover); ++ } ++ ++ /** ++ * Gets the remove reason of the bot ++ * ++ * @return remove reason ++ */ ++ @NotNull ++ public RemoveReason getReason() { ++ return reason; ++ } ++ ++ /** ++ * Gets the remover of the bot ++ * if the remove reason is not COMMAND, the creator might be Optional.empty() ++ * ++ * @return An optional of remover ++ */ ++ @NotNull ++ public Optional getRemover() { ++ return remover; ++ } ++ ++ @Override ++ public boolean isCancelled() { ++ return cancel; ++ } ++ ++ @Override ++ public void setCancelled(boolean cancel) { ++ this.cancel = cancel; + } + + @Override diff --git a/patches/api/0005-Hide-irrelevant-compilation-warnings.patch b/patches/api/0005-Hide-irrelevant-compilation-warnings.patch index d05d59cf..a9e5b589 100644 --- a/patches/api/0005-Hide-irrelevant-compilation-warnings.patch +++ b/patches/api/0005-Hide-irrelevant-compilation-warnings.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Hide irrelevant compilation warnings diff --git a/build.gradle.kts b/build.gradle.kts -index fd39ed209b20c927054b8482c400beeeeab460a3..d83f2d45849411afd91e27721f73189ed2a8bca5 100644 +index 540fe7e2c110e79c3742f229b3ed8c54b101d260..c070e3d308b14cc020475c2644955e7546ef6cef 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -130,6 +130,15 @@ val generateApiVersioningFile by tasks.registering { @@ -24,7 +24,7 @@ index fd39ed209b20c927054b8482c400beeeeab460a3..d83f2d45849411afd91e27721f73189e tasks.jar { from(generateApiVersioningFile.map { it.outputs.files.singleFile }) { into("META-INF/maven/${project.group}/${project.name}") -@@ -187,6 +196,8 @@ tasks.withType { +@@ -188,6 +197,8 @@ tasks.withType { into("build/docs/javadoc") } } diff --git a/patches/api/0006-SIMD-support.patch b/patches/api/0006-SIMD-support.patch index 935e5832..9cdd8251 100644 --- a/patches/api/0006-SIMD-support.patch +++ b/patches/api/0006-SIMD-support.patch @@ -5,7 +5,7 @@ Subject: [PATCH] SIMD support diff --git a/build.gradle.kts b/build.gradle.kts -index d83f2d45849411afd91e27721f73189ed2a8bca5..a42ee9d752eac9b895d9e7c29994c9f630805311 100644 +index c070e3d308b14cc020475c2644955e7546ef6cef..286349a28b06eddebbf103def9bd33bcc224f090 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -136,6 +136,7 @@ tasks.withType { @@ -16,7 +16,7 @@ index d83f2d45849411afd91e27721f73189ed2a8bca5..a42ee9d752eac9b895d9e7c29994c9f6 } // Leaves end - hide irrelevant compilation warnings -@@ -198,6 +199,7 @@ tasks.withType { +@@ -199,6 +200,7 @@ tasks.withType { } options.addStringOption("Xdoclint:none", "-quiet") // Leaves - hide irrelevant compilation warnings diff --git a/patches/api/0008-Force-peaceful-mode-switch.patch b/patches/api/0008-Force-peaceful-mode-switch.patch index 9bbff199..464de73f 100644 --- a/patches/api/0008-Force-peaceful-mode-switch.patch +++ b/patches/api/0008-Force-peaceful-mode-switch.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Force peaceful mode switch diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java -index fdb87adfb8d6eff2bfabe7a41398c53d15d4cd98..531a6cae97fe2a415cf906108a0899bf04e613d8 100644 +index d8a23aa0d898ca3360757721e38ddb97387f7d21..d744614204a840012b51e1f40148caf5f9dc6097 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java -@@ -4344,6 +4344,12 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient +@@ -4213,6 +4213,12 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient void setSendViewDistance(int viewDistance); // Paper end - view distance api diff --git a/patches/api/0009-Replay-Mod-API.patch b/patches/api/0009-Replay-Mod-API.patch index addfb971..561d1e6f 100644 --- a/patches/api/0009-Replay-Mod-API.patch +++ b/patches/api/0009-Replay-Mod-API.patch @@ -14,10 +14,10 @@ index 9764fa643039f215627c20a33ca70c9e36b2d599..97e78e27ee0eea2c8b24886eeb19164d /.factorypath - diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index 345dbebf7a291d43f6f6ceccfba0184af86da531..f633ddbc5041d93333f3db0cb675deb47d423224 100644 +index 6610aa562f2eaf0e889406b395b1fad8deba8411..9e7264149efc346d1e8e323b84bb8c19c0c5c58c 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java -@@ -2919,6 +2919,11 @@ public final class Bukkit { +@@ -2913,6 +2913,11 @@ public final class Bukkit { return server.getBotManager(); } // Leaves end - Bot API @@ -30,10 +30,10 @@ index 345dbebf7a291d43f6f6ceccfba0184af86da531..f633ddbc5041d93333f3db0cb675deb4 @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 1300fb43cf20f9400eb337d3104158383951eae8..98ca0f656ea3a5be30ad49bc7fb22c886adbef03 100644 +index d506fc269c666d847e4a8590c017bf91e2fcb6d6..fe93598096c904ed7c085ebce49bca2ce882cb75 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java -@@ -62,6 +62,7 @@ import org.jetbrains.annotations.Contract; +@@ -63,6 +63,7 @@ import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.leavesmc.leaves.entity.BotManager; @@ -41,7 +41,7 @@ index 1300fb43cf20f9400eb337d3104158383951eae8..98ca0f656ea3a5be30ad49bc7fb22c88 /** * Represents a server implementation. -@@ -2564,4 +2565,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi +@@ -2558,4 +2559,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi */ @NotNull BotManager getBotManager(); // Leaves end - Bot API diff --git a/patches/api/0010-Bytebuf-API.patch b/patches/api/0010-Bytebuf-API.patch index 6c3e5cfd..cfacfada 100644 --- a/patches/api/0010-Bytebuf-API.patch +++ b/patches/api/0010-Bytebuf-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Bytebuf API diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index f633ddbc5041d93333f3db0cb675deb47d423224..992db8d11b6cb230488c0e77ce8f4834932bbded 100644 +index 9e7264149efc346d1e8e323b84bb8c19c0c5c58c..a5be047695fa8fa495da6f8773946768aeaeb05a 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java -@@ -2925,6 +2925,12 @@ public final class Bukkit { +@@ -2919,6 +2919,12 @@ public final class Bukkit { } // Leaves end - Photographer API @@ -22,10 +22,10 @@ index f633ddbc5041d93333f3db0cb675deb47d423224..992db8d11b6cb230488c0e77ce8f4834 public static Server.Spigot spigot() { return server.spigot(); diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index 98ca0f656ea3a5be30ad49bc7fb22c886adbef03..79ad3c362e5437b28e44270a9c7b8947ce8b00d5 100644 +index fe93598096c904ed7c085ebce49bca2ce882cb75..1206268f19defd269c63e3391336b9920573454f 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java -@@ -2568,4 +2568,8 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi +@@ -2562,4 +2562,8 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi // Leaves start - Photographer API @NotNull PhotographerManager getPhotographerManager(); // Leaves end - Photographer API @@ -35,10 +35,10 @@ index 98ca0f656ea3a5be30ad49bc7fb22c886adbef03..79ad3c362e5437b28e44270a9c7b8947 + // Leaves end - Bytebuf API } diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index eb34f22e973fe46529eb93f435f5bf7f85091404..ba79992f0c170ab1c0db402698feb5071fe8cf62 100644 +index 7c56182acaf827f4b1a986a61cea8e9960604c98..45f820485e6f6e3a6a37a30a30c1c6a65b4615bb 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3850,6 +3850,12 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3855,6 +3855,12 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM boolean isChunkSent(long chunkKey); // Paper end diff --git a/patches/server/0001-Build-changes.patch b/patches/server/0001-Build-changes.patch index 74a8c3f3..8b6cc9fa 100644 --- a/patches/server/0001-Build-changes.patch +++ b/patches/server/0001-Build-changes.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Build changes diff --git a/build.gradle.kts b/build.gradle.kts -index 4998aff0b7cb084dcda15c6a18bbe45e99b6000a..16b742b5131376ceca04570dd4c088caff62e677 100644 +index 1a734293c9416f13324bb0edf8f950c9029f8bc4..5025c5df3ee6ed84106782e3f9228874bebe63ca 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,7 +13,7 @@ configurations.named(log4jPlugins.compileClasspathConfigurationName) { @@ -18,7 +18,7 @@ index 4998aff0b7cb084dcda15c6a18bbe45e99b6000a..16b742b5131376ceca04570dd4c088ca implementation("org.jline:jline-terminal-jansi:3.21.0") implementation("net.minecrell:terminalconsoleappender:1.3.0") @@ -67,6 +67,15 @@ paperweight { - craftBukkitPackageVersion.set("v1_20_R4") // also needs to be updated in MappingEnvironment + craftBukkitPackageVersion.set("v1_21_R1") // also needs to be updated in MappingEnvironment } +// Leaves start - hide irrelevant compilation warnings @@ -164,10 +164,10 @@ index 790bad0494454ca12ee152e3de6da3da634d9b20..c060857cb0551fff8f5033553b887f3a private static final String BUILD_DEV = "DEV"; diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 3751c2a077bd13bac330b93c6efc2a640a17f4f2..2235e5cfd853216fd79cf26244f9f029af1fc3b4 100644 +index 330bee331335454a61cf8350a6654217c8124445..7a605d767d4f8e13d26071b9965a7724677e57d8 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1165,7 +1165,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop, String> taskNameCache = new MapMaker().weakKeys().makeMap(); - @@ -587,10 +584,10 @@ index 7620c72a4c243cbeea245203ce03a97cbfa7d922..00000000000000000000000000000000 -} diff --git a/src/main/java/co/aikar/timings/WorldTimingsHandler.java b/src/main/java/co/aikar/timings/WorldTimingsHandler.java deleted file mode 100644 -index 22687667ec69a954261e55e59261286ac1b8b8cd..0000000000000000000000000000000000000000 +index 2f0d9b953802dee821cfde82d22b0567cce8ee91..0000000000000000000000000000000000000000 --- a/src/main/java/co/aikar/timings/WorldTimingsHandler.java +++ /dev/null -@@ -1,140 +0,0 @@ +@@ -1,120 +0,0 @@ -package co.aikar.timings; - -import net.minecraft.server.level.ServerLevel; @@ -652,16 +649,6 @@ index 22687667ec69a954261e55e59261286ac1b8b8cd..00000000000000000000000000000000 - - public final Timing miscMobSpawning; - -- public final Timing poiUnload; -- public final Timing chunkUnload; -- public final Timing poiSaveDataSerialization; -- public final Timing chunkSave; -- public final Timing chunkSaveDataSerialization; -- public final Timing chunkSaveIOWait; -- public final Timing chunkUnloadPrepareSave; -- public final Timing chunkUnloadPOISerialization; -- public final Timing chunkUnloadDataSave; -- - public WorldTimingsHandler(Level server) { - String name = ((PrimaryLevelData) server.getLevelData()).getLevelName() + " - "; - @@ -715,71 +702,12 @@ index 22687667ec69a954261e55e59261286ac1b8b8cd..00000000000000000000000000000000 - - - miscMobSpawning = Timings.ofSafe(name + "Mob spawning - Misc"); -- -- poiUnload = Timings.ofSafe(name + "Chunk unload - POI"); -- chunkUnload = Timings.ofSafe(name + "Chunk unload - Chunk"); -- poiSaveDataSerialization = Timings.ofSafe(name + "Chunk save - POI Data serialization"); -- chunkSave = Timings.ofSafe(name + "Chunk save - Chunk"); -- chunkSaveDataSerialization = Timings.ofSafe(name + "Chunk save - Chunk Data serialization"); -- chunkSaveIOWait = Timings.ofSafe(name + "Chunk save - Chunk IO Wait"); -- chunkUnloadPrepareSave = Timings.ofSafe(name + "Chunk unload - Async Save Prepare"); -- chunkUnloadPOISerialization = Timings.ofSafe(name + "Chunk unload - POI Data Serialization"); -- chunkUnloadDataSave = Timings.ofSafe(name + "Chunk unload - Data Serialization"); - } - - public static Timing getTickList(ServerLevel worldserver, String timingsType) { - return Timings.ofSafe(((PrimaryLevelData) worldserver.getLevelData()).getLevelName() + " - Scheduled " + timingsType); - } -} -diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java -index 6bc7c6f16a1649fc9e24e7cf90fca401e5bd4875..5b446e6ac151f99f64f0c442d0b40b5e251bc4c4 100644 ---- a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java -+++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java -@@ -1316,9 +1316,7 @@ public final class ChunkHolderManager { - } - - public boolean processTicketUpdates() { -- co.aikar.timings.MinecraftTimings.distanceManagerTick.startTiming(); try { // Paper - add timings for distance manager - return this.processTicketUpdates(true, true, null); -- } finally { co.aikar.timings.MinecraftTimings.distanceManagerTick.stopTiming(); } // Paper - add timings for distance manager - } - - private static final ThreadLocal> CURRENT_TICKET_UPDATE_SCHEDULING = new ThreadLocal<>(); -diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java -index 56b07a3306e5735816c8d89601b519cb0db6379a..e932998bb1d833d782e1f6c7f576f521e8ace071 100644 ---- a/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java -+++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java -@@ -1779,19 +1779,17 @@ public final class NewChunkHolder { - boolean canSavePOI = !(chunk instanceof LevelChunk levelChunk && levelChunk.mustNotSave) && (poi != null && poi.isDirty()); - boolean canSaveEntities = entities != null; - -- try (co.aikar.timings.Timing ignored = this.world.timings.chunkSave.startTiming()) { // Paper -- if (canSaveChunk) { -- canSaveChunk = this.saveChunk(chunk, unloading); -- } -- if (canSavePOI) { -- canSavePOI = this.savePOI(poi, unloading); -- } -- if (canSaveEntities) { -- // on shutdown, we need to force transient entity chunks to save -- canSaveEntities = this.saveEntities(entities, unloading || shutdown); -- if (unloading || shutdown) { -- this.lastEntityUnload = null; -- } -+ if (canSaveChunk) { -+ canSaveChunk = this.saveChunk(chunk, unloading); -+ } -+ if (canSavePOI) { -+ canSavePOI = this.savePOI(poi, unloading); -+ } -+ if (canSaveEntities) { -+ // on shutdown, we need to force transient entity chunks to save -+ canSaveEntities = this.saveEntities(entities, unloading || shutdown); -+ if (unloading || shutdown) { -+ this.lastEntityUnload = null; - } - } - diff --git a/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitCommandNode.java b/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitCommandNode.java index 0c3c82b28e581286b798ee58ca4193efc2faff4a..fe6a5a6377bcb577b21471ae93639f8dc5fa0f39 100644 --- a/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitCommandNode.java @@ -813,7 +741,7 @@ index 0c3c82b28e581286b798ee58ca4193efc2faff4a..fe6a5a6377bcb577b21471ae93639f8d // return true as command was handled return 1; diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 2874bc3001c4e7d9191e47ba512c5a68369c21f1..0cb47b5fee85230989293d430c02e53391e0ef67 100644 +index b8499c1cea97a1a88a53053bc7da132f2fd3928d..0a3f2f5b474910af3cabf3bab5310c0e970aed68 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java @@ -1,6 +1,5 @@ @@ -873,11 +801,11 @@ index 097500a59336db1bbfffcd1aa4cff7a8586e46ec..35b00c139864dd7925d46a2d6a317d7e @Override diff --git a/src/main/java/net/minecraft/network/protocol/PacketUtils.java b/src/main/java/net/minecraft/network/protocol/PacketUtils.java -index 57e76b53e5e314c3e6b8856010f7a84188121582..d6daa27a8d7aca00b181e90d789f4249e8437d29 100644 +index d0d36a57ec4896bcb74970f8fb24d8f3e17db133..f7197f1347251a37dd0f6d9ffa2f09bc3a4e1233 100644 --- a/src/main/java/net/minecraft/network/protocol/PacketUtils.java +++ b/src/main/java/net/minecraft/network/protocol/PacketUtils.java -@@ -50,8 +50,7 @@ public class PacketUtils { - try { // Paper - detailed watchdog information +@@ -31,8 +31,7 @@ public class PacketUtils { + engine.executeIfPossible(() -> { if (listener instanceof ServerCommonPacketListenerImpl serverCommonPacketListener && serverCommonPacketListener.processedDisconnect) return; // CraftBukkit - Don't handle sync packets for kicked players if (listener.shouldHandleMessage(packet)) { - co.aikar.timings.Timing timing = co.aikar.timings.MinecraftTimings.getPacketTiming(packet); // Paper - timings @@ -887,7 +815,7 @@ index 57e76b53e5e314c3e6b8856010f7a84188121582..d6daa27a8d7aca00b181e90d789f4249 } catch (Exception exception) { if (exception instanceof ReportedException) { diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 2235e5cfd853216fd79cf26244f9f029af1fc3b4..1f973ed9bb9c753b81979085a6fea45b65165fa3 100644 +index 7a605d767d4f8e13d26071b9965a7724677e57d8..3a37a083556a722ea6fbc75adf32b36e1b66bcc4 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -3,9 +3,6 @@ package net.minecraft.server; @@ -900,16 +828,16 @@ index 2235e5cfd853216fd79cf26244f9f029af1fc3b4..1f973ed9bb9c753b81979085a6fea45b import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -@@ -190,8 +187,6 @@ import org.bukkit.craftbukkit.CraftRegistry; +@@ -196,8 +193,6 @@ import org.bukkit.craftbukkit.CraftRegistry; import org.bukkit.event.server.ServerLoadEvent; // CraftBukkit end -import co.aikar.timings.MinecraftTimings; // Paper - - public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements ServerInfo, CommandSource, AutoCloseable { + public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements ServerInfo, ChunkIOErrorReporter, CommandSource, AutoCloseable, ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer { // Paper - rewrite chunk system private static MinecraftServer SERVER; // Paper -@@ -972,7 +967,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop= MAX_CHUNK_EXEC_TIME) { -- if (!moreTasks) { -- lastMidTickExecuteFailure = currTime; -- } -- -- // note: negative values reduce the time -- long overuse = diff - MAX_CHUNK_EXEC_TIME; -- if (overuse >= (10L * 1000L * 1000L)) { // 10ms -- // make sure something like a GC or dumb plugin doesn't screw us over... -- overuse = 10L * 1000L * 1000L; // 10ms -- } -+ for (;;) { -+ boolean moreTasks = this.tickMidTickTasks(); -+ long currTime = System.nanoTime(); -+ long diff = currTime - startTime; - -- double overuseCount = (double)overuse/(double)MAX_CHUNK_EXEC_TIME; -- long extraSleep = (long)Math.round(overuseCount*CHUNK_TASK_QUEUE_BACKOFF_MIN_TIME); -+ if (!moreTasks || diff >= MAX_CHUNK_EXEC_TIME) { -+ if (!moreTasks) { -+ lastMidTickExecuteFailure = currTime; -+ } - -- lastMidTickExecute = currTime + extraSleep; -- return; -+ // note: negative values reduce the time -+ long overuse = diff - MAX_CHUNK_EXEC_TIME; -+ if (overuse >= (10L * 1000L * 1000L)) { // 10ms -+ // make sure something like a GC or dumb plugin doesn't screw us over... -+ overuse = 10L * 1000L * 1000L; // 10ms - } -+ -+ double overuseCount = (double)overuse/(double)MAX_CHUNK_EXEC_TIME; -+ long extraSleep = (long)Math.round(overuseCount*CHUNK_TASK_QUEUE_BACKOFF_MIN_TIME); -+ -+ lastMidTickExecute = currTime + extraSleep; -+ return; - } -- } finally { -- co.aikar.timings.MinecraftTimings.midTickChunkTasks.stopTiming(); - } - } - // Paper end - execute chunk tasks mid tick -@@ -1554,15 +1543,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { entityplayer.connection.suspendFlushing(); }); @@ -1018,7 +892,7 @@ index 2235e5cfd853216fd79cf26244f9f029af1fc3b4..1f973ed9bb9c753b81979085a6fea45b // Paper start - Folia scheduler API ((io.papermc.paper.threadedregions.scheduler.FoliaGlobalRegionScheduler) Bukkit.getGlobalRegionScheduler()).tick(); getAllLevels().forEach(level -> { -@@ -1714,21 +1697,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop list = Lists.newArrayList(); List list1 = this.level.players(); ObjectIterator objectiterator = this.entityMap.values().iterator(); @@ -1203,7 +1026,7 @@ index 7fb9ba3dadb1eca4a1000ea8cf4d13fed2b7db1e..dc20b051d4f14ce4e0b5a0114e02d157 ChunkMap.TrackedEntity playerchunkmap_entitytracker; -@@ -1214,17 +1198,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -982,17 +980,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider playerchunkmap_entitytracker.serverEntity.sendChanges(); } } @@ -1222,40 +1045,20 @@ index 7fb9ba3dadb1eca4a1000ea8cf4d13fed2b7db1e..dc20b051d4f14ce4e0b5a0114e02d157 } diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index fcecfda569d2a8d6b8a7e228831f822fb7327748..ffab3e27c0d9da2a380a14b6f6ebb243a6fb5e8d 100644 +index 64ed296cfbe7e5d27286b8cee70454fd1d99ebb0..48991b885c7cad9c201887b222acad7d700bd03b 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -274,10 +274,8 @@ public class ServerChunkCache extends ChunkSource { - if (!completablefuture.isDone()) { // Paper - io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.pushChunkWait(this.level, x1, z1); // Paper - rewrite chunk system - com.destroystokyo.paper.io.SyncLoadFinder.logSyncLoad(this.level, x, z); // Paper - Add debug for sync chunk loads -- this.level.timings.syncChunkLoad.startTiming(); // Paper - chunkproviderserver_b.managedBlock(completablefuture::isDone); - io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.popChunkWait(); // Paper - rewrite chunk system -- this.level.timings.syncChunkLoad.stopTiming(); // Paper - } // Paper - ChunkResult chunkresult = (ChunkResult) completablefuture.join(); - ChunkAccess ichunkaccess1 = (ChunkAccess) chunkresult.orElse(null); // CraftBukkit - decompile error -@@ -425,17 +423,13 @@ public class ServerChunkCache extends ChunkSource { +@@ -357,9 +357,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon public void save(boolean flush) { - this.runDistanceManagerUpdates(); + // Paper - rewrite chunk system - try (co.aikar.timings.Timing timed = level.timings.chunkSaveData.startTiming()) { // Paper - Timings this.chunkMap.saveAllChunks(flush); - } // Paper - Timings } - // Paper start - Incremental chunk and player saving; duplicate save, but call incremental - public void saveIncrementally() { - this.runDistanceManagerUpdates(); -- try (co.aikar.timings.Timing timed = level.timings.chunkSaveData.startTiming()) { // Paper - Timings -- this.chunkMap.saveIncrementally(); -- } // Paper - Timings -+ this.chunkMap.saveIncrementally(); - } - // Paper end - Incremental chunk and player saving - -@@ -472,26 +466,20 @@ public class ServerChunkCache extends ChunkSource { + @Override +@@ -387,26 +385,20 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon @Override public void tick(BooleanSupplier shouldKeepTicking, boolean tickChunks) { this.level.getProfiler().push("purge"); @@ -1269,7 +1072,7 @@ index fcecfda569d2a8d6b8a7e228831f822fb7327748..ffab3e27c0d9da2a380a14b6f6ebb243 this.level.getProfiler().popPush("chunks"); if (tickChunks) { - this.level.timings.chunks.startTiming(); // Paper - timings - this.chunkMap.level.playerChunkLoader.tick(); // Paper - replace player chunk loader - this is mostly required to account for view distance changes + ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getPlayerChunkLoader().tick(); // Paper - rewrite chunk system this.tickChunks(); - this.level.timings.chunks.stopTiming(); // Paper - timings this.chunkMap.tick(); @@ -1282,13 +1085,15 @@ index fcecfda569d2a8d6b8a7e228831f822fb7327748..ffab3e27c0d9da2a380a14b6f6ebb243 this.level.getProfiler().pop(); this.clearCache(); } -@@ -507,13 +495,11 @@ public class ServerChunkCache extends ChunkSource { - gameprofilerfiller.push("pollingChunks"); +@@ -424,7 +416,6 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon gameprofilerfiller.push("filteringLoadedChunks"); - // Paper - optimise chunk tick iteration + List list = Lists.newArrayListWithCapacity(this.chunkMap.size()); + Iterator iterator = this.chunkMap.getChunks().iterator(); - if (this.level.getServer().tickRateManager().runsNormally()) this.level.timings.chunkTicks.startTiming(); // Paper - // Paper - optimise chunk tick iteration + while (iterator.hasNext()) { + ChunkHolder playerchunk = (ChunkHolder) iterator.next(); +@@ -437,7 +428,6 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon if (this.level.tickRateManager().runsNormally()) { gameprofilerfiller.popPush("naturalSpawnCount"); @@ -1296,7 +1101,7 @@ index fcecfda569d2a8d6b8a7e228831f822fb7327748..ffab3e27c0d9da2a380a14b6f6ebb243 int k = this.distanceManager.getNaturalSpawnChunkCount(); // Paper start - Optional per player mob spawns int naturalSpawnChunkCount = k; -@@ -538,7 +524,6 @@ public class ServerChunkCache extends ChunkSource { +@@ -462,7 +452,6 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon spawnercreature_d = NaturalSpawner.createState(naturalSpawnChunkCount, this.level.getAllEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false); } // Paper end - Optional per player mob spawns @@ -1304,10 +1109,10 @@ index fcecfda569d2a8d6b8a7e228831f822fb7327748..ffab3e27c0d9da2a380a14b6f6ebb243 this.lastSpawnState = spawnercreature_d; gameprofilerfiller.popPush("spawnAndTick"); -@@ -647,19 +632,14 @@ public class ServerChunkCache extends ChunkSource { +@@ -503,21 +492,16 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon + } } } - // Paper end - optimise chunk tick iteration - this.level.timings.chunkTicks.stopTiming(); // Paper gameprofilerfiller.popPush("customSpawners"); @@ -1319,22 +1124,15 @@ index fcecfda569d2a8d6b8a7e228831f822fb7327748..ffab3e27c0d9da2a380a14b6f6ebb243 } gameprofilerfiller.popPush("broadcast"); -- // Paper - optimise chunk tick iteration + list.forEach((chunkproviderserver_a1) -> { - this.level.timings.broadcastChunkUpdates.startTiming(); // Paper - timing - // Paper start - optimise chunk tick iteration - if (!this.chunkMap.needsChangeBroadcasting.isEmpty()) { - it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet copy = this.chunkMap.needsChangeBroadcasting.clone(); -@@ -673,8 +653,6 @@ public class ServerChunkCache extends ChunkSource { - } - } - // Paper end - optimise chunk tick iteration + chunkproviderserver_a1.holder.broadcastChanges(chunkproviderserver_a1.chunk); - this.level.timings.broadcastChunkUpdates.stopTiming(); // Paper - timing -- // Paper - optimise chunk tick iteration + }); gameprofilerfiller.pop(); gameprofilerfiller.pop(); - } diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index ca56a0b596976448da6bb2a0e82b3d5cd4133e12..92805a3311bc1f21df9512b14b209e1d51174ac5 100644 +index e079f4db4e4738f60a6fdbdbf5e4d1baf593a62f..d6af1d0cd2829bc1e7e7c7a7a8014750c2bdac2b 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1,7 +1,6 @@ @@ -1345,7 +1143,7 @@ index ca56a0b596976448da6bb2a0e82b3d5cd4133e12..92805a3311bc1f21df9512b14b209e1d import com.google.common.collect.Lists; import com.mojang.datafixers.DataFixer; import com.mojang.datafixers.util.Pair; -@@ -851,7 +850,6 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -682,7 +681,6 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. } gameprofilerfiller.popPush("tickPending"); @@ -1353,7 +1151,7 @@ index ca56a0b596976448da6bb2a0e82b3d5cd4133e12..92805a3311bc1f21df9512b14b209e1d if (!this.isDebug() && flag) { j = this.getGameTime(); gameprofilerfiller.push("blockTicks"); -@@ -860,24 +858,17 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -691,24 +689,17 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. this.fluidTicks.tick(j, paperConfig().environment.maxFluidTicks, this::tickFluid); // Paper - configurable max fluid ticks gameprofilerfiller.pop(); } @@ -1378,7 +1176,7 @@ index ca56a0b596976448da6bb2a0e82b3d5cd4133e12..92805a3311bc1f21df9512b14b209e1d } this.handlingTick = false; -@@ -890,7 +881,6 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -721,7 +712,6 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. if (flag1 || this.emptyTime++ < 300) { gameprofilerfiller.push("entities"); @@ -1386,7 +1184,7 @@ index ca56a0b596976448da6bb2a0e82b3d5cd4133e12..92805a3311bc1f21df9512b14b209e1d if (this.dragonFight != null && flag) { gameprofilerfiller.push("dragonFight"); this.dragonFight.tick(); -@@ -898,7 +888,6 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -729,7 +719,6 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. } org.spigotmc.ActivationRange.activateEntities(this); // Spigot @@ -1394,7 +1192,7 @@ index ca56a0b596976448da6bb2a0e82b3d5cd4133e12..92805a3311bc1f21df9512b14b209e1d this.entityTickList.forEach((entity) -> { if (!entity.isRemoved()) { if (false && this.shouldDiscardEntity(entity)) { // CraftBukkit - We prevent spawning in general, so this butchering is not needed -@@ -925,8 +914,6 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -756,8 +745,6 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. } } }); @@ -1403,7 +1201,7 @@ index ca56a0b596976448da6bb2a0e82b3d5cd4133e12..92805a3311bc1f21df9512b14b209e1d gameprofilerfiller.pop(); this.tickBlockEntities(); } -@@ -1039,7 +1026,6 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -870,7 +857,6 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. } // Paper - Option to disable ice and snow gameprofilerfiller.popPush("tickBlocks"); @@ -1411,7 +1209,7 @@ index ca56a0b596976448da6bb2a0e82b3d5cd4133e12..92805a3311bc1f21df9512b14b209e1d if (randomTickSpeed > 0) { // Paper start - optimize random block ticking LevelChunkSection[] sections = chunk.getSections(); -@@ -1073,7 +1059,6 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -904,7 +890,6 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. } // Paper end - optimise random block ticking @@ -1419,17 +1217,17 @@ index ca56a0b596976448da6bb2a0e82b3d5cd4133e12..92805a3311bc1f21df9512b14b209e1d gameprofilerfiller.pop(); } -@@ -1386,9 +1371,7 @@ public class ServerLevel extends Level implements WorldGenLevel { - currentlyTickingEntity.lazySet(entity); - } - // Paper end - log detailed entity tick information +@@ -1206,9 +1191,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. + } + + public void tickNonPassenger(Entity entity) { - ++TimingHistory.entityTicks; // Paper - timings // Spigot start - co.aikar.timings.Timing timer; // Paper /*if (!org.spigotmc.ActivationRange.checkIfActive(entity)) { // Paper - comment out - EAR 2, reimplement below entity.tickCount++; timer = entity.getType().inactiveTickTimer.startTiming(); try { // Paper - timings -@@ -1397,11 +1380,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1217,11 +1200,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. return; }*/ // Paper - comment out EAR 2 // Spigot end @@ -1441,7 +1239,7 @@ index ca56a0b596976448da6bb2a0e82b3d5cd4133e12..92805a3311bc1f21df9512b14b209e1d entity.setOldPosAndRot(); ProfilerFiller gameprofilerfiller = this.getProfiler(); -@@ -1411,12 +1390,10 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1231,12 +1210,10 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. }); gameprofilerfiller.incrementCounter("tickNonPassenger"); if (isActive) { // Paper - EAR 2 @@ -1454,7 +1252,7 @@ index ca56a0b596976448da6bb2a0e82b3d5cd4133e12..92805a3311bc1f21df9512b14b209e1d Iterator iterator = entity.getPassengers().iterator(); while (iterator.hasNext()) { -@@ -1439,8 +1416,6 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1253,8 +1230,6 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. if (passenger instanceof Player || this.entityTickList.contains(passenger)) { // Paper - EAR 2 final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(passenger); @@ -1463,7 +1261,7 @@ index ca56a0b596976448da6bb2a0e82b3d5cd4133e12..92805a3311bc1f21df9512b14b209e1d // Paper end passenger.setOldPosAndRot(); ++passenger.tickCount; -@@ -1469,8 +1444,6 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1283,8 +1258,6 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. this.tickPassenger(passenger, entity2); } @@ -1472,46 +1270,7 @@ index ca56a0b596976448da6bb2a0e82b3d5cd4133e12..92805a3311bc1f21df9512b14b209e1d } } else { passenger.stopRiding(); -@@ -1490,26 +1463,22 @@ public class ServerLevel extends Level implements WorldGenLevel { - org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); - } - -- try (co.aikar.timings.Timing ignored = this.timings.worldSave.startTiming()) { -- if (doFull) { -- this.saveLevelData(true); // Paper - Write SavedData IO async -- } -+ if (doFull) { -+ this.saveLevelData(true); // Paper - Write SavedData IO async -+ } - -- this.timings.worldSaveChunks.startTiming(); // Paper -- if (!this.noSave()) chunkproviderserver.saveIncrementally(); -- this.timings.worldSaveChunks.stopTiming(); // Paper -+ if (!this.noSave()) chunkproviderserver.saveIncrementally(); - -- // Copied from save() -- // CraftBukkit start - moved from MinecraftServer.saveChunks -- if (doFull) { // Paper -- ServerLevel worldserver1 = this; -+ // Copied from save() -+ // CraftBukkit start - moved from MinecraftServer.saveChunks -+ if (doFull) { // Paper -+ ServerLevel worldserver1 = this; - -- this.serverLevelData.setWorldBorder(worldserver1.getWorldBorder().createSettings()); -- this.serverLevelData.setCustomBossEvents(this.server.getCustomBossEvents().save(this.registryAccess())); -- this.convertable.saveDataTag(this.server.registryAccess(), this.serverLevelData, this.server.getPlayerList().getSingleplayerData()); -- } -- // CraftBukkit end -+ this.serverLevelData.setWorldBorder(worldserver1.getWorldBorder().createSettings()); -+ this.serverLevelData.setCustomBossEvents(this.server.getCustomBossEvents().save(this.registryAccess())); -+ this.convertable.saveDataTag(this.server.registryAccess(), this.serverLevelData, this.server.getPlayerList().getSingleplayerData()); - } -+ // CraftBukkit end - } - // Paper end - Incremental chunk and player saving - -@@ -1523,7 +1492,6 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1306,7 +1279,6 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. if (!savingDisabled) { org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(this.getWorld())); // CraftBukkit @@ -1519,20 +1278,21 @@ index ca56a0b596976448da6bb2a0e82b3d5cd4133e12..92805a3311bc1f21df9512b14b209e1d if (progressListener != null) { progressListener.progressStartNoAbort(Component.translatable("menu.savingLevel")); } -@@ -1533,11 +1501,8 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1316,12 +1288,8 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. progressListener.progressStage(Component.translatable("menu.savingChunks")); } - timings.worldSaveChunks.startTiming(); // Paper - if (!close) chunkproviderserver.save(flush); // Paper - rewrite chunk system - if (close) chunkproviderserver.close(true); // Paper - rewrite chunk system + if (!close) { chunkproviderserver.save(flush); } // Paper - add close param - timings.worldSaveChunks.stopTiming(); // Paper - }// Paper - // Paper - rewrite chunk system - entity saving moved into ChunkHolder - - } else if (close) { chunkproviderserver.close(false); } // Paper - rewrite chunk system + // Paper - rewrite chunk system +- + } + // Paper start - add close param + if (close) { diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index a2142930b4d4b05987c90496fb9d733d99040aa0..6957cbfbea51d6a3b57e1c5bfcebd52a25cde8d5 100644 +index 5f20606cc2c79ad9a4c4d4d6c9e6a2a31a88b282..a45ece7009dd9a2f4682f4c0a4759e2718404b0b 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -1,6 +1,5 @@ @@ -1542,24 +1302,20 @@ index a2142930b4d4b05987c90496fb9d733d99040aa0..6957cbfbea51d6a3b57e1c5bfcebd52a import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -@@ -1235,7 +1234,6 @@ public abstract class PlayerList { +@@ -1183,11 +1182,9 @@ public abstract class PlayerList { - public void saveAll(int interval) { + public void saveAll() { io.papermc.paper.util.MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main - MinecraftTimings.savePlayers.startTiming(); // Paper - int numSaved = 0; - long now = MinecraftServer.currentTick; for (int i = 0; i < this.players.size(); ++i) { -@@ -1246,7 +1244,6 @@ public abstract class PlayerList { - } - // Paper end - Incremental chunk and player saving + this.save(this.players.get(i)); } - MinecraftTimings.savePlayers.stopTiming(); // Paper return null; }); // Paper - ensure main } diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index a46bf73c608641bf1f00fd55242de71a0f2ee06e..9b15a2a966de203ada8894a9354ff8e0e737ef75 100644 +index cb61462d4691a055a4b25f7b953609d8a154fdfe..b2b97c4c61ea5b6f7ec199fabbd1bd1c86647ccc 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java @@ -343,10 +343,6 @@ public class EntityType implements FeatureElement, EntityTypeT @@ -1587,10 +1343,10 @@ index a46bf73c608641bf1f00fd55242de71a0f2ee06e..9b15a2a966de203ada8894a9354ff8e0 return this != EntityType.PLAYER && this != EntityType.LLAMA_SPIT && this != EntityType.WITHER && this != EntityType.BAT && this != EntityType.ITEM_FRAME && this != EntityType.GLOW_ITEM_FRAME && this != EntityType.LEASH_KNOT && this != EntityType.PAINTING && this != EntityType.END_CRYSTAL && this != EntityType.EVOKER_FANGS; } diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 21e61bb75ac7ce468bc757633ce678b21bcb9deb..5b5d8d2430f2b92f56ea3fb0e9a35aa4b9aea48f 100644 +index b9cef93fe382b666bec04ca95eeaf2d8acbb3c40..de0c9798261c00a76c7c37c396379f42a44720be 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -150,7 +150,6 @@ import org.bukkit.event.entity.EntityTeleportEvent; +@@ -157,7 +157,6 @@ import org.bukkit.event.entity.EntityTeleportEvent; import org.bukkit.event.player.PlayerItemConsumeEvent; // CraftBukkit end @@ -1674,10 +1430,10 @@ index 85b4b24361e785acf75571ff98f924c00ae80748..1f3e0392f88a7cb3fb5c0767cdd1b4bc } diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 14281a4e72f49dc4eb2ca3da8479c1f81a3a175d..6a1adbc426a8c79c3fefc5a17509d9097ac9f3db 100644 +index 0d202ce8eb88bfdb8ca3306593d758fa483d8612..41acb79ec31f6f53589d698d1d4547485f0adc71 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -171,7 +171,6 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -172,7 +172,6 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl // Paper end - add paper world config public final com.destroystokyo.paper.antixray.ChunkPacketBlockController chunkPacketBlockController; // Paper - Anti-Xray @@ -1685,15 +1441,15 @@ index 14281a4e72f49dc4eb2ca3da8479c1f81a3a175d..6a1adbc426a8c79c3fefc5a17509d909 public static BlockPos lastPhysicsProblem; // Spigot private org.spigotmc.TickLimiter entityLimiter; private org.spigotmc.TickLimiter tileLimiter; -@@ -284,7 +283,6 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -342,7 +341,6 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl public void onBorderSetDamageSafeZOne(WorldBorder border, double safeZoneRadius) {} }); // CraftBukkit end - this.timings = new co.aikar.timings.WorldTimingsHandler(this); // Paper - code below can generate new world and access timings this.entityLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.entityMaxTickTime); this.tileLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.tileMaxTickTime); - this.chunkPacketBlockController = this.paperConfig().anticheat.antiXray.enabled ? new com.destroystokyo.paper.antixray.ChunkPacketBlockControllerAntiXray(this, executor) : com.destroystokyo.paper.antixray.ChunkPacketBlockController.NO_OPERATION_INSTANCE; // Paper - Anti-Xray -@@ -1252,15 +1250,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + this.entityLookup = new ca.spottedleaf.moonrise.patches.chunk_system.level.entity.dfl.DefaultEntityLookup(this); // Paper - rewrite chunk system +@@ -944,15 +942,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl ProfilerFiller gameprofilerfiller = this.getProfiler(); gameprofilerfiller.push("blockEntities"); @@ -1709,7 +1465,7 @@ index 14281a4e72f49dc4eb2ca3da8479c1f81a3a175d..6a1adbc426a8c79c3fefc5a17509d909 // Spigot start // Iterator iterator = this.blockEntityTickers.iterator(); boolean flag = this.tickRateManager().runsNormally(); -@@ -1289,9 +1284,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -983,9 +978,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl } this.blockEntityTickers.removeAll(toRemove); // Paper - Fix MC-117075 @@ -1740,10 +1496,10 @@ index ed8032495af9ce9c23419224814b8d27e4a97c17..189a6bd4967aba72e12170e091dbb5b7 } 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 cf8b8c8efd1c9c81eb5f02d75bd75875eb66771f..555d255a79c6136d0df3504218a0bc4681a5489f 100644 +index 45704653310efe9cb755a644674b54b8722c2c84..0c0b149a6cdfaf1de81bfbb92477fbb5c4a8a4bb 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java -@@ -103,13 +103,6 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -102,13 +102,6 @@ public class Block extends BlockBehaviour implements ItemLike { this != Blocks.STRUCTURE_BLOCK && this != Blocks.JIGSAW; } @@ -1777,18 +1533,18 @@ index c0563260277f9f4bd9ff08993b2efb4bca9a0c60..d93125ea494cb977b1616cabc90e2e7a private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry(); public CraftPersistentDataContainer persistentDataContainer; diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -index 14ee7b5b9b804bebd4e2a846b238547a28a36035..33673bde99023af6a136270091959cca69f514fb 100644 +index d388fbcbff63928f0e9140c02400a63ba8f19d9c..bfed0a72280631e6f20e6b5d493515c9b589db97 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -785,7 +785,6 @@ public class LevelChunk extends ChunkAccess { - this.chunkHolder.getEntityChunk().callEntitiesLoadEvent(); // Paper - rewrite chunk system +@@ -628,7 +628,6 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p + ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(this.locX, this.locZ).getEntityChunk().callEntitiesLoadEvent(); // Paper - rewrite chunk system if (this.needsDecoration) { - try (co.aikar.timings.Timing ignored = this.level.timings.chunkLoadPopulate.startTiming()) { // Paper this.needsDecoration = false; java.util.Random random = new java.util.Random(); random.setSeed(this.level.getSeed()); -@@ -805,7 +804,6 @@ public class LevelChunk extends ChunkAccess { +@@ -648,7 +647,6 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p } } server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkPopulateEvent(bukkitChunk)); @@ -1796,7 +1552,7 @@ index 14ee7b5b9b804bebd4e2a846b238547a28a36035..33673bde99023af6a136270091959cca } } } -@@ -1161,7 +1159,6 @@ public class LevelChunk extends ChunkAccess { +@@ -988,7 +986,6 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p ProfilerFiller gameprofilerfiller = LevelChunk.this.level.getProfiler(); gameprofilerfiller.push(this::getType); @@ -1804,7 +1560,7 @@ index 14ee7b5b9b804bebd4e2a846b238547a28a36035..33673bde99023af6a136270091959cca BlockState iblockdata = LevelChunk.this.getBlockState(blockposition); if (this.blockEntity.getType().isValid(iblockdata)) { -@@ -1187,9 +1184,6 @@ public class LevelChunk extends ChunkAccess { +@@ -1014,9 +1011,6 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p LevelChunk.this.removeBlockEntity(this.getPos()); // Paper end - Prevent block entity and entity crashes // Spigot start @@ -1814,30 +1570,6 @@ index 14ee7b5b9b804bebd4e2a846b238547a28a36035..33673bde99023af6a136270091959cca } } } -diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index 1155fc80c0292c8d7efb21dbac3d984176fcaa2d..77dc69ecec095b4d4129913846a12e5c86f21df5 100644 ---- a/src/main/java/org/bukkit/craftbukkit/Main.java -+++ b/src/main/java/org/bukkit/craftbukkit/Main.java -@@ -346,8 +346,8 @@ public class Main { - tryPreloadClass("org.jline.terminal.impl.MouseSupport"); - tryPreloadClass("org.jline.terminal.impl.MouseSupport$1"); - tryPreloadClass("org.jline.terminal.Terminal$MouseTracking"); -- tryPreloadClass("co.aikar.timings.TimingHistory"); -- tryPreloadClass("co.aikar.timings.TimingHistory$MinuteReport"); -+ // tryPreloadClass("co.aikar.timings.TimingHistory"); Leaves - remove timings -+ // tryPreloadClass("co.aikar.timings.TimingHistory$MinuteReport"); Leaves - remove timings - tryPreloadClass("io.netty.channel.AbstractChannelHandlerContext"); - tryPreloadClass("io.netty.channel.AbstractChannelHandlerContext$11"); - tryPreloadClass("io.netty.channel.AbstractChannelHandlerContext$12"); -@@ -360,7 +360,7 @@ public class Main { - tryPreloadClass("org.bukkit.craftbukkit.scheduler.CraftScheduler$1"); - tryPreloadClass("org.bukkit.craftbukkit.scheduler.CraftScheduler$2"); - tryPreloadClass("org.bukkit.craftbukkit.scheduler.CraftScheduler$3"); -- tryPreloadClass("org.bukkit.craftbukkit.scheduler.CraftScheduler$4"); -+ // tryPreloadClass("org.bukkit.craftbukkit.scheduler.CraftScheduler$4"); Leaves - remove timings - tryPreloadClass("org.slf4j.helpers.MessageFormatter"); - tryPreloadClass("org.slf4j.helpers.FormattingTuple"); - tryPreloadClass("org.slf4j.helpers.BasicMarker"); diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java index e85b9bb3f9c225d289a4959921970b9963881199..bb9383f1a457433f9db3e78d7913616280925200 100644 --- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java @@ -1973,7 +1705,7 @@ index b3e1adeb932da9b3bed16acd94e2f16da48a7c72..e9798517b9211c50a20ea5c69603aab3 } } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index f99353a60e3f236735ef6e2e6f13381b50ae9b7b..5e42a3392fa03813e3e58e80299625993c560396 100644 +index d70c5546c8bd6f364fad9b24880b6867efdab644..5735e6ab4c3530cd296580f9e8dcb107607929b1 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -220,7 +220,6 @@ public final class CraftMagicNumbers implements UnsafeValues { @@ -1985,7 +1717,7 @@ index f99353a60e3f236735ef6e2e6f13381b50ae9b7b..5e42a3392fa03813e3e58e8029962599 // Paper end diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index 3283ed99c35ffed6805567705e0518d9f84feedc..e32e4ffa222fe72c3d3152a91057113c99d3b122 100644 +index bf2d18f74b0f0da7c3c30310c74224a1c0853564..621bda8248e35f5a5730f89a4bcfbe6615ed969c 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -34,7 +34,6 @@ import net.minecraft.world.entity.projectile.FireworkRocketEntity; diff --git a/patches/server/0004-Leaves-Server-Utils.patch b/patches/server/0004-Leaves-Server-Utils.patch index 2b2e63b7..0771227e 100644 --- a/patches/server/0004-Leaves-Server-Utils.patch +++ b/patches/server/0004-Leaves-Server-Utils.patch @@ -31,10 +31,10 @@ index 46954db7ecd35ac4018fdf476df7c8020d7ce6c8..044c51ebb058fc36074fd178929e3279 public PlayerAreaMap() { super(); diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 7ef9f67d27cc240191dd5d07e8dcf5fbdebe1049..864e6d223de55f42122485bf6a3c84bbb636479c 100644 +index 83f3ffdd8fa901b3de580d2359cdb5ead0d762cb..9729b3a7ce3027ff4eb02fcb908768d24f74a5f8 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -425,6 +425,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -430,6 +430,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess private UUID originWorld; public boolean freezeLocked = false; // Paper - Freeze Tick Lock API public boolean fixedPose = false; // Paper - Expand Pose API @@ -42,7 +42,7 @@ index 7ef9f67d27cc240191dd5d07e8dcf5fbdebe1049..864e6d223de55f42122485bf6a3c84bb public void setOrigin(@javax.annotation.Nonnull Location location) { this.origin = location.toVector(); -@@ -2554,6 +2555,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2453,6 +2454,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess nbttagcompound.putBoolean("Paper.FreezeLock", true); } // Paper end @@ -50,7 +50,7 @@ index 7ef9f67d27cc240191dd5d07e8dcf5fbdebe1049..864e6d223de55f42122485bf6a3c84bb return nbttagcompound; } catch (Throwable throwable) { CrashReport crashreport = CrashReport.forThrowable(throwable, "Saving entity NBT"); -@@ -2701,6 +2703,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2600,6 +2602,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess freezeLocked = nbt.getBoolean("Paper.FreezeLock"); } // Paper end @@ -62,7 +62,7 @@ index 7ef9f67d27cc240191dd5d07e8dcf5fbdebe1049..864e6d223de55f42122485bf6a3c84bb } catch (Throwable throwable) { CrashReport crashreport = CrashReport.forThrowable(throwable, "Loading entity NBT"); -@@ -5000,4 +5007,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4821,4 +4828,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return ((net.minecraft.server.level.ServerChunkCache) level.getChunkSource()).isPositionTicking(this); } // Paper end - Expose entity id counter @@ -75,10 +75,10 @@ index 7ef9f67d27cc240191dd5d07e8dcf5fbdebe1049..864e6d223de55f42122485bf6a3c84bb } diff --git a/src/main/java/org/leavesmc/leaves/LeavesLogger.java b/src/main/java/org/leavesmc/leaves/LeavesLogger.java new file mode 100644 -index 0000000000000000000000000000000000000000..730174b8c26375510c919fd841dc9371446ae8f2 +index 0000000000000000000000000000000000000000..47347a3bdab2ff9818bf8198291d2dabec7da8c6 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/LeavesLogger.java -@@ -0,0 +1,16 @@ +@@ -0,0 +1,24 @@ +package org.leavesmc.leaves; + +import org.bukkit.Bukkit; @@ -94,6 +94,14 @@ index 0000000000000000000000000000000000000000..730174b8c26375510c919fd841dc9371 + setParent(Bukkit.getLogger()); + setLevel(Level.ALL); + } ++ ++ public void severe(String msg, Exception exception) { ++ this.severe(msg + ", " + exception.getCause() + ": " + exception.getMessage()); ++ } ++ ++ public void warning(String msg, Exception exception) { ++ this.warning(msg + ", " + exception.getCause() + ": " + exception.getMessage()); ++ } +} diff --git a/src/main/java/org/leavesmc/leaves/util/AsyncExecutor.java b/src/main/java/org/leavesmc/leaves/util/AsyncExecutor.java new file mode 100644 @@ -289,3 +297,109 @@ index 0000000000000000000000000000000000000000..440c4d903e145229bc54eb5b6f3578fd + return backingMap.size(); + } +} +diff --git a/src/main/java/org/leavesmc/leaves/util/MathUtils.java b/src/main/java/org/leavesmc/leaves/util/MathUtils.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a6a4fd61644815a7fb01ab1a5844a34f39e57e6d +--- /dev/null ++++ b/src/main/java/org/leavesmc/leaves/util/MathUtils.java +@@ -0,0 +1,100 @@ ++package org.leavesmc.leaves.util; ++ ++import org.bukkit.util.NumberConversions; ++import org.bukkit.util.Vector; ++ ++import java.util.regex.Pattern; ++ ++public class MathUtils { ++ // Lag ? ++ public static void clean(Vector vector) { ++ if (!NumberConversions.isFinite(vector.getX())) vector.setX(0); ++ if (!NumberConversions.isFinite(vector.getY())) vector.setY(0); ++ if (!NumberConversions.isFinite(vector.getZ())) vector.setZ(0); ++ } ++ ++ private static final Pattern numericPattern = Pattern.compile("^-?[1-9]\\d*$|^0$"); ++ ++ public static boolean isNumeric(String str) { ++ return numericPattern.matcher(str).matches(); ++ } ++ ++ public static float[] fetchYawPitch(Vector dir) { ++ double x = dir.getX(); ++ double z = dir.getZ(); ++ ++ float[] out = new float[2]; ++ ++ if (x == 0.0D && z == 0.0D) { ++ out[1] = (float) (dir.getY() > 0.0D ? -90 : 90); ++ } else { ++ double theta = Math.atan2(-x, z); ++ out[0] = (float) Math.toDegrees((theta + 6.283185307179586D) % 6.283185307179586D); ++ ++ double x2 = NumberConversions.square(x); ++ double z2 = NumberConversions.square(z); ++ double xz = Math.sqrt(x2 + z2); ++ out[1] = (float) Math.toDegrees(Math.atan(-dir.getY() / xz)); ++ } ++ ++ return out; ++ } ++ ++ public static float fetchPitch(Vector dir) { ++ double x = dir.getX(); ++ double z = dir.getZ(); ++ ++ float result; ++ ++ if (x == 0.0D && z == 0.0D) { ++ result = (float) (dir.getY() > 0.0D ? -90 : 90); ++ } else { ++ double x2 = NumberConversions.square(x); ++ double z2 = NumberConversions.square(z); ++ double xz = Math.sqrt(x2 + z2); ++ result = (float) Math.toDegrees(Math.atan(-dir.getY() / xz)); ++ } ++ ++ return result; ++ } ++ ++ public static Vector getDirection(double rotX, double rotY) { ++ Vector vector = new Vector(); ++ ++ rotX = Math.toRadians(rotX); ++ rotY = Math.toRadians(rotY); ++ ++ double xz = Math.abs(Math.cos(rotY)); ++ ++ vector.setX(-Math.sin(rotX) * xz); ++ vector.setZ(Math.cos(rotX) * xz); ++ vector.setY(-Math.sin(rotY)); ++ ++ return vector; ++ } ++ ++ private static final int[] MULTIPLY_DE_BRUIJN_BIT_POSITION = new int[]{0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9}; ++ ++ public static int floorLog2(int value) { ++ return ceilLog2(value) - (isPowerOfTwo(value) ? 0 : 1); ++ } ++ ++ public static int ceilLog2(int value) { ++ value = isPowerOfTwo(value) ? value : smallestEncompassingPowerOfTwo(value); ++ return MULTIPLY_DE_BRUIJN_BIT_POSITION[(int) ((long) value * 125613361L >> 27) & 31]; ++ } ++ ++ public static boolean isPowerOfTwo(int value) { ++ return value != 0 && (value & value - 1) == 0; ++ } ++ ++ public static int smallestEncompassingPowerOfTwo(int value) { ++ int i = value - 1; ++ i |= i >> 1; ++ i |= i >> 2; ++ i |= i >> 4; ++ i |= i >> 8; ++ i |= i >> 16; ++ return i + 1; ++ } ++} diff --git a/patches/server/0005-Update-version-fetcher-repo.patch b/patches/server/0005-Update-version-fetcher-repo.patch index 2d24d9cc..7d4211c0 100644 --- a/patches/server/0005-Update-version-fetcher-repo.patch +++ b/patches/server/0005-Update-version-fetcher-repo.patch @@ -27,7 +27,7 @@ index 532306cacd52579cdf37e4aca25887b1ed3ba6a1..917ffaae401f3374d07d7fb7c024234a if (data == null) { return null; diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 5e42a3392fa03813e3e58e80299625993c560396..1fed83a95ae6f3fc805fe5c2e303f4089de194e6 100644 +index 5735e6ab4c3530cd296580f9e8dcb107607929b1..1d07f5026243196cff49a81635bd17373b02e591 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -503,7 +503,7 @@ public final class CraftMagicNumbers implements UnsafeValues { @@ -41,10 +41,10 @@ index 5e42a3392fa03813e3e58e80299625993c560396..1fed83a95ae6f3fc805fe5c2e303f408 @Override diff --git a/src/main/java/org/leavesmc/leaves/util/LeavesVersionFetcher.java b/src/main/java/org/leavesmc/leaves/util/LeavesVersionFetcher.java new file mode 100644 -index 0000000000000000000000000000000000000000..b102e2f5cf541b8ced87cf1ec7469ea90da4bb72 +index 0000000000000000000000000000000000000000..83f9bf9464ded48858b816107b4f14a065d80399 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/util/LeavesVersionFetcher.java -@@ -0,0 +1,126 @@ +@@ -0,0 +1,128 @@ +package org.leavesmc.leaves.util; + +import com.destroystokyo.paper.PaperVersionFetcher; @@ -89,6 +89,8 @@ index 0000000000000000000000000000000000000000..b102e2f5cf541b8ced87cf1ec7469ea9 + final ServerBuildInfo build = ServerBuildInfo.buildInfo(); + if (build.buildNumber().isEmpty() && build.gitCommit().isEmpty()) { + updateMessage = text("You are running a development version without access to version information", color(0xFF5300)); ++ } else if (build.buildNumber().isEmpty()) { ++ updateMessage = text("You are running a development version form CI", color(0xFF5300)); + } else { + updateMessage = getUpdateStatusMessage("LeavesMC/Leaves", build); + } @@ -160,7 +162,7 @@ index 0000000000000000000000000000000000000000..b102e2f5cf541b8ced87cf1ec7469ea9 + + try { + try (BufferedReader reader = Resources.asCharSource( -+ URI.create("https://api.leavesmc.org/v2/projects/leaves/versions/" + build.minecraftVersionId() + "/differ/" + build.gitCommit()).toURL(), ++ URI.create("https://api.leavesmc.org/v2/projects/leaves/versions/" + build.minecraftVersionId() + "/differ/" + build.gitCommit().get()).toURL(), + Charsets.UTF_8 + ).openBufferedStream()) { + return Integer.parseInt(reader.readLine()); diff --git a/patches/server/0006-Leaves-Server-Config-And-Command.patch b/patches/server/0006-Leaves-Server-Config-And-Command.patch index c978141e..48835967 100644 --- a/patches/server/0006-Leaves-Server-Config-And-Command.patch +++ b/patches/server/0006-Leaves-Server-Config-And-Command.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Leaves Server Config And Command diff --git a/build.gradle.kts b/build.gradle.kts -index 16b742b5131376ceca04570dd4c088caff62e677..fe1f6f1a97ab35c44f596596d16765b8b81753a9 100644 +index 5025c5df3ee6ed84106782e3f9228874bebe63ca..268193499b9f1fae0c01963e8004a3e7422f77ca 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -212,6 +212,14 @@ tasks.registerRunTask("runDevServer") { @@ -23,23 +23,11 @@ index 16b742b5131376ceca04570dd4c088caff62e677..fe1f6f1a97ab35c44f596596d16765b8 tasks.registerRunTask("runBundler") { description = "Spin up a test server from the Mojang mapped bundler jar" classpath(rootProject.tasks.named("createMojmapBundlerJar").flatMap { it.outputZip }) -diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 1f973ed9bb9c753b81979085a6fea45b65165fa3..59cc1855d5bebbcaa8f6afc39e91ae0698adcf73 100644 ---- a/src/main/java/net/minecraft/server/MinecraftServer.java -+++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1147,6 +1147,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { -+ snowballAndEggCanKnockback = config.getBoolean("settings.snowball-and-egg-can-knockback-player", snowballAndEggCanKnockback); -+ fakeplayerSupport = config.getBoolean("settings.fakeplayer.enable", fakeplayerSupport); -+ unableFakeplayerNames = (List) config.getList("settings.fakeplayer.unable-fakeplayer-names", unableFakeplayerNames); -+ shearsInDispenserCanZeroAmount = config.getBoolean("settings.shears-in-dispenser-can-zero-amount", shearsInDispenserCanZeroAmount); -+ redstoneShearsWrench = config.getBoolean("settings.redstone-shears-wrench", redstoneShearsWrench); -+ buddingAmethystCanPushByPiston = config.getBoolean("settings.budding-amethyst-can-push-by-piston", buddingAmethystCanPushByPiston); -+ spectatorDontGetAdvancement = config.getBoolean("settings.spectator-dont-get-advancement", spectatorDontGetAdvancement); -+ stickChangeArmorStandArmStatus = config.getBoolean("settings.stick-change-armorstand-arm-status", stickChangeArmorStandArmStatus); -+ noChatSign = config.getBoolean("settings.no-chat-sign", noChatSign); -+ -+ config.set("settings.snowball-and-egg-can-knockback-player", null); -+ config.set("settings.player-can-edit-sign", null); -+ config.set("settings.fakeplayer", null); -+ config.set("settings.shears-in-dispenser-can-zero-amount", null); -+ config.set("settings.redstone-shears-wrench", null); -+ config.set("settings.budding-amethyst-can-push-by-piston", null); -+ config.set("settings.spectator-dont-get-advancement", null); -+ config.set("settings.stick-change-armorstand-arm-status", null); -+ config.set("settings.no-chat-sign", null); -+ } -+ -+ case 2 -> { -+ config.set("settings.modify.player-can-edit-sign", null); -+ config.set("settings.performance.skip-clone-loot-parameters", null); -+ } -+ -+ case 3 -> { -+ boolean carpetAlternative = config.getBoolean("settings.protocol.carpet-alternative-block-placement", false); -+ alternativeBlockPlacement = carpetAlternative ? AlternativePlaceType.CARPET : AlternativePlaceType.NONE; -+ config.set("settings.protocol.carpet-alternative-block-placement", null); -+ } -+ -+ case 4 -> { -+ shearsInDispenserCanZeroAmount = config.getBoolean("settings.modify.shears-in-dispenser-can-zero-amount", shearsInDispenserCanZeroAmount); -+ instantBlockUpdaterReintroduced = config.getBoolean("settings.modify.instant-block-updater-reintroduced", instantBlockUpdaterReintroduced); -+ redstoneDontCantOnTrapDoor = config.getBoolean("settings.modify.redstone-wire-dont-connect-if-on-trapdoor", redstoneDontCantOnTrapDoor); -+ mendingCompatibilityInfinity = config.getBoolean("settings.modify.mending-compatibility-infinity", mendingCompatibilityInfinity); -+ zeroTickPlants = config.getBoolean("settings.modify.zero-tick-plants", zeroTickPlants); -+ -+ config.set("settings.modify.shears-in-dispenser-can-zero-amount", null); -+ config.set("settings.modify.instant-block-updater-reintroduced", null); -+ config.set("settings.modify.redstone-wire-dont-connect-if-on-trapdoor", null); -+ config.set("settings.modify.mending-compatibility-infinity", null); -+ config.set("settings.modify.zero-tick-plants", null); -+ } -+ } -+ } -+ } -+ + public static void registerCommand(String name, Command command) { + MinecraftServer.getServer().server.getCommandMap().register(name, "leaves", command); + MinecraftServer.getServer().server.syncCommands(); + } + + public static void unregisterCommand(String name) { -+ name = name.toLowerCase(java.util.Locale.ENGLISH).trim(); ++ name = name.toLowerCase(Locale.ENGLISH).trim(); + MinecraftServer.getServer().server.getCommandMap().getKnownCommands().remove(name); + MinecraftServer.getServer().server.getCommandMap().getKnownCommands().remove("leaves:" + name); + MinecraftServer.getServer().server.syncCommands(); @@ -254,6 +183,7 @@ index 0000000000000000000000000000000000000000..5809475f59efe62e18a0905532810e54 + + // Leaves start - modify - fakeplayer + ++ @RemovedConfig(name = "enable", category = "fakeplayer", transform = true) + @GlobalConfig(name = "enable", category = {"modify", "fakeplayer"}, verify = FakeplayerVerify.class) + public static boolean fakeplayerSupport = true; + @@ -270,6 +200,7 @@ index 0000000000000000000000000000000000000000..5809475f59efe62e18a0905532810e54 + } + } + ++ @RemovedConfig(name = "unable-fakeplayer-names", category = "fakeplayer", transform = true) + @GlobalConfig(name = "unable-fakeplayer-names", category = {"modify", "fakeplayer"}, verify = ConfigVerify.ListConfigVerify.class) + public static List unableFakeplayerNames = List.of("player-name"); + @@ -307,13 +238,22 @@ index 0000000000000000000000000000000000000000..5809475f59efe62e18a0905532810e54 + } + } + ++ @GlobalConfig(name = "use-action", category = {"modify", "fakeplayer"}) ++ public static boolean fakeplayerUseAction = true; ++ ++ @GlobalConfig(name = "modify-config", category = {"modify", "fakeplayer"}) ++ public static boolean fakeplayerModifyConfig = false; ++ + // Leaves end - modify - fakeplayer + + // Leaves start - modify - minecraft-old + ++ @RemovedConfig(name = "shears-in-dispenser-can-zero-amount", category = {}, transform = true) ++ @RemovedConfig(name = "shears-in-dispenser-can-zero-amount", category = "modify", transform = true) + @GlobalConfig(name = "shears-in-dispenser-can-zero-amount", category = {"modify", "minecraft-old"}) + public static boolean shearsInDispenserCanZeroAmount = false; + ++ @RemovedConfig(name = "instant-block-updater-reintroduced", category = "modify", transform = true) + @GlobalConfig(name = "instant-block-updater-reintroduced", category = {"modify", "minecraft-old"}, lock = true) + public static boolean instantBlockUpdaterReintroduced = false; + @@ -340,12 +280,11 @@ index 0000000000000000000000000000000000000000..5809475f59efe62e18a0905532810e54 + @GlobalConfig(name = "crafter-1gt-delay", category = {"modify", "minecraft-old"}) + public static boolean crafter1gt = false; + ++ @RemovedConfig(name = "redstone-wire-dont-connect-if-on-trapdoor", category = "modify", transform = true) + @GlobalConfig(name = "redstone-wire-dont-connect-if-on-trapdoor", category = {"modify", "minecraft-old"}) + public static boolean redstoneDontCantOnTrapDoor = false; + -+ @GlobalConfig(name = "mending-compatibility-infinity", category = {"modify", "minecraft-old"}) -+ public static boolean mendingCompatibilityInfinity = false; -+ ++ @RemovedConfig(name = "zero-tick-plants", category = "modify", transform = true) + @GlobalConfig(name = "zero-tick-plants", category = {"modify", "minecraft-old"}) + public static boolean zeroTickPlants = false; + @@ -356,13 +295,19 @@ index 0000000000000000000000000000000000000000..5809475f59efe62e18a0905532810e54 + private static class RNGFishingVerify extends ConfigVerify.BooleanConfigVerify { + @Override + public String check(Boolean old, Boolean value) { -+// LeavesFeatureSet.register(LeavesFeature.of("rng_fishing", value)); // Leaves - remove protocol temporarily ++ LeavesFeatureSet.register(LeavesFeature.of("rng_fishing", value)); + return null; + } + } + -+ @GlobalConfig(name = "protection-stacking", category = {"modify", "minecraft-old"}) -+ public static boolean protectionStacking = false; ++ @GlobalConfig(name = "allow-grindstone-overstacking", category = {"modify", "minecraft-old"}) ++ public static boolean allowGrindstoneOverstacking = false; ++ ++ @GlobalConfig(name = "allow-entity-portal-with-passenger", category = {"modify", "minecraft-old"}) ++ public static boolean allowEntityPortalWithPassenger = true; ++ ++ @GlobalConfig(name = "disable-gateway-portal-entity-ticking", category = {"modify", "minecraft-old"}) ++ public static boolean disableGatewayPortalEntityTicking = false; + + // Leaves end - modify - minecraft-old + @@ -388,18 +333,23 @@ index 0000000000000000000000000000000000000000..5809475f59efe62e18a0905532810e54 + + // Leaves end - modify - elytra-aeronautics + ++ @RemovedConfig(name = "redstone-shears-wrench", category = {}, transform = true) + @GlobalConfig(name = "redstone-shears-wrench", category = "modify") + public static boolean redstoneShearsWrench = true; + ++ @RemovedConfig(name = "budding-amethyst-can-push-by-piston", category = {}, transform = true) + @GlobalConfig(name = "budding-amethyst-can-push-by-piston", category = "modify") + public static boolean buddingAmethystCanPushByPiston = false; + ++ @RemovedConfig(name = "spectator-dont-get-advancement", category = {}, transform = true) + @GlobalConfig(name = "spectator-dont-get-advancement", category = "modify") + public static boolean spectatorDontGetAdvancement = false; + ++ @RemovedConfig(name = "stick-change-armorstand-arm-status", category = {}, transform = true) + @GlobalConfig(name = "stick-change-armorstand-arm-status", category = "modify") + public static boolean stickChangeArmorStandArmStatus = true; + ++ @RemovedConfig(name = "snowball-and-egg-can-knockback-player", category = {}, transform = true) + @GlobalConfig(name = "snowball-and-egg-can-knockback-player", category = "modify") + public static boolean snowballAndEggCanKnockback = true; + @@ -460,7 +410,7 @@ index 0000000000000000000000000000000000000000..5809475f59efe62e18a0905532810e54 + private static class UseVanillaRandomVerify extends ConfigVerify.BooleanConfigVerify { + @Override + public String check(Boolean old, Boolean value) { -+// LeavesFeatureSet.register(LeavesFeature.of("use_vanilla_random", value)); // Leaves - remove protocol temporarily ++ LeavesFeatureSet.register(LeavesFeature.of("use_vanilla_random", value)); + return null; + } + } @@ -471,9 +421,19 @@ index 0000000000000000000000000000000000000000..5809475f59efe62e18a0905532810e54 + @GlobalConfig(name = "bedrock-break-list", category = "modify", lock = true) + public static boolean bedrockBreakList = false; + -+ @GlobalConfig(name = "disable-distance-check-for-use-item", category = "modify") ++ @GlobalConfig(name = "disable-distance-check-for-use-item", category = "modify", verify = DisableDistanceCheckForUseItemVerify.class) + public static boolean disableDistanceCheckForUseItem = false; + ++ private static class DisableDistanceCheckForUseItemVerify extends ConfigVerify.BooleanConfigVerify { ++ @Override ++ public String check(Boolean old, Boolean value) { ++ if (alternativeBlockPlacement != AlternativePlaceType.NONE && !value) { ++ return "alternative-block-placement is enable, disable-distance-check-for-use-item always need true"; ++ } ++ return null; ++ } ++ } ++ + @GlobalConfig(name = "no-feather-falling-trample", category = "modify") + public static boolean noFeatherFallingTrample = false; + @@ -512,7 +472,7 @@ index 0000000000000000000000000000000000000000..5809475f59efe62e18a0905532810e54 + private static class LavaRiptideVerify extends ConfigVerify.BooleanConfigVerify { + @Override + public String check(Boolean old, Boolean value) { -+// LeavesFeatureSet.register(LeavesFeature.of("lava_riptide", value)); // Leaves - remove protocol temporarily ++ LeavesFeatureSet.register(LeavesFeature.of("lava_riptide", value)); + return null; + } + } @@ -610,6 +570,15 @@ index 0000000000000000000000000000000000000000..5809475f59efe62e18a0905532810e54 + @RemovedConfig(name = "tick-command", category = "modify") + public static boolean tickCommand = false; + ++ @RemovedConfig(name = "player-can-edit-sign", category = "modify") ++ public static boolean playerCanEditSign = false; ++ ++ @RemovedConfig(name = "mending-compatibility-infinity", category = {"modify", "minecraft-old"}) ++ public static boolean mendingCompatibilityInfinity = false; ++ ++ @RemovedConfig(name = "protection-stacking", category = {"modify", "minecraft-old"}) ++ public static boolean protectionStacking = false; ++ + // Leaves end - modify - removed + + // Leaves end - modify @@ -624,9 +593,6 @@ index 0000000000000000000000000000000000000000..5809475f59efe62e18a0905532810e54 + @GlobalConfig(name = "inventory-contains-iterators", category = {"performance", "remove"}) + public static boolean removeInventoryContainsIterators = true; + -+ @RemovedConfig(name = "get-nearby-players-streams", category = {"performance", "remove"}) -+ public static boolean removeGetNearPlayerStreams = true; -+ + @GlobalConfig(name = "range-check-streams-and-iterators", category = {"performance", "remove"}) + public static boolean removeRangeCheckStreams = true; + @@ -647,18 +613,12 @@ index 0000000000000000000000000000000000000000..5809475f59efe62e18a0905532810e54 + @GlobalConfig(name = "enable-suffocation-optimization", category = "performance") + public static boolean enableSuffocationOptimization = true; + -+ @RemovedConfig(name = "strip-raytracing-for-entity", category = "performance") -+ public static boolean entityStripRaytracing = true; -+ + @GlobalConfig(name = "check-spooky-season-once-an-hour", category = "performance") + public static boolean checkSpookySeasonOnceAnHour = true; + + @GlobalConfig(name = "optimize-chunk-ticking", category = "performance", lock = true) + public static boolean optimizeChunkTicking = true; + -+ @RemovedConfig(name = "skip-poi-find-in-vehicle", category = "performance") -+ public static boolean skipPOIFindingInVehicle = true; -+ + @GlobalConfig(name = "entity-target-find-optimization", category = "performance") + public static boolean entityTargetFindingOptimization = true; + @@ -678,7 +638,7 @@ index 0000000000000000000000000000000000000000..5809475f59efe62e18a0905532810e54 + public static boolean biomeTemperaturesUseAgingCache = true; + + @GlobalConfig(name = "reduce-entity-fluid-lookup", category = "performance") -+ public static boolean reduceEntityFluidLookup = true; ++ public static boolean reduceEntityFluidLookup = false; + + @GlobalConfig(name = "reduce-chuck-load-and-lookup", category = "performance") + public static boolean reduceChuckLoadAndLookup = true; @@ -692,9 +652,6 @@ index 0000000000000000000000000000000000000000..5809475f59efe62e18a0905532810e54 + @GlobalConfig(name = "faster-chunk-serialization", category = "performance") + public static boolean fasterChunkSerialization = true; + -+ @GlobalConfig(name = "optimize-world-generation-and-block-access", category = "performance") -+ public static boolean optimizeWorldGenerationAccess = true; -+ + @GlobalConfig(name = "cache-world-generator-sea-level", category = "performance") + public static boolean cacheWorldGeneratorSeaLevel = true; + @@ -757,6 +714,21 @@ index 0000000000000000000000000000000000000000..5809475f59efe62e18a0905532810e54 + @RemovedConfig(name = "fix-paper-9372", category = {"performance", "fix"}) + public static boolean fixPaper9372 = true; + ++ @RemovedConfig(name = "skip-clone-loot-parameters", category = "performance") ++ public static boolean skipCloneLootParameters = true; ++ ++ @RemovedConfig(name = "skip-poi-find-in-vehicle", category = "performance") ++ public static boolean skipPOIFindingInVehicle = true; ++ ++ @RemovedConfig(name = "strip-raytracing-for-entity", category = "performance") ++ public static boolean entityStripRaytracing = true; ++ ++ @RemovedConfig(name = "get-nearby-players-streams", category = {"performance", "remove"}) ++ public static boolean removeGetNearPlayerStreams = true; ++ ++ @RemovedConfig(name = "optimize-world-generation-and-block-access", category = "performance") ++ public static boolean optimizeWorldGenerationAccess = true; ++ + // Leaves end - performance - removed + + // Leaves end - performance @@ -774,7 +746,7 @@ index 0000000000000000000000000000000000000000..5809475f59efe62e18a0905532810e54 + private static class MSPTSyncVerify extends ConfigVerify.BooleanConfigVerify { + @Override + public String check(Boolean old, Boolean value) { -+// LeavesFeatureSet.register(LeavesFeature.of("mspt_sync", value)); // Leaves - remove protocol temporarily ++ LeavesFeatureSet.register(LeavesFeature.of("mspt_sync", value)); + return null; + } + } @@ -806,7 +778,7 @@ index 0000000000000000000000000000000000000000..5809475f59efe62e18a0905532810e54 + @Override + public String check(Boolean old, Boolean value) { + if (value) { -+// org.leavesmc.leaves.protocol.syncmatica.SyncmaticaProtocol.init(); // Leaves - remove protocol temporarily ++ org.leavesmc.leaves.protocol.syncmatica.SyncmaticaProtocol.init(); + } + return null; + } @@ -846,6 +818,12 @@ index 0000000000000000000000000000000000000000..5809475f59efe62e18a0905532810e54 + } + + private static class AlternativePlaceVerify extends ConfigVerify.EnumConfigVerify { ++ @Override ++ public void runAfterLoader(Enum value) { ++ if (value != AlternativePlaceType.NONE) { ++ disableDistanceCheckForUseItem = true; ++ } ++ } + } + + @GlobalConfig(name = "appleskin-protocol", category = "protocol") @@ -922,6 +900,7 @@ index 0000000000000000000000000000000000000000..5809475f59efe62e18a0905532810e54 + @GlobalConfig(name = "disable-method-profiler", category = "misc") + public static boolean disableMethodProfiler = true; + ++ @RemovedConfig(name = "no-chat-sign", category = {}, transform = true) + @GlobalConfig(name = "no-chat-sign", category = "misc") + public static boolean noChatSign = true; + @@ -950,7 +929,7 @@ index 0000000000000000000000000000000000000000..5809475f59efe62e18a0905532810e54 + public static boolean bstatsPrivacyMode = false; + + @GlobalConfig(name = "force-minecraft-command", category = "misc") -+ public static boolean forceMinecraftCommand = true; ++ public static boolean forceMinecraftCommand = false; + + @GlobalConfig(name = "leaves-packet-event", category = "misc") + public static boolean leavesPacketEvent = true; @@ -1019,10 +998,10 @@ index 0000000000000000000000000000000000000000..5809475f59efe62e18a0905532810e54 +} diff --git a/src/main/java/org/leavesmc/leaves/command/CommandArgument.java b/src/main/java/org/leavesmc/leaves/command/CommandArgument.java new file mode 100644 -index 0000000000000000000000000000000000000000..381cd8b33137a5b7dc688306b56805f35c57012a +index 0000000000000000000000000000000000000000..2f0e6671dd8bfe4f320eab92c5f5bbc10abc3b05 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/command/CommandArgument.java -@@ -0,0 +1,43 @@ +@@ -0,0 +1,49 @@ +package org.leavesmc.leaves.command; + +import org.jetbrains.annotations.NotNull; @@ -1057,6 +1036,12 @@ index 0000000000000000000000000000000000000000..381cd8b33137a5b7dc688306b56805f3 + return this; + } + ++ public CommandArgument setAllTabComplete(List> tabComplete) { ++ this.tabComplete.clear(); ++ this.tabComplete.addAll(tabComplete); ++ return this; ++ } ++ + public CommandArgumentResult parse(int index, String @NotNull [] args) { + Object[] result = new Object[argumentTypes.size()]; + Arrays.fill(result, null); @@ -1068,10 +1053,10 @@ index 0000000000000000000000000000000000000000..381cd8b33137a5b7dc688306b56805f3 +} diff --git a/src/main/java/org/leavesmc/leaves/command/CommandArgumentResult.java b/src/main/java/org/leavesmc/leaves/command/CommandArgumentResult.java new file mode 100644 -index 0000000000000000000000000000000000000000..e50ca0473ab4d40e2623ab15f8566276cc14f4e7 +index 0000000000000000000000000000000000000000..6549037cf0bb8460fef8bef41d2335be079b9e9b --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/command/CommandArgumentResult.java -@@ -0,0 +1,62 @@ +@@ -0,0 +1,61 @@ +package org.leavesmc.leaves.command; + +import net.minecraft.core.BlockPos; @@ -1132,7 +1117,6 @@ index 0000000000000000000000000000000000000000..e50ca0473ab4d40e2623ab15f8566276 + return null; + } + } -+ +} diff --git a/src/main/java/org/leavesmc/leaves/command/CommandArgumentType.java b/src/main/java/org/leavesmc/leaves/command/CommandArgumentType.java new file mode 100644 @@ -1179,7 +1163,7 @@ index 0000000000000000000000000000000000000000..dccd32714b86d1fa3e0a9b10a23f765f +} diff --git a/src/main/java/org/leavesmc/leaves/command/LeavesCommand.java b/src/main/java/org/leavesmc/leaves/command/LeavesCommand.java new file mode 100644 -index 0000000000000000000000000000000000000000..b9e2bdb034dcd5119680ddea44a1eda11a0189b2 +index 0000000000000000000000000000000000000000..ebd62b1d3a60d3e22e3849047293e1f62533eae7 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/command/LeavesCommand.java @@ -0,0 +1,118 @@ @@ -1195,9 +1179,9 @@ index 0000000000000000000000000000000000000000..b9e2bdb034dcd5119680ddea44a1eda1 +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionDefault; +import org.bukkit.plugin.PluginManager; -+import org.checkerframework.checker.nullness.qual.Nullable; +import org.jetbrains.annotations.NotNull; -+import org.leavesmc.leaves.command.subcommands.ConfigCommand; ++import org.jetbrains.annotations.Nullable; ++import org.leavesmc.leaves.command.subcommands.*; + +import java.util.ArrayList; +import java.util.Arrays; @@ -1615,10 +1599,10 @@ index 0000000000000000000000000000000000000000..67d4365d25714c3732274e5ab21981a3 +} diff --git a/src/main/java/org/leavesmc/leaves/config/GlobalConfigManager.java b/src/main/java/org/leavesmc/leaves/config/GlobalConfigManager.java new file mode 100644 -index 0000000000000000000000000000000000000000..828bbd8b048df8e48ef007d2c1eefe1458b4b2c3 +index 0000000000000000000000000000000000000000..0addf5a2f5e015b73b8a02e8f3eef79790eb4587 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/config/GlobalConfigManager.java -@@ -0,0 +1,188 @@ +@@ -0,0 +1,192 @@ +package org.leavesmc.leaves.config; + +import org.bukkit.Bukkit; @@ -1647,8 +1631,7 @@ index 0000000000000000000000000000000000000000..828bbd8b048df8e48ef007d2c1eefe14 + if (Modifier.isStatic(field.getModifiers())) { + field.setAccessible(true); + -+ RemovedConfig removedConfig = field.getAnnotation(RemovedConfig.class); -+ if (removedConfig != null) { ++ for (RemovedConfig removedConfig : field.getAnnotationsByType(RemovedConfig.class)) { + RemovedVerifiedConfig verifiedConfig = RemovedVerifiedConfig.build(removedConfig, field); + verifiedConfig.run(); + } @@ -1671,7 +1654,7 @@ index 0000000000000000000000000000000000000000..828bbd8b048df8e48ef007d2c1eefe14 + + try { + Object savedValue = LeavesConfig.config.get(verifiedConfig.path); -+ if (isEnumConfig) { ++ if (isEnumConfig && savedValue != null) { + savedValue = verify.convert(savedValue.toString()); + } + String checkInfo = verify.check(null, savedValue); @@ -1713,18 +1696,23 @@ index 0000000000000000000000000000000000000000..828bbd8b048df8e48ef007d2c1eefe14 + public void run() { + if (config.transform()) { + if (LeavesConfig.config.contains(path)) { -+ String string = LeavesConfig.config.get(path).toString(); -+ try { -+ Object object = convert.convert(string); -+ field.set(null, object); -+ } catch (Exception e) { -+ e.printStackTrace(); ++ Object savedValue = LeavesConfig.config.get(path); ++ if (savedValue != null) { ++ try { ++ Object object = convert.convert(savedValue.toString()); ++ field.set(null, object); ++ } catch (Exception e) { ++ LeavesLogger.LOGGER.warning("Failure to load leaves config" + path, e); ++ } ++ } else { ++ LeavesLogger.LOGGER.warning("Failed to convert saved value for " + path + ", reset to default"); + } + } + } + LeavesConfig.config.set(path, null); + } + ++ @SuppressWarnings("all") + public static RemovedVerifiedConfig build(RemovedConfig config, Field field) { + StringBuilder path = new StringBuilder("settings."); + for (int i = 0; i < config.category().length; i++) { @@ -1738,7 +1726,7 @@ index 0000000000000000000000000000000000000000..828bbd8b048df8e48ef007d2c1eefe14 + constructor.setAccessible(true); + configConvert = constructor.newInstance(); + } catch (Exception e) { -+ e.printStackTrace(); ++ LeavesLogger.LOGGER.warning("Failure to load leaves config" + path, e); + } + + return new RemovedVerifiedConfig(config, configConvert, field, path.toString()); @@ -1786,6 +1774,7 @@ index 0000000000000000000000000000000000000000..828bbd8b048df8e48ef007d2c1eefe14 + } + } + ++ @SuppressWarnings("all") + public static VerifiedConfig build(GlobalConfig config, Field field) { + StringBuilder path = new StringBuilder("settings."); + for (int i = 0; i < config.category().length; i++) { @@ -1799,29 +1788,30 @@ index 0000000000000000000000000000000000000000..828bbd8b048df8e48ef007d2c1eefe14 + constructor.setAccessible(true); + configVerify = constructor.newInstance(); + } catch (Exception e) { -+ e.printStackTrace(); ++ LeavesLogger.LOGGER.warning("Failure to load leaves config" + path, e); + } + -+ + return new VerifiedConfig(config, configVerify, field, path.toString()); + } + } +} diff --git a/src/main/java/org/leavesmc/leaves/config/RemovedConfig.java b/src/main/java/org/leavesmc/leaves/config/RemovedConfig.java new file mode 100644 -index 0000000000000000000000000000000000000000..90137a284acaf9036334ee2fe6ab34025acb4f4d +index 0000000000000000000000000000000000000000..df9af9e3561ad9eb77f75a6250327e6428d21d1e --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/config/RemovedConfig.java -@@ -0,0 +1,19 @@ +@@ -0,0 +1,21 @@ +package org.leavesmc.leaves.config; + +import java.lang.annotation.ElementType; ++import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) ++@Repeatable(RemovedConfigs.class) +public @interface RemovedConfig { + + String name(); @@ -1832,3 +1822,21 @@ index 0000000000000000000000000000000000000000..90137a284acaf9036334ee2fe6ab3402 + + Class> convert() default ConfigVerify.BooleanConfigVerify.class; +} +diff --git a/src/main/java/org/leavesmc/leaves/config/RemovedConfigs.java b/src/main/java/org/leavesmc/leaves/config/RemovedConfigs.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b1ab6db328b562a8ab7d2091b47b81cee739adf1 +--- /dev/null ++++ b/src/main/java/org/leavesmc/leaves/config/RemovedConfigs.java +@@ -0,0 +1,12 @@ ++package org.leavesmc.leaves.config; ++ ++import java.lang.annotation.ElementType; ++import java.lang.annotation.Retention; ++import java.lang.annotation.RetentionPolicy; ++import java.lang.annotation.Target; ++ ++@Target(ElementType.FIELD) ++@Retention(RetentionPolicy.RUNTIME) ++public @interface RemovedConfigs { ++ RemovedConfig[] value(); ++} diff --git a/patches/server/0007-Leaves-Protocol-Core.patch b/patches/server/0007-Leaves-Protocol-Core.patch index a4b22ead..712be94e 100644 --- a/patches/server/0007-Leaves-Protocol-Core.patch +++ b/patches/server/0007-Leaves-Protocol-Core.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Leaves Protocol Core diff --git a/src/main/java/net/minecraft/network/protocol/common/custom/CustomPacketPayload.java b/src/main/java/net/minecraft/network/protocol/common/custom/CustomPacketPayload.java -index 0211311b3b63bcdea7ebf7bcb24629674c771402..c05a72f4928ee2cec28a61ed06a9079d52634900 100644 +index 7655987d061bdb2839b30f926efb034046feaea3..7ae6b2bb868cc3d391bae87fa5e141cf64cc6c78 100644 --- a/src/main/java/net/minecraft/network/protocol/common/custom/CustomPacketPayload.java +++ b/src/main/java/net/minecraft/network/protocol/common/custom/CustomPacketPayload.java @@ -40,13 +40,23 @@ public interface CustomPacketPayload { @@ -33,11 +33,24 @@ index 0211311b3b63bcdea7ebf7bcb24629674c771402..c05a72f4928ee2cec28a61ed06a9079d } }; } +diff --git a/src/main/java/net/minecraft/resources/ResourceLocation.java b/src/main/java/net/minecraft/resources/ResourceLocation.java +index 1967c43ee3a12e63365cc40ee6565307e2fd73cf..6e376d0db5321d8e9b6e0b54617ffd171bf4ee73 100644 +--- a/src/main/java/net/minecraft/resources/ResourceLocation.java ++++ b/src/main/java/net/minecraft/resources/ResourceLocation.java +@@ -36,7 +36,7 @@ public final class ResourceLocation implements Comparable { + private final String namespace; + private final String path; + +- private ResourceLocation(String namespace, String path) { ++ public ResourceLocation(String namespace, String path) { // Leaves - private -> public + assert isValidNamespace(namespace); + + assert isValidPath(path); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 59cc1855d5bebbcaa8f6afc39e91ae0698adcf73..f8ddccd4d9b79c9fb26bca580bf023194bc0eae8 100644 +index 3a37a083556a722ea6fbc75adf32b36e1b66bcc4..9d7f102b6128638cd478e21867ad9f276bad4f32 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1782,6 +1782,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop> extends CustomPacketPayload { + ++ @Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) + @Retention(RetentionPolicy.RUNTIME) + @interface New { + } @@ -163,13 +179,14 @@ index 0000000000000000000000000000000000000000..986d2a6641ff8017dddf3e5f2655adfc +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/core/LeavesProtocolManager.java b/src/main/java/org/leavesmc/leaves/protocol/core/LeavesProtocolManager.java new file mode 100644 -index 0000000000000000000000000000000000000000..3a33982b92bfb12ce1284fb9429672a698a7ce4b +index 0000000000000000000000000000000000000000..53b42f150d4bcca3bed444216d848fdf714102bf --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/core/LeavesProtocolManager.java -@@ -0,0 +1,365 @@ +@@ -0,0 +1,384 @@ +package org.leavesmc.leaves.protocol.core; + +import net.minecraft.network.FriendlyByteBuf; ++import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerPlayer; +import org.apache.commons.lang.ArrayUtils; @@ -180,6 +197,7 @@ index 0000000000000000000000000000000000000000..3a33982b92bfb12ce1284fb9429672a6 +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Constructor; ++import java.lang.reflect.Executable; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; @@ -202,9 +220,11 @@ index 0000000000000000000000000000000000000000..3a33982b92bfb12ce1284fb9429672a6 + +public class LeavesProtocolManager { + ++ private static final Class[] PAYLOAD_PARAMETER_TYPES = {ResourceLocation.class, FriendlyByteBuf.class}; ++ + private static final LeavesLogger LOGGER = LeavesLogger.LOGGER; + -+ private static final Map>>> KNOWN_TYPES = new HashMap<>(); ++ private static final Map> KNOWN_TYPES = new HashMap<>(); + private static final Map> KNOW_RECEIVERS = new HashMap<>(); + + private static final List TICKERS = new ArrayList<>(); @@ -229,7 +249,7 @@ index 0000000000000000000000000000000000000000..3a33982b92bfb12ce1284fb9429672a6 + return; + } + -+ Map>> map = KNOWN_TYPES.getOrDefault(protocol, new HashMap<>()); ++ Map map = KNOWN_TYPES.getOrDefault(protocol, new HashMap<>()); + for (final Method method : methods) { + if (method.isBridge() || method.isSynthetic() || !Modifier.isStatic(method.getModifiers())) { + continue; @@ -250,14 +270,25 @@ index 0000000000000000000000000000000000000000..3a33982b92bfb12ce1284fb9429672a6 + final ProtocolHandler.PayloadReceiver receiver = method.getAnnotation(ProtocolHandler.PayloadReceiver.class); + if (receiver != null) { + try { -+ Constructor> constructor = receiver.payload().getConstructor(ResourceLocation.class, FriendlyByteBuf.class); -+ constructor.setAccessible(true); -+ -+ if (constructor.getAnnotation(LeavesCustomPayload.New.class) == null) { -+ LOGGER.warning("Failed to find new annotation for " + receiver.payload().getName()); ++ boolean found = false; ++ for (Method payloadMethod : receiver.payload().getDeclaredMethods()) { ++ if (payloadMethod.isAnnotationPresent(LeavesCustomPayload.New.class)) { ++ if (payloadMethod.getParameterTypes() == PAYLOAD_PARAMETER_TYPES && payloadMethod.getReturnType() == receiver.payload() && Modifier.isStatic(payloadMethod.getModifiers())) { ++ payloadMethod.setAccessible(true); ++ map.put(receiver, payloadMethod); ++ found = true; ++ break; ++ } ++ } + } + -+ map.put(receiver, constructor); ++ if (!found) { ++ Constructor> constructor = receiver.payload().getConstructor(PAYLOAD_PARAMETER_TYPES); ++ if (constructor.isAnnotationPresent(LeavesCustomPayload.New.class)) { ++ map.put(receiver, constructor); ++ constructor.setAccessible(true); ++ } ++ } + } catch (NoSuchMethodException exception) { + LOGGER.severe("Failed to find constructor for " + receiver.payload().getName() + ", " + exception.getCause() + ": " + exception.getMessage()); + continue; @@ -315,11 +346,15 @@ index 0000000000000000000000000000000000000000..3a33982b92bfb12ce1284fb9429672a6 + continue; + } + -+ Map>> map = KNOWN_TYPES.get(protocol); ++ Map map = KNOWN_TYPES.get(protocol); + for (ProtocolHandler.PayloadReceiver receiver : map.keySet()) { + if (receiver.ignoreId() || ArrayUtils.contains(receiver.payloadId(), id.getPath())) { + try { -+ return map.get(receiver).newInstance(id, buf); ++ if (map.get(receiver) instanceof Constructor constructor) { ++ return (LeavesCustomPayload) constructor.newInstance(id, buf); ++ } else if (map.get(receiver) instanceof Method method) { ++ return (LeavesCustomPayload) method.invoke(null, id, buf); ++ } + } catch (InvocationTargetException | InstantiationException | IllegalAccessException exception) { + LOGGER.warning("Failed to create payload for " + id + " in " + ArrayUtils.toString(protocol.namespace()) + ", " + exception.getCause() + ": " + exception.getMessage()); + buf.readBytes(buf.readableBytes()); @@ -333,7 +368,7 @@ index 0000000000000000000000000000000000000000..3a33982b92bfb12ce1284fb9429672a6 + + public static void handlePayload(ServerPlayer player, LeavesCustomPayload payload) { + if (payload instanceof ErrorPayload errorPayload) { -+ player.connection.disconnect("Payload " + Arrays.toString(errorPayload.packetID) + " from " + Arrays.toString(errorPayload.protocolID) + " error", PlayerKickEvent.Cause.INVALID_PAYLOAD); ++ player.connection.disconnect(Component.literal("Payload " + Arrays.toString(errorPayload.packetID) + " from " + Arrays.toString(errorPayload.protocolID) + " error"), PlayerKickEvent.Cause.INVALID_PAYLOAD); + return; + } + @@ -427,7 +462,7 @@ index 0000000000000000000000000000000000000000..3a33982b92bfb12ce1284fb9429672a6 + } + + public static Set> getClasses(String pack) { -+ Set> classes = new LinkedHashSet>(); ++ Set> classes = new LinkedHashSet<>(); + String packageDirName = pack.replace('.', '/'); + Enumeration dirs; + try { @@ -509,7 +544,7 @@ index 0000000000000000000000000000000000000000..3a33982b92bfb12ce1284fb9429672a6 + + public record EmptyPayload(ResourceLocation id) implements LeavesCustomPayload { + -+ @LeavesCustomPayload.New ++ @New + public EmptyPayload(ResourceLocation location, FriendlyByteBuf buf) { + this(location); + } @@ -521,7 +556,7 @@ index 0000000000000000000000000000000000000000..3a33982b92bfb12ce1284fb9429672a6 + + public record LeavesPayload(FriendlyByteBuf data, ResourceLocation id) implements LeavesCustomPayload { + -+ @LeavesCustomPayload.New ++ @New + public LeavesPayload(ResourceLocation location, FriendlyByteBuf buf) { + this(new FriendlyByteBuf(buf.readBytes(buf.readableBytes())), location); + } @@ -534,7 +569,7 @@ index 0000000000000000000000000000000000000000..3a33982b92bfb12ce1284fb9429672a6 +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/core/ProtocolHandler.java b/src/main/java/org/leavesmc/leaves/protocol/core/ProtocolHandler.java new file mode 100644 -index 0000000000000000000000000000000000000000..f9dc0a60ca4287e5ec91dd3fc1ae315e2826da34 +index 0000000000000000000000000000000000000000..f941f095184cf4b7af284d1357ea1a85815e8a66 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/core/ProtocolHandler.java @@ -0,0 +1,61 @@ @@ -559,7 +594,7 @@ index 0000000000000000000000000000000000000000..f9dc0a60ca4287e5ec91dd3fc1ae315e + + Class> payload(); + -+ String[] payloadId(); ++ String[] payloadId() default ""; + + boolean ignoreId() default false; + } diff --git a/patches/server/0008-Fix-gravity-block-duper.patch b/patches/server/0008-Fix-gravity-block-duper.patch deleted file mode 100644 index 5b542c95..00000000 --- a/patches/server/0008-Fix-gravity-block-duper.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: violetc <58360096+s-yh-china@users.noreply.github.com> -Date: Sat, 30 Oct 2021 21:07:43 +0800 -Subject: [PATCH] Fix gravity block duper - - -diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 864e6d223de55f42122485bf6a3c84bbb636479c..caed44af1b4c48ecd49a7248845a418dfd9b8fbb 100644 ---- a/src/main/java/net/minecraft/world/entity/Entity.java -+++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -442,6 +442,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - return this.originWorld; - } - // Paper end - Entity origin API -+ /* Leaves - fix gravity block duper - // Paper start - make end portalling safe - public BlockPos portalBlock; - public ServerLevel portalWorld; -@@ -472,6 +473,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - this.teleportTo(worldserver, null); - } - // Paper end - make end portalling safe -+ */ - // Paper start - optimise entity tracking - final org.spigotmc.TrackingRange.TrackingRangeType trackingRangeType = org.spigotmc.TrackingRange.getTrackingRangeType(this); - -@@ -3265,7 +3267,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - } - - this.processPortalCooldown(); -- if (!io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowUnsafeEndPortalTeleportation) this.tickEndPortal(); // Paper - make end portalling safe -+ // Leaves - fix gravity block duper - } - } - -diff --git a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java -index 7272d70c672b54dcf595beafd7a2ed33c96e35cb..d8d355b4ee4869fa9a5d7b4dcd81a3375dd976ba 100644 ---- a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java -+++ b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java -@@ -61,15 +61,19 @@ public class EndPortalBlock extends BaseEntityBlock { - // return; // CraftBukkit - always fire event in case plugins wish to change it - } - -- // Paper start - move all of this logic into portal tick -- entity.portalWorld = ((ServerLevel)world); -- entity.portalBlock = pos.immutable(); -- if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowUnsafeEndPortalTeleportation) { -- entity.tickEndPortal(); -+ // Leaves start - fix gravity block duper -+ // CraftBukkit start - Entity in portal -+ EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ())); -+ world.getCraftServer().getPluginManager().callEvent(event); -+ -+ if (entity instanceof ServerPlayer) { -+ ((ServerPlayer) entity).changeDimension(worldserver, PlayerTeleportEvent.TeleportCause.END_PORTAL); -+ return; - } -- // Paper end - move all of this logic into portal tick -+ // CraftBukkit end -+ entity.changeDimension(worldserver); -+ // Leaves end - fix gravity block duper - } -- - } - - @Override diff --git a/patches/server/0009-Fix-trading-with-the-void.patch b/patches/server/0008-Fix-trading-with-the-void.patch similarity index 88% rename from patches/server/0009-Fix-trading-with-the-void.patch rename to patches/server/0008-Fix-trading-with-the-void.patch index 44d93f8e..497b0631 100644 --- a/patches/server/0009-Fix-trading-with-the-void.patch +++ b/patches/server/0008-Fix-trading-with-the-void.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix trading with the void diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 92805a3311bc1f21df9512b14b209e1d51174ac5..c93d0fbb921309a63c21ba7775fdf44aaa7985c4 100644 +index d6af1d0cd2829bc1e7e7c7a7a8014750c2bdac2b..9ac697d12ec670e2f67d11d94a09de50c7bd0b9e 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -2751,11 +2751,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2516,11 +2516,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. // Spigot end // Spigot Start if (entity.getBukkitEntity() instanceof org.bukkit.inventory.InventoryHolder && (!(entity instanceof ServerPlayer) || entity.getRemovalReason() != Entity.RemovalReason.KILLED)) { // SPIGOT-6876: closeInventory clears death message diff --git a/patches/server/0010-Make-snowball-and-egg-can-knockback-player.patch b/patches/server/0009-Make-snowball-and-egg-can-knockback-player.patch similarity index 53% rename from patches/server/0010-Make-snowball-and-egg-can-knockback-player.patch rename to patches/server/0009-Make-snowball-and-egg-can-knockback-player.patch index 5842810c..d3d09765 100644 --- a/patches/server/0010-Make-snowball-and-egg-can-knockback-player.patch +++ b/patches/server/0009-Make-snowball-and-egg-can-knockback-player.patch @@ -5,45 +5,35 @@ Subject: [PATCH] Make snowball and egg can knockback player diff --git a/src/main/java/net/minecraft/world/entity/projectile/Snowball.java b/src/main/java/net/minecraft/world/entity/projectile/Snowball.java -index 2b4d206c0d31ba38d7b2af654bd420e85145d441..9711279772d1617395c6fc34ae0b4bea6a215fae 100644 +index 2b4d206c0d31ba38d7b2af654bd420e85145d441..f1070a44cd51b8d611f64e7e30691de372d9567f 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Snowball.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Snowball.java -@@ -3,6 +3,7 @@ package net.minecraft.world.entity.projectile; - import net.minecraft.core.particles.ItemParticleOption; - import net.minecraft.core.particles.ParticleOptions; - import net.minecraft.core.particles.ParticleTypes; -+import net.minecraft.server.level.ServerPlayer; - import net.minecraft.world.entity.Entity; - import net.minecraft.world.entity.EntityType; - import net.minecraft.world.entity.LivingEntity; -@@ -61,6 +62,13 @@ public class Snowball extends ThrowableItemProjectile { +@@ -61,6 +61,13 @@ public class Snowball extends ThrowableItemProjectile { int i = entity instanceof Blaze ? 3 : 0; entity.hurt(this.damageSources().thrown(this, this.getOwner()), (float) i); + + // Leaves start - make snowball can knockback player -+ if (org.leavesmc.leaves.LeavesConfig.snowballAndEggCanKnockback && entity instanceof ServerPlayer) { -+ entity.hurt(this.damageSources().thrown(this, this.getOwner()), 0.0000001F); -+ ((ServerPlayer) entity).knockback(0.4000000059604645D, this.getX() - entity.getX(), this.getZ() - entity.getZ(), this, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.DAMAGE); ++ if (org.leavesmc.leaves.LeavesConfig.snowballAndEggCanKnockback && entity instanceof net.minecraft.server.level.ServerPlayer player) { ++ player.hurt(this.damageSources().thrown(this, this.getOwner()), 0.0000001F); ++ player.knockback(0.4000000059604645D, this.getX() - player.getX(), this.getZ() - player.getZ(), this, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.DAMAGE); + } + // Leaves end - make snowball can knockback player } @Override diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java -index 82bb8004635865f5202578d5a6f520048e7269d5..22eae2f5fb8b5b767003e130014e3962d7522fd4 100644 +index dbd60cc8c39f5d2d4c77e2de4f2567e7fa456cd2..2b8c8d0e813cd673f593dab49ecd4ee2d04dc6fa 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java +++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java -@@ -46,7 +46,14 @@ public class ThrownEgg extends ThrowableItemProjectile { - @Override +@@ -50,6 +50,12 @@ public class ThrownEgg extends ThrowableItemProjectile { protected void onHitEntity(EntityHitResult entityHitResult) { super.onHitEntity(entityHitResult); -+ Entity entity = entityHitResult.getEntity(); // Leaves - make egg can knockback player entityHitResult.getEntity().hurt(this.damageSources().thrown(this, this.getOwner()), 0.0F); + // Leaves start - make egg can knockback player -+ if (org.leavesmc.leaves.LeavesConfig.snowballAndEggCanKnockback && entity instanceof ServerPlayer) { -+ entity.hurt(this.damageSources().thrown(this, this.getOwner()), 0.0000001F); -+ ((ServerPlayer) entity).knockback(0.4000000059604645D, this.getX() - entity.getX(), this.getZ() - entity.getZ(), this, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.DAMAGE); ++ if (org.leavesmc.leaves.LeavesConfig.snowballAndEggCanKnockback && entityHitResult.getEntity() instanceof ServerPlayer player) { ++ player.hurt(this.damageSources().thrown(this, this.getOwner()), 0.0000001F); ++ player.knockback(0.4000000059604645D, this.getX() - player.getX(), this.getZ() - player.getZ(), this, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.DAMAGE); + } + // Leaves end - make egg can knockback player } diff --git a/patches/server/0011-Fakeplayer-support.patch b/patches/server/0010-Fakeplayer-support.patch similarity index 91% rename from patches/server/0011-Fakeplayer-support.patch rename to patches/server/0010-Fakeplayer-support.patch index 5442f8cb..6f7b9572 100644 --- a/patches/server/0011-Fakeplayer-support.patch +++ b/patches/server/0010-Fakeplayer-support.patch @@ -33,30 +33,11 @@ index 35772110e9318df46a2729dbc0b5879b290011b7..f26989a44cdda9baabf337d573436c6c PlayerAdvancements playerAdvancements = player.getAdvancements(); Set> set = (Set) playerAdvancements.criterionData.get(this); // Paper - fix AdvancementDataPlayer leak if (set != null && !set.isEmpty()) { -diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java -index f40420a6841f03983b0837e177ea2ae7c3a37ca1..27dbea917d1a03aaa0d8de3db49d3cd25e76448f 100644 ---- a/src/main/java/net/minecraft/network/Connection.java -+++ b/src/main/java/net/minecraft/network/Connection.java -@@ -392,6 +392,14 @@ public class Connection extends SimpleChannelInboundHandler> { - } - } - -+ // Leaves start - fakeplayer -+ public void setListenerForce(PacketListener packetListener) { -+ Validate.notNull(packetListener, "packetListener"); -+ this.packetListener = packetListener; -+ this.disconnectListener = null; -+ } -+ // Leaves end - fakeplayer -+ - public void setListenerForServerboundHandshake(PacketListener packetListener) { - if (this.packetListener != null) { - throw new IllegalStateException("Listener already set"); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index f8ddccd4d9b79c9fb26bca580bf023194bc0eae8..c671f0ffae3c54290f8cff233306a1cd91aa9ffe 100644 +index 9d7f102b6128638cd478e21867ad9f276bad4f32..e91c1db3bcb9f9139d4082e3868d7bcb9a9b084e 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -667,6 +667,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop loot = new java.util.ArrayList<>(this.getInventory().getContainerSize()); // Paper - Restore vanilla drops behavior boolean keepInventory = this.level().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || this.isSpectator(); - if (!keepInventory) { -+ if (!keepInventory || this instanceof ServerBot) { // Leaves - skip bot ++ if (!keepInventory || this instanceof org.leavesmc.leaves.bot.ServerBot) { // Leaves - skip bot for (ItemStack item : this.getInventory().getContents()) { - if (!item.isEmpty() && !EnchantmentHelper.hasVanishingCurse(item)) { + if (!item.isEmpty() && !EnchantmentHelper.has(item, EnchantmentEffectComponents.PREVENT_EQUIPMENT_DROP)) { loot.add(new DefaultDrop(item, stack -> this.drop(stack, true, false, false))); // Paper - Restore vanilla drops behavior; drop function taken from Inventory#dropAll (don't fire drop event) -@@ -1350,6 +1355,13 @@ public class ServerPlayer extends Player { +@@ -1416,6 +1420,13 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple this.lastSentHealth = -1.0F; this.lastSentFood = -1; + // Leaves start - bot support + if (org.leavesmc.leaves.LeavesConfig.fakeplayerSupport) { -+ ServerBot.getBots().forEach(bot1 -> ++ org.leavesmc.leaves.bot.ServerBot.getBots().forEach(bot1 -> + bot1.sendFakeDataIfNeed(this, true)); // Leaves - render bot + } + // Leaves end - bot support @@ -191,7 +164,7 @@ index 6a4637eef14cbd84bbe26ef16f004b8f93367a3d..1b64253c30d1528f7401f15eaa336bbf PlayerChangedWorldEvent changeEvent = new PlayerChangedWorldEvent(this.getBukkitEntity(), worldserver1.getWorld()); this.level().getCraftServer().getPluginManager().callEvent(changeEvent); diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 11d73647d2d94c8131c5e3eeef490fb3472fe0a4..ef719bf410912b24d57de422d1fa3fb2bcef5105 100644 +index ad1aae2c06cae2f0c9756175a61dd32d8e7701ea..3d196ce60afd638867a337ecfa3dbe5a29e8c7e0 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -123,6 +123,8 @@ import org.bukkit.event.player.PlayerRespawnEvent.RespawnReason; @@ -225,7 +198,7 @@ index 11d73647d2d94c8131c5e3eeef490fb3472fe0a4..ef719bf410912b24d57de422d1fa3fb2 final net.kyori.adventure.text.Component jm = playerJoinEvent.joinMessage(); if (jm != null && !jm.equals(net.kyori.adventure.text.Component.empty())) { // Paper - Adventure -@@ -999,6 +1016,13 @@ public abstract class PlayerList { +@@ -936,6 +953,13 @@ public abstract class PlayerList { } // Paper end - Add PlayerPostRespawnEvent @@ -237,9 +210,9 @@ index 11d73647d2d94c8131c5e3eeef490fb3472fe0a4..ef719bf410912b24d57de422d1fa3fb2 + // Leaves end - bot support + // CraftBukkit end + return entityplayer1; - } -@@ -1115,11 +1139,16 @@ public abstract class PlayerList { +@@ -1068,11 +1092,16 @@ public abstract class PlayerList { } public String[] getPlayerNamesArray() { @@ -257,7 +230,7 @@ index 11d73647d2d94c8131c5e3eeef490fb3472fe0a4..ef719bf410912b24d57de422d1fa3fb2 return astring; } -@@ -1598,4 +1627,16 @@ public abstract class PlayerList { +@@ -1539,4 +1568,16 @@ public abstract class PlayerList { public boolean isAllowCommandsForAllPlayers() { return this.allowCommandsForAllPlayers; } @@ -275,23 +248,23 @@ index 11d73647d2d94c8131c5e3eeef490fb3472fe0a4..ef719bf410912b24d57de422d1fa3fb2 + // Leaves end - fakeplayer support } diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index caed44af1b4c48ecd49a7248845a418dfd9b8fbb..05898ab27ddb80157c842bd0a12ec66ef10936eb 100644 +index 9729b3a7ce3027ff4eb02fcb908768d24f74a5f8..2dc27d27908a50101e5671809d1331db0cb2a96c 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -1510,7 +1510,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1393,7 +1393,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return offsetFactor; } - private Vec3 collide(Vec3 movement) { + public Vec3 collide(Vec3 movement) { // Leaves - private -> public - // Paper start - optimise collisions - final boolean xZero = movement.x == 0.0; - final boolean yZero = movement.y == 0.0; + AABB axisalignedbb = this.getBoundingBox(); + List list = this.level().getEntityCollisions(this, axisalignedbb.expandTowards(movement)); + Vec3 vec3d1 = movement.lengthSqr() == 0.0D ? movement : Entity.collideBoundingBox(this, movement, axisalignedbb, this.level(), list); diff --git a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java -index 7dd5e0b935d98d552c916f8412569ff4aa0e9b04..79ed9104efd9695aee9f9f45d342900d88a7ef02 100644 +index 1223c5d23d0ea6aed068bdf0f5725e2ad49fc82c..0e00f59a8962dd6356d483ef5be3209a3a410008 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java +++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java -@@ -62,7 +62,7 @@ public class FishingHook extends Projectile { +@@ -63,7 +63,7 @@ public class FishingHook extends Projectile { public static final EntityDataAccessor DATA_HOOKED_ENTITY = SynchedEntityData.defineId(FishingHook.class, EntityDataSerializers.INT); private static final EntityDataAccessor DATA_BITING = SynchedEntityData.defineId(FishingHook.class, EntityDataSerializers.BOOLEAN); private int life; @@ -353,10 +326,10 @@ index 1b1b475ca27e799e251d6f8a8c9fe1a4fd8bae83..bb9d8cb957f5be517d3ae2959e0406af if (randomsource.nextInt(j) >= world.paperConfig().entities.behavior.playerInsomniaStartTicks) { // Paper - Ability to control player's insomnia and phantoms BlockPos blockposition1 = blockposition.above(20 + randomsource.nextInt(15)).east(-10 + randomsource.nextInt(21)).south(-10 + randomsource.nextInt(21)); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index d58f59b7079cb2cfe3e58391ea3a3576aa030542..a75f5cf9dc6044a3778106adf0c325c1a563e302 100644 +index cb4922442cb696e587d07022e152c4fd9a21ca6f..d7f373bae76e14ce20515ec22bf48c40a2054f92 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -307,6 +307,7 @@ public final class CraftServer implements Server { +@@ -309,6 +309,7 @@ public final class CraftServer implements Server { public static Exception excessiveVelEx; // Paper - Velocity warnings private final io.papermc.paper.logging.SysoutCatcher sysoutCatcher = new io.papermc.paper.logging.SysoutCatcher(); // Paper private final io.papermc.paper.potion.PaperPotionBrewer potionBrewer; // Paper - Custom Potion Mixes @@ -364,7 +337,7 @@ index d58f59b7079cb2cfe3e58391ea3a3576aa030542..a75f5cf9dc6044a3778106adf0c325c1 // Paper start - Folia region threading API private final io.papermc.paper.threadedregions.scheduler.FallbackRegionScheduler regionizedScheduler = new io.papermc.paper.threadedregions.scheduler.FallbackRegionScheduler(); -@@ -3291,4 +3292,11 @@ public final class CraftServer implements Server { +@@ -3216,4 +3217,11 @@ public final class CraftServer implements Server { return this.potionBrewer; } // Paper end @@ -377,23 +350,14 @@ index d58f59b7079cb2cfe3e58391ea3a3576aa030542..a75f5cf9dc6044a3778106adf0c325c1 + // Leaves end - Bot API } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index a2d336ceb52b63db5c03432ee7bc94dc6a742b82..ff4563be301d237bb2f431e424687891e95b2b4f 100644 +index 2cde808bfa797256409879505ba205a71f381981..a007beca6c00bce4514889935b1762a37826c75a 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -55,6 +55,8 @@ import org.bukkit.plugin.Plugin; - import org.bukkit.util.BoundingBox; - import org.bukkit.util.NumberConversions; - import org.bukkit.util.Vector; -+import org.leavesmc.leaves.bot.ServerBot; -+import org.leavesmc.leaves.entity.CraftBot; - - import net.md_5.bungee.api.chat.BaseComponent; // Spigot - -@@ -92,6 +94,8 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -94,6 +94,8 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return new CraftHumanEntity(server, (net.minecraft.world.entity.player.Player) entity); } -+ if (entity instanceof ServerBot) { return new CraftBot(server, (ServerBot) entity); } ++ if (entity instanceof org.leavesmc.leaves.bot.ServerBot bot) { return new org.leavesmc.leaves.entity.CraftBot(server, bot); } + // Special case complex part, since there is no extra entity type for them if (entity instanceof EnderDragonPart complexPart) { @@ -411,29 +375,12 @@ index bb9383f1a457433f9db3e78d7913616280925200..55b41ca7630db143d70137324a9de871 /** * The start ID for the counter. */ -diff --git a/src/main/java/org/leavesmc/leaves/LeavesConfig.java b/src/main/java/org/leavesmc/leaves/LeavesConfig.java -index 5809475f59efe62e18a0905532810e54d5a395d6..161870271e000effffe87c55c4d1d3e242e19c57 100644 ---- a/src/main/java/org/leavesmc/leaves/LeavesConfig.java -+++ b/src/main/java/org/leavesmc/leaves/LeavesConfig.java -@@ -204,6 +204,12 @@ public final class LeavesConfig { - } - } - -+ @GlobalConfig(name = "use-action", category = {"modify", "fakeplayer"}) -+ public static boolean fakeplayerUseAction = true; -+ -+ @GlobalConfig(name = "modify-config", category = {"modify", "fakeplayer"}) -+ public static boolean fakeplayerModifyConfig = false; -+ - // Leaves end - modify - fakeplayer - - // Leaves start - modify - minecraft-old diff --git a/src/main/java/org/leavesmc/leaves/bot/BotCommand.java b/src/main/java/org/leavesmc/leaves/bot/BotCommand.java new file mode 100644 -index 0000000000000000000000000000000000000000..4b31cd0407d46c3405506470f70568a1c6162262 +index 0000000000000000000000000000000000000000..b9d4431b8994f79a4569bd267a6f5680b9650bff --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/bot/BotCommand.java -@@ -0,0 +1,405 @@ +@@ -0,0 +1,407 @@ +package org.leavesmc.leaves.bot; + +import org.bukkit.Bukkit; @@ -457,6 +404,8 @@ index 0000000000000000000000000000000000000000..4b31cd0407d46c3405506470f70568a1 +import org.leavesmc.leaves.entity.Bot; +import org.leavesmc.leaves.event.bot.BotActionEvent; +import org.leavesmc.leaves.event.bot.BotConfigModifyEvent; ++import org.leavesmc.leaves.event.bot.BotCreateEvent; ++import org.leavesmc.leaves.event.bot.BotRemoveEvent; + +import java.util.ArrayList; +import java.util.HashMap; @@ -575,8 +524,8 @@ index 0000000000000000000000000000000000000000..4b31cd0407d46c3405506470f70568a1 + + if (canCreate(sender, args[1])) { + if (sender instanceof Player player) { -+ new ServerBot.BotCreateState(player.getLocation(), args[1], args.length < 3 ? args[1] : args[2]).createAsync(bot -> bot.createPlayer = player.getUniqueId()); -+ } else if (sender instanceof ConsoleCommandSender) { ++ new ServerBot.BotCreateState(player.getLocation(), args[1], args.length < 3 ? args[1] : args[2], BotCreateEvent.CreateReason.COMMAND, player).create(bot -> bot.createPlayer = player.getUniqueId()); ++ } else if (sender instanceof ConsoleCommandSender csender) { + if (args.length < 6) { + sender.sendMessage(ChatColor.RED + "Use /bot create to create a fakeplayer"); + return; @@ -589,7 +538,7 @@ index 0000000000000000000000000000000000000000..4b31cd0407d46c3405506470f70568a1 + double z = Double.parseDouble(args[6]); + + if (world != null) { -+ new ServerBot.BotCreateState(new Location(world, x, y, z), args[1], args[2]).createAsync(null); ++ new ServerBot.BotCreateState(new Location(world, x, y, z), args[1], args[2], BotCreateEvent.CreateReason.COMMAND, csender).create(null); + } + } catch (Exception e) { + e.printStackTrace(); @@ -635,7 +584,7 @@ index 0000000000000000000000000000000000000000..4b31cd0407d46c3405506470f70568a1 + return; + } + -+ bot.die(bot.damageSources().fellOutOfWorld()); ++ bot.onRemove(BotRemoveEvent.RemoveReason.COMMAND, sender); + } + + private void onAction(CommandSender sender, String @NotNull [] args) { @@ -1082,7 +1031,7 @@ index 0000000000000000000000000000000000000000..5bd34353b6ea86cd15ff48b8d6570167 +} diff --git a/src/main/java/org/leavesmc/leaves/bot/BotUtil.java b/src/main/java/org/leavesmc/leaves/bot/BotUtil.java new file mode 100644 -index 0000000000000000000000000000000000000000..e63bdf65183fb2c55df865b0adc2e207ac50071a +index 0000000000000000000000000000000000000000..147293d108bfa5fc5d0ffd66cdc7c0569799d404 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/bot/BotUtil.java @@ -0,0 +1,183 @@ @@ -1230,7 +1179,7 @@ index 0000000000000000000000000000000000000000..e63bdf65183fb2c55df865b0adc2e207 + String skin = fakePlayer.get("skin").getAsString(); + + Location location = new Location(Bukkit.getWorld(dimension), pos_x, pos_y, pos_z, yaw, pitch); -+ ServerBot.BotCreateState state = new ServerBot.BotCreateState(location, username, skin); ++ ServerBot.BotCreateState state = new ServerBot.BotCreateState(location, username, skin, org.leavesmc.leaves.event.bot.BotCreateEvent.CreateReason.INTERNAL, null); + + ListTag inv = null; + File file = MinecraftServer.getServer().getWorldPath(LevelResource.ROOT).resolve("fakeplayer/" + getBotUUID(state) + ".dat").toFile(); @@ -1246,7 +1195,7 @@ index 0000000000000000000000000000000000000000..e63bdf65183fb2c55df865b0adc2e207 + + final JsonArray finalActions = fakePlayer.get("actions").getAsJsonArray(); + final ListTag finalInv = inv; -+ state.createAsync(serverBot -> { ++ state.create(serverBot -> { + if (finalInv != null) { + serverBot.getInventory().load(finalInv); + } @@ -1318,10 +1267,10 @@ index 0000000000000000000000000000000000000000..0db337866c71283464d026a4f230016b +} diff --git a/src/main/java/org/leavesmc/leaves/bot/ServerBot.java b/src/main/java/org/leavesmc/leaves/bot/ServerBot.java new file mode 100644 -index 0000000000000000000000000000000000000000..bba57a2d72ab3051aacd4f4defa3e7377511c36b +index 0000000000000000000000000000000000000000..0cb04bf5c5da387b295897997ae0692eb8baab6e --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/bot/ServerBot.java -@@ -0,0 +1,716 @@ +@@ -0,0 +1,745 @@ +package org.leavesmc.leaves.bot; + +import com.google.common.collect.Lists; @@ -1337,7 +1286,6 @@ index 0000000000000000000000000000000000000000..bba57a2d72ab3051aacd4f4defa3e737 +import net.minecraft.network.PacketSendListener; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.PacketFlow; -+import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; +import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket; +import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket; +import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket; @@ -1345,6 +1293,7 @@ index 0000000000000000000000000000000000000000..bba57a2d72ab3051aacd4f4defa3e737 +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.network.syncher.EntityDataSerializers; +import net.minecraft.server.MinecraftServer; ++import net.minecraft.server.level.ChunkMap; +import net.minecraft.server.level.ClientInformation; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; @@ -1365,6 +1314,7 @@ index 0000000000000000000000000000000000000000..bba57a2d72ab3051aacd4f4defa3e737 +import net.minecraft.world.inventory.ChestMenu; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.gameevent.GameEvent; ++import net.minecraft.world.level.portal.DimensionTransition; +import net.minecraft.world.level.storage.LevelResource; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; @@ -1372,12 +1322,15 @@ index 0000000000000000000000000000000000000000..bba57a2d72ab3051aacd4f4defa3e737 +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; ++import org.bukkit.command.CommandSender; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.scheduler.CraftScheduler; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Nullable; +import org.leavesmc.leaves.LeavesConfig; ++import org.leavesmc.leaves.LeavesLogger; +import org.leavesmc.leaves.bot.agent.BotAction; +import org.leavesmc.leaves.bot.agent.actions.StopAction; +import org.leavesmc.leaves.entity.Bot; @@ -1385,9 +1338,9 @@ index 0000000000000000000000000000000000000000..bba57a2d72ab3051aacd4f4defa3e737 +import org.leavesmc.leaves.event.bot.BotCreateEvent; +import org.leavesmc.leaves.event.bot.BotInventoryOpenEvent; +import org.leavesmc.leaves.event.bot.BotJoinEvent; ++import org.leavesmc.leaves.event.bot.BotRemoveEvent; +import org.leavesmc.leaves.util.MathUtils; + -+import javax.annotation.Nullable; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; @@ -1459,7 +1412,7 @@ index 0000000000000000000000000000000000000000..bba57a2d72ab3051aacd4f4defa3e737 + + MinecraftServer server = MinecraftServer.getServer(); + -+ BotCreateEvent event = new BotCreateEvent(state.name, state.skinName, state.loc, ChatColor.YELLOW + state.name + " joined the game"); ++ BotCreateEvent event = new BotCreateEvent(state.name, state.skinName, state.loc, state.createReason, state.creator); + server.server.getPluginManager().callEvent(event); + + if (event.isCancelled()) { @@ -1489,10 +1442,6 @@ index 0000000000000000000000000000000000000000..bba57a2d72ab3051aacd4f4defa3e737 + bot.isRealPlayer = true; + bot.createState = state; + -+ if (event.getJoinMessage() != null) { -+ Bukkit.broadcastMessage(event.getJoinMessage()); -+ } -+ + bot.teleportTo(location.getX(), location.getY(), location.getZ()); + bot.setRot(location.getYaw(), location.getPitch()); + bot.getBukkitEntity().setRotation(location.getYaw(), location.getPitch()); @@ -1502,9 +1451,13 @@ index 0000000000000000000000000000000000000000..bba57a2d72ab3051aacd4f4defa3e737 + server.getPlayerList().addNewBot(bot); + bots.add(bot); + -+ BotJoinEvent event1 = new BotJoinEvent(bot.getBukkitPlayer()); ++ BotJoinEvent event1 = new BotJoinEvent(bot.getBukkitPlayer(), ChatColor.YELLOW + state.name + " joined the game"); + server.server.getPluginManager().callEvent(event1); + ++ if (event1.getJoinMessage() != null) { ++ Bukkit.broadcastMessage(event1.getJoinMessage()); ++ } ++ + return bot; + } + @@ -1513,7 +1466,7 @@ index 0000000000000000000000000000000000000000..bba57a2d72ab3051aacd4f4defa3e737 + return false; + } + -+ if (Bukkit.getPlayer(name) != null || ServerBot.getBot(name) != null) { ++ if (Bukkit.getPlayerExact(name) != null || ServerBot.getBot(name) != null) { + return false; + } + @@ -1548,13 +1501,20 @@ index 0000000000000000000000000000000000000000..bba57a2d72ab3051aacd4f4defa3e737 + } + + public void sendFakeData(ServerPlayerConnection playerConnection, boolean login) { -+ playerConnection.send(new ClientboundAddEntityPacket(this)); ++ ChunkMap.TrackedEntity entityTracker = ((ServerLevel) this.level()).getChunkSource().chunkMap.entityMap.get(this.getId()); ++ ++ if (entityTracker == null) { ++ LeavesLogger.LOGGER.warning("Fakeplayer cant get entity tracker for " + this.getId()); ++ return; ++ } ++ ++ playerConnection.send(this.getAddEntityPacket(entityTracker.serverEntity)); + if (login) { + Bukkit.getScheduler().runTaskLater(CraftScheduler.MINECRAFT, () -> { -+ connection.send(new ClientboundRotateHeadPacket(this, (byte) ((getYRot() * 256f) / 360f))); ++ playerConnection.send(new ClientboundRotateHeadPacket(this, (byte) ((getYRot() * 256f) / 360f))); + }, 10); + } else { -+ connection.send(new ClientboundRotateHeadPacket(this, (byte) ((getYRot() * 256f) / 360f))); ++ playerConnection.send(new ClientboundRotateHeadPacket(this, (byte) ((getYRot() * 256f) / 360f))); + } + } + @@ -1568,18 +1528,25 @@ index 0000000000000000000000000000000000000000..bba57a2d72ab3051aacd4f4defa3e737 + @Override + public void die(@NotNull DamageSource damageSource) { + super.die(damageSource); -+ this.dieCheck(); ++ if (removeOnDeath) { ++ onRemove(BotRemoveEvent.RemoveReason.DEATH); ++ } + } + -+ private void dieCheck() { -+ if (removeOnDeath) { -+ bots.remove(this); -+ server.getPlayerList().removeBot(this); -+ remove(RemovalReason.KILLED); -+ this.setDead(); -+ this.removeTab(); -+ Bukkit.broadcastMessage(ChatColor.YELLOW + this.getName().getString() + " left the game"); // TODO i18n ++ public void onRemove(BotRemoveEvent.RemoveReason reason) { ++ onRemove(reason, null); ++ } ++ ++ public void onRemove(BotRemoveEvent.RemoveReason reason, @Nullable CommandSender remover) { ++ if (!new BotRemoveEvent(this.getBukkitPlayer(), reason, remover).callEvent()) { ++ return; + } ++ bots.remove(this); ++ server.getPlayerList().removeBot(this); ++ remove(RemovalReason.DISCARDED); ++ this.setDead(); ++ this.removeTab(); ++ Bukkit.broadcastMessage(ChatColor.YELLOW + this.getName().getString() + " left the game"); // TODO i18n + } + + private void removeTab() { @@ -1597,7 +1564,7 @@ index 0000000000000000000000000000000000000000..bba57a2d72ab3051aacd4f4defa3e737 + + @Nullable + @Override -+ public Entity changeDimension(@NotNull ServerLevel destination) { ++ public Entity changeDimension(@NotNull DimensionTransition teleportTarget) { + return null; // disable dimension change + } + @@ -1927,7 +1894,7 @@ index 0000000000000000000000000000000000000000..bba57a2d72ab3051aacd4f4defa3e737 + e.printStackTrace(); + } + } else { -+ removeAllBot(); ++ removeAllBot(BotRemoveEvent.RemoveReason.INTERNAL); + } + } + @@ -1950,11 +1917,11 @@ index 0000000000000000000000000000000000000000..bba57a2d72ab3051aacd4f4defa3e737 + } + } + -+ public static boolean removeAllBot() { ++ public static boolean removeAllBot(BotRemoveEvent.RemoveReason reason) { + Iterator iterator = bots.iterator(); + while (iterator.hasNext()) { + ServerBot bot = iterator.next(); -+ bot.die(bot.damageSources().fellOutOfWorld()); ++ bot.onRemove(reason); + } + return true; + } @@ -1987,25 +1954,35 @@ index 0000000000000000000000000000000000000000..bba57a2d72ab3051aacd4f4defa3e737 + private String realName; + private String name; + -+ public BotCreateState(Location loc, String realName, String skinName) { ++ public BotCreateEvent.CreateReason createReason; ++ public CommandSender creator; ++ ++ public BotCreateState(Location loc, String realName, String skinName, BotCreateEvent.CreateReason createReason, CommandSender creator) { + this.loc = loc; + this.skinName = skinName; + this.setRealName(realName); ++ this.createReason = createReason; ++ this.creator = creator; + } + -+ public BotCreateState(Location loc, String name, String realName, String skinName, String[] skin) { ++ public BotCreateState(Location loc, String name, String realName, String skinName, String[] skin, BotCreateEvent.CreateReason createReason, CommandSender creator) { + this.loc = loc; + this.skinName = skinName; + this.skin = skin; + this.realName = realName; + this.name = name; ++ this.createReason = createReason; ++ this.creator = creator; + } + -+ public ServerBot createSync() { -+ return createBot(this); -+ } -+ -+ public void createAsync(Consumer consumer) { ++ public @Nullable Bot create(Consumer consumer) { ++ if (skin != null) { ++ ServerBot bot = createBot(this); ++ if (bot != null && consumer != null) { ++ consumer.accept(bot); ++ } ++ return bot != null ? bot.getBukkitEntity() : null; ++ } + Bukkit.getScheduler().runTaskAsynchronously(CraftScheduler.MINECRAFT, () -> { + if (skinName != null) { + this.skin = MojangAPI.getSkin(skinName); @@ -2018,6 +1995,7 @@ index 0000000000000000000000000000000000000000..bba57a2d72ab3051aacd4f4defa3e737 + } + }); + }); ++ return null; + } + + public void setName(String name) { @@ -3236,33 +3214,6 @@ index 0000000000000000000000000000000000000000..46c8dad4a6205e3e460b82f8ce5617f8 + return false; + } +} -diff --git a/src/main/java/org/leavesmc/leaves/command/CommandArgument.java b/src/main/java/org/leavesmc/leaves/command/CommandArgument.java -index 381cd8b33137a5b7dc688306b56805f35c57012a..2f0e6671dd8bfe4f320eab92c5f5bbc10abc3b05 100644 ---- a/src/main/java/org/leavesmc/leaves/command/CommandArgument.java -+++ b/src/main/java/org/leavesmc/leaves/command/CommandArgument.java -@@ -32,6 +32,12 @@ public class CommandArgument { - return this; - } - -+ public CommandArgument setAllTabComplete(List> tabComplete) { -+ this.tabComplete.clear(); -+ this.tabComplete.addAll(tabComplete); -+ return this; -+ } -+ - public CommandArgumentResult parse(int index, String @NotNull [] args) { - Object[] result = new Object[argumentTypes.size()]; - Arrays.fill(result, null); -diff --git a/src/main/java/org/leavesmc/leaves/command/CommandArgumentResult.java b/src/main/java/org/leavesmc/leaves/command/CommandArgumentResult.java -index e50ca0473ab4d40e2623ab15f8566276cc14f4e7..6549037cf0bb8460fef8bef41d2335be079b9e9b 100644 ---- a/src/main/java/org/leavesmc/leaves/command/CommandArgumentResult.java -+++ b/src/main/java/org/leavesmc/leaves/command/CommandArgumentResult.java -@@ -58,5 +58,4 @@ public class CommandArgumentResult { - return null; - } - } -- - } diff --git a/src/main/java/org/leavesmc/leaves/entity/CraftBot.java b/src/main/java/org/leavesmc/leaves/entity/CraftBot.java new file mode 100644 index 0000000000000000000000000000000000000000..fe1df01906f15e130cf947bbecb5df4bddf98c7c @@ -3338,26 +3289,28 @@ index 0000000000000000000000000000000000000000..fe1df01906f15e130cf947bbecb5df4b +} diff --git a/src/main/java/org/leavesmc/leaves/entity/CraftBotManager.java b/src/main/java/org/leavesmc/leaves/entity/CraftBotManager.java new file mode 100644 -index 0000000000000000000000000000000000000000..3995912855a612f09567027138f855ec40e26acf +index 0000000000000000000000000000000000000000..badd1d78398fc154254cd465c0a59c64b3fa500c --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/entity/CraftBotManager.java -@@ -0,0 +1,93 @@ +@@ -0,0 +1,102 @@ +package org.leavesmc.leaves.entity; + +import com.google.common.base.Function; +import com.google.common.collect.Lists; +import org.bukkit.Location; -+import org.bukkit.util.Consumer; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.bot.agent.Actions; +import org.leavesmc.leaves.bot.agent.actions.CraftCustomBotAction; +import org.leavesmc.leaves.entity.botaction.CustomBotAction; ++import org.leavesmc.leaves.event.bot.BotCreateEvent; ++import org.leavesmc.leaves.event.bot.BotRemoveEvent; + +import java.util.Collection; +import java.util.Collections; +import java.util.UUID; ++import java.util.function.Consumer; + +public class CraftBotManager implements BotManager { + @@ -3380,17 +3333,24 @@ index 0000000000000000000000000000000000000000..3995912855a612f09567027138f855ec + + @Override + public @Nullable Bot createBot(@NotNull String name, @NotNull String realName, @Nullable String[] skin, @Nullable String skinName, @NotNull Location location) { -+ ServerBot bot = new ServerBot.BotCreateState(location, name, realName, skinName, skin).createSync(); -+ if (bot != null) { -+ return bot.getBukkitPlayer(); -+ } -+ return null; ++ return this.createBot(name, realName, skin, skinName, location, null); + } + + @Override -+ public void createBot(@NotNull String name, @Nullable String skinName, @NotNull Location location, Consumer consumer) { -+ new ServerBot.BotCreateState(location, name, skinName).createAsync((serverBot -> { -+ consumer.accept(serverBot.getBukkitPlayer()); ++ public @Nullable Bot createBot(@NotNull String name, @NotNull String realName, @NotNull String[] skin, @Nullable String skinName, @NotNull Location location, @Nullable Consumer consumer) { ++ return new ServerBot.BotCreateState(location, name, realName, skinName, skin, BotCreateEvent.CreateReason.PLUGIN, null).create((serverBot -> { ++ if (consumer != null) { ++ consumer.accept(serverBot.getBukkitPlayer()); ++ } ++ })); ++ } ++ ++ @Override ++ public void createBot(@NotNull String name, @Nullable String skinName, @NotNull Location location, @Nullable Consumer consumer) { ++ new ServerBot.BotCreateState(location, name, skinName, BotCreateEvent.CreateReason.PLUGIN, null).create((serverBot -> { ++ if (consumer != null) { ++ consumer.accept(serverBot.getBukkitPlayer()); ++ } + })); + } + @@ -3398,7 +3358,7 @@ index 0000000000000000000000000000000000000000..3995912855a612f09567027138f855ec + public void removeBot(@NotNull String name) { + ServerBot bot = ServerBot.getBot(name); + if (bot != null) { -+ bot.die(bot.damageSources().fellOutOfWorld()); ++ bot.onRemove(org.leavesmc.leaves.event.bot.BotRemoveEvent.RemoveReason.PLUGIN); + } + } + @@ -3406,13 +3366,13 @@ index 0000000000000000000000000000000000000000..3995912855a612f09567027138f855ec + public void removeBot(@NotNull UUID uuid) { + ServerBot bot = ServerBot.getBot(uuid); + if (bot != null) { -+ bot.die(bot.damageSources().fellOutOfWorld()); ++ bot.onRemove(BotRemoveEvent.RemoveReason.PLUGIN); + } + } + + @Override + public void removeAllBots() { -+ ServerBot.removeAllBot(); ++ ServerBot.removeAllBot(BotRemoveEvent.RemoveReason.PLUGIN); + } + + @Override @@ -3435,87 +3395,3 @@ index 0000000000000000000000000000000000000000..3995912855a612f09567027138f855ec + return Actions.unregister(name); + } +} -diff --git a/src/main/java/org/leavesmc/leaves/util/MathUtils.java b/src/main/java/org/leavesmc/leaves/util/MathUtils.java -new file mode 100644 -index 0000000000000000000000000000000000000000..6c42b029d98ed293645f06dde6838761f87f20bb ---- /dev/null -+++ b/src/main/java/org/leavesmc/leaves/util/MathUtils.java -@@ -0,0 +1,78 @@ -+package org.leavesmc.leaves.util; -+ -+import org.bukkit.util.NumberConversions; -+import org.bukkit.util.Vector; -+ -+import java.util.regex.Pattern; -+ -+public class MathUtils { -+ // Lag ? -+ public static void clean(Vector vector) { -+ if (!NumberConversions.isFinite(vector.getX())) vector.setX(0); -+ if (!NumberConversions.isFinite(vector.getY())) vector.setY(0); -+ if (!NumberConversions.isFinite(vector.getZ())) vector.setZ(0); -+ } -+ -+ private static final Pattern numericPattern = Pattern.compile("^-?[1-9]\\d*$|^0$"); -+ public static boolean isNumeric(String str){ -+ return numericPattern.matcher(str).matches(); -+ } -+ -+ public static float[] fetchYawPitch(Vector dir) { -+ double x = dir.getX(); -+ double z = dir.getZ(); -+ -+ float[] out = new float[2]; -+ -+ if (x == 0.0D && z == 0.0D) { -+ out[1] = (float) (dir.getY() > 0.0D ? -90 : 90); -+ } -+ -+ else { -+ double theta = Math.atan2(-x, z); -+ out[0] = (float) Math.toDegrees((theta + 6.283185307179586D) % 6.283185307179586D); -+ -+ double x2 = NumberConversions.square(x); -+ double z2 = NumberConversions.square(z); -+ double xz = Math.sqrt(x2 + z2); -+ out[1] = (float) Math.toDegrees(Math.atan(-dir.getY() / xz)); -+ } -+ -+ return out; -+ } -+ -+ public static float fetchPitch(Vector dir) { -+ double x = dir.getX(); -+ double z = dir.getZ(); -+ -+ float result; -+ -+ if (x == 0.0D && z == 0.0D) { -+ result = (float) (dir.getY() > 0.0D ? -90 : 90); -+ } -+ -+ else { -+ double x2 = NumberConversions.square(x); -+ double z2 = NumberConversions.square(z); -+ double xz = Math.sqrt(x2 + z2); -+ result = (float) Math.toDegrees(Math.atan(-dir.getY() / xz)); -+ } -+ -+ return result; -+ } -+ -+ public static Vector getDirection(double rotX, double rotY) { -+ Vector vector = new Vector(); -+ -+ rotX = Math.toRadians(rotX); -+ rotY = Math.toRadians(rotY); -+ -+ double xz = Math.abs(Math.cos(rotY)); -+ -+ vector.setX(-Math.sin(rotX) * xz); -+ vector.setZ(Math.cos(rotX) * xz); -+ vector.setY(-Math.sin(rotY)); -+ -+ return vector; -+ } -+} diff --git a/patches/server/0012-Make-shears-in-dispenser-can-unlimited-use.patch b/patches/server/0011-Make-shears-in-dispenser-can-unlimited-use.patch similarity index 84% rename from patches/server/0012-Make-shears-in-dispenser-can-unlimited-use.patch rename to patches/server/0011-Make-shears-in-dispenser-can-unlimited-use.patch index db79877c..61b74433 100644 --- a/patches/server/0012-Make-shears-in-dispenser-can-unlimited-use.patch +++ b/patches/server/0011-Make-shears-in-dispenser-can-unlimited-use.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Make shears in dispenser can unlimited use diff --git a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java -index a024c697a65bbab27408da1d6a75e531d9719b47..d572549fa76e08e233b810e1b82f79b8174009b9 100644 +index 44b79a7c2f8b95a484d1999fa2167ce588f7985b..67c1aaf2fce72da77e74748d3a8855f0e2b02efb 100644 --- a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java @@ -64,7 +64,7 @@ public class ShearsDispenseItemBehavior extends OptionalDispenseItemBehavior { @@ -14,6 +14,6 @@ index a024c697a65bbab27408da1d6a75e531d9719b47..d572549fa76e08e233b810e1b82f79b8 this.setSuccess(ShearsDispenseItemBehavior.tryShearBeehive(worldserver, blockposition) || ShearsDispenseItemBehavior.tryShearLivingEntity(worldserver, blockposition, bukkitBlock, craftItem)); // CraftBukkit - if (this.isSuccess()) { + if (this.isSuccess() && !org.leavesmc.leaves.LeavesConfig.shearsInDispenserCanZeroAmount) { // Leaves - Make shears in dispenser can unlimited use - stack.hurtAndBreak(1, worldserver.getRandom(), (ServerPlayer) null, () -> { - stack.setCount(0); + stack.hurtAndBreak(1, worldserver, (ServerPlayer) null, (item) -> { }); + } diff --git a/patches/server/0013-Redstone-Shears-Wrench.patch b/patches/server/0012-Redstone-Shears-Wrench.patch similarity index 73% rename from patches/server/0013-Redstone-Shears-Wrench.patch rename to patches/server/0012-Redstone-Shears-Wrench.patch index 69c2f0d2..8d65c308 100644 --- a/patches/server/0013-Redstone-Shears-Wrench.patch +++ b/patches/server/0012-Redstone-Shears-Wrench.patch @@ -5,40 +5,31 @@ Subject: [PATCH] Redstone Shears Wrench diff --git a/src/main/java/net/minecraft/world/item/ShearsItem.java b/src/main/java/net/minecraft/world/item/ShearsItem.java -index cb809796372a4658aa617404f9fddffff9b45cb7..accea918869275c76bef2dd8ce117e2119947fe2 100644 +index cb809796372a4658aa617404f9fddffff9b45cb7..f2fb88dd19b7d8e6dd3283266a80503502560fbf 100644 --- a/src/main/java/net/minecraft/world/item/ShearsItem.java +++ b/src/main/java/net/minecraft/world/item/ShearsItem.java -@@ -3,6 +3,7 @@ package net.minecraft.world.item; - import java.util.List; - import net.minecraft.advancements.CriteriaTriggers; - import net.minecraft.core.BlockPos; +@@ -19,6 +19,20 @@ import net.minecraft.world.level.block.GrowingPlantHeadBlock; + import net.minecraft.world.level.block.state.BlockState; + import net.minecraft.world.level.gameevent.GameEvent; + ++// Leaves start - shears wrench +import net.minecraft.network.chat.Component; - import net.minecraft.server.level.ServerPlayer; - import net.minecraft.sounds.SoundEvents; - import net.minecraft.sounds.SoundSource; -@@ -15,9 +16,21 @@ import net.minecraft.world.item.component.Tool; - import net.minecraft.world.item.context.UseOnContext; - import net.minecraft.world.level.Level; - import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.Block; +import net.minecraft.Util; +import net.minecraft.world.level.block.ComparatorBlock; +import net.minecraft.world.level.block.DispenserBlock; - import net.minecraft.world.level.block.GrowingPlantHeadBlock; +import net.minecraft.world.level.block.HopperBlock; +import net.minecraft.world.level.block.ObserverBlock; +import net.minecraft.world.level.block.RepeaterBlock; +import net.minecraft.world.level.block.piston.PistonBaseBlock; - import net.minecraft.world.level.block.state.BlockState; - import net.minecraft.world.level.gameevent.GameEvent; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.Property; ++// Leaves end - shears wrench + -+import javax.annotation.Nullable; - public class ShearsItem extends Item { public ShearsItem(Item.Properties settings) { -@@ -77,6 +90,60 @@ public class ShearsItem extends Item { + super(settings); +@@ -77,6 +91,60 @@ public class ShearsItem extends Item { return InteractionResult.sidedSuccess(level.isClientSide); } @@ -55,17 +46,17 @@ index cb809796372a4658aa617404f9fddffff9b45cb7..accea918869275c76bef2dd8ce117e21 + } + + if (block instanceof PistonBaseBlock) { -+ if (getNameHelper(blockState, blockstatelist.getProperty("extended")).equals("true")) { ++ if (getNameHelper(blockState, PistonBaseBlock.EXTENDED).equals("true")) { + return InteractionResult.FAIL; + } + } + + if (block instanceof RepeaterBlock || block instanceof ComparatorBlock) { -+ if (getNameHelper(blockState, blockstatelist.getProperty("powered")).equals("true")) { ++ if (getNameHelper(blockState, ComparatorBlock.POWERED).equals("true")) { + return InteractionResult.FAIL; + } + if (block instanceof RepeaterBlock) { -+ if (getNameHelper(blockState, blockstatelist.getProperty("locked")).equals("true")) { ++ if (getNameHelper(blockState, RepeaterBlock.LOCKED).equals("true")) { + return InteractionResult.FAIL; + } + } @@ -83,10 +74,10 @@ index cb809796372a4658aa617404f9fddffff9b45cb7..accea918869275c76bef2dd8ce117e21 + + // Leaves start - shears wrench + private static > BlockState cycleState(BlockState state, Property property, boolean inverse) { -+ return (BlockState) state.setValue(property, ShearsItem.getRelative(property.getPossibleValues(), state.getValue(property), inverse)); // CraftBukkit - decompile error ++ return state.setValue(property, ShearsItem.getRelative(property.getPossibleValues(), state.getValue(property), inverse)); // CraftBukkit - decompile error + } + -+ private static T getRelative(Iterable elements, @Nullable T current, boolean inverse) { ++ private static T getRelative(Iterable elements, T current, boolean inverse) { + return inverse ? Util.findPreviousInIterable(elements, current) : Util.findNextInIterable(elements, current); + } + diff --git a/patches/server/0014-Add-isShrink-to-EntityResurrectEvent.patch b/patches/server/0013-Add-isShrink-to-EntityResurrectEvent.patch similarity index 87% rename from patches/server/0014-Add-isShrink-to-EntityResurrectEvent.patch rename to patches/server/0013-Add-isShrink-to-EntityResurrectEvent.patch index e8c3dbdb..413b2a80 100644 --- a/patches/server/0014-Add-isShrink-to-EntityResurrectEvent.patch +++ b/patches/server/0013-Add-isShrink-to-EntityResurrectEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add isShrink to EntityResurrectEvent diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 5b5d8d2430f2b92f56ea3fb0e9a35aa4b9aea48f..f6bff4eb349f51a20516aecb010d19d5f625575e 100644 +index de0c9798261c00a76c7c37c396379f42a44720be..8766907511d0234a50f2ae23689a7e3005757309 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -1642,12 +1642,12 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1630,12 +1630,12 @@ public abstract class LivingEntity extends Entity implements Attackable { } org.bukkit.inventory.EquipmentSlot handSlot = (hand != null) ? org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand) : null; @@ -23,7 +23,7 @@ index 5b5d8d2430f2b92f56ea3fb0e9a35aa4b9aea48f..f6bff4eb349f51a20516aecb010d19d5 itemstack1.shrink(1); } if (itemstack != null && this instanceof ServerPlayer) { -@@ -4546,3 +4546,4 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4595,3 +4595,4 @@ public abstract class LivingEntity extends Entity implements Attackable { } } diff --git a/patches/server/0015-Budding-Amethyst-can-push-by-piston.patch b/patches/server/0014-Budding-Amethyst-can-push-by-piston.patch similarity index 89% rename from patches/server/0015-Budding-Amethyst-can-push-by-piston.patch rename to patches/server/0014-Budding-Amethyst-can-push-by-piston.patch index 7f8d0d55..5fdee87b 100644 --- a/patches/server/0015-Budding-Amethyst-can-push-by-piston.patch +++ b/patches/server/0014-Budding-Amethyst-can-push-by-piston.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Budding Amethyst can push by piston 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 555d255a79c6136d0df3504218a0bc4681a5489f..e27f2317e4e2f13b6ef12be727046497a750fd3a 100644 +index 0c0b149a6cdfaf1de81bfbb92477fbb5c4a8a4bb..992c778f4a826be8d7a5a5d96bf7968b741f490e 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java -@@ -591,6 +591,12 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -588,6 +588,12 @@ public class Block extends BlockBehaviour implements ItemLike { } // Spigot end @@ -38,10 +38,10 @@ index 8920855b07a31715327b8102c7faafc9f916825d..32d926a1b952b8069c5bf48c88e3c108 + // Leaves end - budding amethyst can push by piston } diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -index 2034ca2edd3aff61d94416266e75402babd3e741..d7ae3a3a63a3eb3a95534c303ba87303cb96744d 100644 +index a768b07dae4bf75b68e3bc1d3de4b68fc7d23842..80635b82b1da66dbbd8363dd6ace0c2d0686ceb1 100644 --- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java +++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -@@ -1088,7 +1088,7 @@ public abstract class BlockBehaviour implements FeatureElement { +@@ -1016,7 +1016,7 @@ public abstract class BlockBehaviour implements FeatureElement { } public PushReaction getPistonPushReaction() { diff --git a/patches/server/0016-Spectator-dont-get-Advancement.patch b/patches/server/0015-Spectator-dont-get-Advancement.patch similarity index 91% rename from patches/server/0016-Spectator-dont-get-Advancement.patch rename to patches/server/0015-Spectator-dont-get-Advancement.patch index 3d93d94a..9386bd77 100644 --- a/patches/server/0016-Spectator-dont-get-Advancement.patch +++ b/patches/server/0015-Spectator-dont-get-Advancement.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Spectator dont get Advancement diff --git a/src/main/java/net/minecraft/server/PlayerAdvancements.java b/src/main/java/net/minecraft/server/PlayerAdvancements.java -index 8d2b26b2ec48727b12ddb1bede53aecb71f46feb..60ad7e71a3d4b9dc7bab2f961865eac76c0f68c1 100644 +index b5f18a0115b629930de84a9d086505adaa6087dd..ece0aa3bf18e864a261d4d4edf0a98a40e7f6bb3 100644 --- a/src/main/java/net/minecraft/server/PlayerAdvancements.java +++ b/src/main/java/net/minecraft/server/PlayerAdvancements.java @@ -221,6 +221,11 @@ public class PlayerAdvancements { diff --git a/patches/server/0017-Stick-can-change-ArmorStand-arm-status.patch b/patches/server/0016-Stick-can-change-ArmorStand-arm-status.patch similarity index 87% rename from patches/server/0017-Stick-can-change-ArmorStand-arm-status.patch rename to patches/server/0016-Stick-can-change-ArmorStand-arm-status.patch index 5c461905..cc65c63d 100644 --- a/patches/server/0017-Stick-can-change-ArmorStand-arm-status.patch +++ b/patches/server/0016-Stick-can-change-ArmorStand-arm-status.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Stick can change ArmorStand arm status diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -index a02ca704e98ef42f32c3c50b111ee3537f60bf7b..32fd9c3d79bb9e9e75b03750696425089e503dcb 100644 +index 2f398750bfee5758ad8b1367b6fc14364e4de776..df29a54063ee957c2b88a12ef228c7d8541a2f2c 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -@@ -393,6 +393,12 @@ public class ArmorStand extends LivingEntity { +@@ -392,6 +392,12 @@ public class ArmorStand extends LivingEntity { return InteractionResult.SUCCESS; } } else { diff --git a/patches/server/0018-Fix-tripwire-update.patch b/patches/server/0017-Fix-tripwire-update.patch similarity index 100% rename from patches/server/0018-Fix-tripwire-update.patch rename to patches/server/0017-Fix-tripwire-update.patch diff --git a/patches/server/0019-No-chat-sign.patch b/patches/server/0018-No-chat-sign.patch similarity index 93% rename from patches/server/0019-No-chat-sign.patch rename to patches/server/0018-No-chat-sign.patch index c334257a..e6011ca4 100644 --- a/patches/server/0019-No-chat-sign.patch +++ b/patches/server/0018-No-chat-sign.patch @@ -5,7 +5,7 @@ Subject: [PATCH] No chat sign diff --git a/src/main/java/io/papermc/paper/adventure/ChatProcessor.java b/src/main/java/io/papermc/paper/adventure/ChatProcessor.java -index e83f9517b31c5171b8dc75ab63a5bfe654221c84..19d973a0582c487617fafadd3df4857f8a1819a4 100644 +index 14e412ebf75b0e06ab53a1c8f9dd1be6ad1e2680..8fe9a0bf5a6c27d8a505afc2f51b3dccc905423b 100644 --- a/src/main/java/io/papermc/paper/adventure/ChatProcessor.java +++ b/src/main/java/io/papermc/paper/adventure/ChatProcessor.java @@ -317,7 +317,7 @@ public final class ChatProcessor { @@ -41,7 +41,7 @@ index 479e6e2aa88a22ef7f8fccb06add6806f5b71d9d..e6a6d09a64414ae6932e9bac338ce360 buf.writeCollection(this.entries, (buf2, entry) -> entry.write(buf2)); } diff --git a/src/main/java/net/minecraft/network/FriendlyByteBuf.java b/src/main/java/net/minecraft/network/FriendlyByteBuf.java -index aafeb9c61ddba6a8671f0238eda47b227619f1af..84a57cf6454db6b84aabc78017b64cc57c3a2070 100644 +index 0cd6a50837efce87ca052a0e1e24db2b75761196..8212aaf92f028ea560b357771cdf5810d84aed43 100644 --- a/src/main/java/net/minecraft/network/FriendlyByteBuf.java +++ b/src/main/java/net/minecraft/network/FriendlyByteBuf.java @@ -129,6 +129,16 @@ public class FriendlyByteBuf extends ByteBuf { @@ -107,10 +107,10 @@ index 5705cb920084b775cce4b361683b32c6b6e003ed..cbff868303d751d09b68f431c78bb13b } } diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index 437f714fc1b38f0040b57cef94a76faa88f1c495..f240a9d90ec469a99d3d8b82cfa3fcb5d0e78057 100644 +index ec9ade19778c71561b4045ade5ab6cd090768547..2068081a072a0298e95fe40d67e020bf2331f093 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -@@ -663,7 +663,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -666,7 +666,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface // Paper start - Add setting for proxy online mode status return dedicatedserverproperties.enforceSecureProfile && io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode() @@ -120,10 +120,10 @@ index 437f714fc1b38f0040b57cef94a76faa88f1c495..f240a9d90ec469a99d3d8b82cfa3fcb5 } diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -index 82bf29bb3096797801f768c2b631d8b6cae8f761..c02f073e6fa16a05927154462af694731c24347b 100644 +index 01c2e26f92d5d1e46b98ebd20727beb779c98095..ced6a08caf546e245bd6a631df3dc9f8085ed871 100644 --- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -@@ -295,10 +295,24 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -296,10 +296,24 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack } public void send(Packet packet) { @@ -149,10 +149,10 @@ index 82bf29bb3096797801f768c2b631d8b6cae8f761..c02f073e6fa16a05927154462af69473 if (packet == null || this.processedDisconnect) { // Spigot return; diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index ef719bf410912b24d57de422d1fa3fb2bcef5105..00809b615f65b2f4985856673430d8ba68525765 100644 +index 3d196ce60afd638867a337ecfa3dbe5a29e8c7e0..627c6b4bba6863ea89a2be2c3f163533e0d80147 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -1488,7 +1488,7 @@ public abstract class PlayerList { +@@ -1429,7 +1429,7 @@ public abstract class PlayerList { } public boolean verifyChatTrusted(PlayerChatMessage message) { // Paper - private -> public diff --git a/patches/server/0020-Dont-send-useless-entity-packets.patch b/patches/server/0019-Dont-send-useless-entity-packets.patch similarity index 76% rename from patches/server/0020-Dont-send-useless-entity-packets.patch rename to patches/server/0019-Dont-send-useless-entity-packets.patch index 66aa440a..c636eed3 100644 --- a/patches/server/0020-Dont-send-useless-entity-packets.patch +++ b/patches/server/0019-Dont-send-useless-entity-packets.patch @@ -6,21 +6,13 @@ Subject: [PATCH] Dont send useless entity packets This patch is Powered by Purpur(https://github.com/PurpurMC/Purpur) diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java -index a2279262c93408c11f5d2290b48fd794975e8cfe..6177fd5c7e1719a1618388f55b8510d8984a5bf2 100644 +index 1d849ce4e2c85f149af25318b8ffb6dcef6c6788..0c6ee6a22768d3cdd9ddad1c6fbf9bdffd8b4257 100644 --- a/src/main/java/net/minecraft/server/level/ServerEntity.java +++ b/src/main/java/net/minecraft/server/level/ServerEntity.java -@@ -204,6 +204,7 @@ public class ServerEntity { - flag4 = true; - flag5 = true; - } -+ // Leaves end - Better checking - } else { - this.wasOnGround = this.entity.onGround(); - this.teleportDelay = 0; -@@ -211,6 +212,11 @@ public class ServerEntity { - flag4 = true; - flag5 = true; - } +@@ -200,6 +200,11 @@ public class ServerEntity { + packet1 = new ClientboundTeleportEntityPacket(this.entity); + flag4 = true; + flag5 = true; + // Leaves start - dont send useless entity packets + if (org.leavesmc.leaves.LeavesConfig.dontSendUselessEntityPackets && isUselessPacket(packet1)) { + packet1 = null; @@ -29,7 +21,7 @@ index a2279262c93408c11f5d2290b48fd794975e8cfe..6177fd5c7e1719a1618388f55b8510d8 } if ((this.trackDelta || this.entity.hasImpulse || this.entity instanceof LivingEntity && ((LivingEntity) this.entity).isFallFlying()) && this.tickCount > 0) { -@@ -291,6 +297,21 @@ public class ServerEntity { +@@ -281,6 +286,21 @@ public class ServerEntity { }); } diff --git a/patches/server/0021-Optimize-entity-coordinate-key.patch b/patches/server/0020-Optimize-entity-coordinate-key.patch similarity index 85% rename from patches/server/0021-Optimize-entity-coordinate-key.patch rename to patches/server/0020-Optimize-entity-coordinate-key.patch index e2f95c2f..d3a749ce 100644 --- a/patches/server/0021-Optimize-entity-coordinate-key.patch +++ b/patches/server/0020-Optimize-entity-coordinate-key.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Optimize entity coordinate key This patch is Powered by Pufferfish(https://github.com/pufferfish-gg/Pufferfish) diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java -index 1d6b3fe2ce240af4ede61588795456b046eee6c9..21847dfde06ded5944699ca30a4ec9c2d3511555 100644 +index 02d6c98b7a2212b13ffd9859ebfdc0a8357ebe65..8add631c0614879d24455a96d94bc6711456f223 100644 --- a/src/main/java/io/papermc/paper/util/MCUtil.java +++ b/src/main/java/io/papermc/paper/util/MCUtil.java -@@ -215,7 +215,13 @@ public final class MCUtil { +@@ -199,7 +199,13 @@ public final class MCUtil { } public static long getCoordinateKey(final Entity entity) { @@ -25,10 +25,10 @@ index 1d6b3fe2ce240af4ede61588795456b046eee6c9..21847dfde06ded5944699ca30a4ec9c2 public static long getCoordinateKey(final ChunkPos pair) { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 05898ab27ddb80157c842bd0a12ec66ef10936eb..ea232cb815666032580a0c6d81e7a52ef92dbaaa 100644 +index 2dc27d27908a50101e5671809d1331db0cb2a96c..9e984f4bad722244d70d8b45755ca3abd0a22d4a 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -311,7 +311,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -316,7 +316,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess public double yo; public double zo; private Vec3 position; diff --git a/patches/server/0022-Optimize-suffocation.patch b/patches/server/0021-Optimize-suffocation.patch similarity index 89% rename from patches/server/0022-Optimize-suffocation.patch rename to patches/server/0021-Optimize-suffocation.patch index 0f30bbf1..2d0ba2f6 100644 --- a/patches/server/0022-Optimize-suffocation.patch +++ b/patches/server/0021-Optimize-suffocation.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Optimize suffocation This patch is Powered by Pufferfish(https://github.com/pufferfish-gg/Pufferfish) diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index f6bff4eb349f51a20516aecb010d19d5f625575e..8d3ed01ba207900aeaa38f3b4f7a51a277b5686b 100644 +index d6aeaf7f182ff881122dbbe478ed0a74982fbd38..9fadb5b98810efbc477e8cb7daa580b61c92e75c 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -426,7 +426,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -448,7 +448,7 @@ public abstract class LivingEntity extends Entity implements Attackable { boolean flag = this instanceof net.minecraft.world.entity.player.Player; if (!this.level().isClientSide) { @@ -18,7 +18,7 @@ index f6bff4eb349f51a20516aecb010d19d5f625575e..8d3ed01ba207900aeaa38f3b4f7a51a2 this.hurt(this.damageSources().inWall(), 1.0F); } else if (flag && !this.level().getWorldBorder().isWithinBounds(this.getBoundingBox())) { double d0 = this.level().getWorldBorder().getDistanceToBorder(this) + this.level().getWorldBorder().getDamageSafeZone(); -@@ -1430,6 +1430,15 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1407,6 +1407,15 @@ public abstract class LivingEntity extends Entity implements Attackable { return this.getHealth() <= 0.0F; } diff --git a/patches/server/0023-Only-check-for-spooky-season-once-an-hour.patch b/patches/server/0022-Only-check-for-spooky-season-once-an-hour.patch similarity index 82% rename from patches/server/0023-Only-check-for-spooky-season-once-an-hour.patch rename to patches/server/0022-Only-check-for-spooky-season-once-an-hour.patch index 1252e93c..d52e630c 100644 --- a/patches/server/0023-Only-check-for-spooky-season-once-an-hour.patch +++ b/patches/server/0022-Only-check-for-spooky-season-once-an-hour.patch @@ -6,18 +6,10 @@ Subject: [PATCH] Only check for spooky season once an hour This patch is Powered by Pufferfish(https://github.com/pufferfish-gg/Pufferfish) diff --git a/src/main/java/net/minecraft/world/entity/ambient/Bat.java b/src/main/java/net/minecraft/world/entity/ambient/Bat.java -index dc27ddf5131e7398a5390a5187261d4c7fb6ccaa..8237f252cf60cb0ed85f6eb61e2bdb5f8e3cefef 100644 +index dc27ddf5131e7398a5390a5187261d4c7fb6ccaa..601072324b54d062bd4cceb821ae187d904ad49b 100644 --- a/src/main/java/net/minecraft/world/entity/ambient/Bat.java +++ b/src/main/java/net/minecraft/world/entity/ambient/Bat.java -@@ -215,6 +215,7 @@ public class Bat extends AmbientCreature { - super.readAdditionalSaveData(nbt); - this.entityData.set(Bat.DATA_ID_FLAGS, nbt.getByte("BatFlags")); - } -+ // Leaves end - only check for spooky season once an hour - - @Override - public void addAdditionalSaveData(CompoundTag nbt) { -@@ -239,12 +240,28 @@ public class Bat extends AmbientCreature { +@@ -239,13 +239,30 @@ public class Bat extends AmbientCreature { } } @@ -48,5 +40,7 @@ index dc27ddf5131e7398a5390a5187261d4c7fb6ccaa..8237f252cf60cb0ed85f6eb61e2bdb5f + return j == 10 && i >= 20 || j == 11 && i <= 3; + } } ++ // Leaves end - only check for spooky season once an hour private void setupAnimationStates() { + if (this.isResting()) { diff --git a/patches/server/0026-Early-return-optimization-for-target-finding.patch b/patches/server/0023-Early-return-optimization-for-target-finding.patch similarity index 95% rename from patches/server/0026-Early-return-optimization-for-target-finding.patch rename to patches/server/0023-Early-return-optimization-for-target-finding.patch index 5a269647..2281acf7 100644 --- a/patches/server/0026-Early-return-optimization-for-target-finding.patch +++ b/patches/server/0023-Early-return-optimization-for-target-finding.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Early return optimization for target finding This patch is Powered by Pufferfish(https://github.com/pufferfish-gg/Pufferfish) diff --git a/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java b/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java -index d2f0c3b26d4beedb49d86e0242d843590d469d02..0f06374f81f8cc727955c661626dac33d7f7b210 100644 +index aecb0ad814586bfc5e56755ee14379a69388b38c..c618d7c87a0b2e2ee55cbe64cae80178fd8bd651 100644 --- a/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java +++ b/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java @@ -76,9 +76,17 @@ public class TargetingConditions { @@ -21,10 +21,10 @@ index d2f0c3b26d4beedb49d86e0242d843590d469d02..0f06374f81f8cc727955c661626dac33 + return false; + } + } ++ // Leaves end - check range before getting visibility double d = this.testInvisible ? targetEntity.getVisibilityPercent(baseEntity) : 1.0; double e = Math.max((this.useFollowRange ? this.getFollowRange(baseEntity) : this.range) * d, 2.0); // Paper - Fix MC-145656 - double f = baseEntity.distanceToSqr(targetEntity.getX(), targetEntity.getY(), targetEntity.getZ()); -+ // Leaves end - check range before getting visibility if (f > e * e) { return false; } diff --git a/patches/server/0024-Move-ThreadUnsafeRandom-Initialization.patch b/patches/server/0024-Move-ThreadUnsafeRandom-Initialization.patch index c2666e55..3b2c07d5 100644 --- a/patches/server/0024-Move-ThreadUnsafeRandom-Initialization.patch +++ b/patches/server/0024-Move-ThreadUnsafeRandom-Initialization.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Move ThreadUnsafeRandom Initialization This patch is Powered by Pufferfish(https://github.com/pufferfish-gg/Pufferfish) diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index c93d0fbb921309a63c21ba7775fdf44aaa7985c4..84472442e0e68c22c4ebeaaf980aee1e8a234d81 100644 +index 9ac697d12ec670e2f67d11d94a09de50c7bd0b9e..cef5f66db297a68d74cbb7ca538b30d3d362be30 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -971,7 +971,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -802,7 +802,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. } // Paper start - optimise random block ticking private final BlockPos.MutableBlockPos chunkTickMutablePosition = new BlockPos.MutableBlockPos(); @@ -19,20 +19,42 @@ index c93d0fbb921309a63c21ba7775fdf44aaa7985c4..84472442e0e68c22c4ebeaaf980aee1e public void tickChunk(LevelChunk chunk, int randomTickSpeed) { diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 6a1adbc426a8c79c3fefc5a17509d9097ac9f3db..f7823ed9b293b040e38c517d6b96789c7ebba276 100644 +index 41acb79ec31f6f53589d698d1d4547485f0adc71..42206013ca0790f1366319669fe433640a74798c 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -204,6 +204,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - - public abstract ResourceKey getTypeKey(); +@@ -203,11 +203,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl + } + // Paper end +- public abstract ResourceKey getTypeKey(); + protected final io.papermc.paper.util.math.ThreadUnsafeRandom randomTickRandom = new io.papermc.paper.util.math.ThreadUnsafeRandom(java.util.concurrent.ThreadLocalRandom.current().nextLong()); // Leaves - move thread unsafe random initialization + ++ public abstract ResourceKey getTypeKey(); + // Paper start - rewrite chunk system + private ca.spottedleaf.moonrise.patches.chunk_system.level.entity.EntityLookup entityLookup; + + - 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 - create paper world config; Async-Anti-Xray: Pass executor + @Override + public final ca.spottedleaf.moonrise.patches.chunk_system.level.entity.EntityLookup moonrise$getEntityLookup() { + return this.entityLookup; +@@ -255,14 +257,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl + public ChunkAccess moonrise$getSpecificChunkIfLoaded(final int chunkX, final int chunkZ, final ChunkStatus leastStatus) { + return this.getChunkSource().getChunk(chunkX, chunkZ, leastStatus, false); + } +- + @Override + public void moonrise$midTickTasks() { + // no-op on ClientLevel + } + // Paper end - rewrite chunk system + +- 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 - create paper world config & Anti-Xray ++ 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 - create paper world config; 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 - create paper world config -@@ -292,6 +294,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - // Paper end - optimise collisions + this.generator = gen; +@@ -347,6 +348,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl + this.chunkPacketBlockController = this.paperConfig().anticheat.antiXray.enabled ? new com.destroystokyo.paper.antixray.ChunkPacketBlockControllerAntiXray(this, executor) : com.destroystokyo.paper.antixray.ChunkPacketBlockController.NO_OPERATION_INSTANCE; // Paper - Anti-Xray } + // Leaves start - thread unsafe random get diff --git a/patches/server/0028-Config-to-disable-method-profiler.patch b/patches/server/0025-Config-to-disable-method-profiler.patch similarity index 81% rename from patches/server/0028-Config-to-disable-method-profiler.patch rename to patches/server/0025-Config-to-disable-method-profiler.patch index 0f514349..703e34e7 100644 --- a/patches/server/0028-Config-to-disable-method-profiler.patch +++ b/patches/server/0025-Config-to-disable-method-profiler.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Config to disable method profiler This patch is Powered by Pufferfish(https://github.com/pufferfish-gg/Pufferfish) diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index c671f0ffae3c54290f8cff233306a1cd91aa9ffe..b22d0b0a2cb7e877875739abd87a3beac977c82a 100644 +index e91c1db3bcb9f9139d4082e3868d7bcb9a9b084e..8806c9612e81f53241f5f16663aa781b8e03a98f 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -2530,6 +2530,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop, AttributeInstance> attributes = new Object2ObjectOpenHashMap<>(); - private final Set dirtyAttributes = new ObjectOpenHashSet<>(); +@@ -23,9 +23,11 @@ public class AttributeMap { + private final Set attributesToSync = new ObjectOpenHashSet<>(); + private final Set attributesToUpdate = new ObjectOpenHashSet<>(); private final AttributeSupplier supplier; + private final java.util.function.Function, AttributeInstance> createInstance; // Leaves - reduce entity allocations @@ -21,7 +21,7 @@ index 9ef8f014af332da129bfcd3370da983ec035ecc6..1e5f018ea357c3431d5aabbe435ce7d9 } private void onAttributeModified(AttributeInstance instance) { -@@ -43,7 +45,13 @@ public class AttributeMap { +@@ -49,7 +51,13 @@ public class AttributeMap { @Nullable public AttributeInstance getInstance(Holder attribute) { diff --git a/patches/server/0031-Remove-lambda-from-ticking-guard.patch b/patches/server/0029-Remove-lambda-from-ticking-guard.patch similarity index 78% rename from patches/server/0031-Remove-lambda-from-ticking-guard.patch rename to patches/server/0029-Remove-lambda-from-ticking-guard.patch index 7d593f41..ecbec179 100644 --- a/patches/server/0031-Remove-lambda-from-ticking-guard.patch +++ b/patches/server/0029-Remove-lambda-from-ticking-guard.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Remove lambda from ticking guard This patch is Powered by Pufferfish(https://github.com/pufferfish-gg/Pufferfish) diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 38fcba055839fc1b5522e8a88bdaa63d6f24780d..63652c3011c48c461c1b5be1889847b2f065e34c 100644 +index cef5f66db297a68d74cbb7ca538b30d3d362be30..1ff888bdc9c83a7e84393711ff50c96e78a1d55a 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -908,7 +908,24 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -739,7 +739,23 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. } gameprofilerfiller.push("tick"); @@ -18,15 +18,14 @@ index 38fcba055839fc1b5522e8a88bdaa63d6f24780d..63652c3011c48c461c1b5be1889847b2 + if (org.leavesmc.leaves.LeavesConfig.removeTickGuardLambda) { + try { + this.tickNonPassenger(entity); // Leaves - changed -+ MinecraftServer.getServer().executeMidTickTasks(); // Tuinity - execute chunk tasks mid tick + } catch (Throwable throwable) { + if (throwable instanceof ThreadDeath) throw throwable; // Paper -+ // Paper start - Prevent tile entity and entity crashes ++ // Paper start - Prevent block entity and entity crashes + 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 com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerInternalException(msg, throwable))); -+ entity.discard(); -+ // Paper end ++ getCraftServer().getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerInternalException(msg, throwable))); // Paper - ServerExceptionEvent ++ entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); ++ // Paper end - Prevent block entity and entity crashes + } + } else { + this.guardEntityTick(this::tickNonPassenger, entity); diff --git a/patches/server/0030-Remove-iterators-from-inventory-contains.patch b/patches/server/0030-Remove-iterators-from-inventory-contains.patch new file mode 100644 index 00000000..960d5fbf --- /dev/null +++ b/patches/server/0030-Remove-iterators-from-inventory-contains.patch @@ -0,0 +1,134 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: violetc <58360096+s-yh-china@users.noreply.github.com> +Date: Wed, 17 Aug 2022 11:04:12 +0800 +Subject: [PATCH] Remove iterators from inventory contains + +This patch is Powered by Pufferfish(https://github.com/pufferfish-gg/Pufferfish) + +diff --git a/src/main/java/net/minecraft/world/entity/player/Inventory.java b/src/main/java/net/minecraft/world/entity/player/Inventory.java +index 6e66141dca61f777b354854b5d0bac2570b8bf3b..eb11482f48c9f330b7fa62a278fd6f07d3a642e1 100644 +--- a/src/main/java/net/minecraft/world/entity/player/Inventory.java ++++ b/src/main/java/net/minecraft/world/entity/player/Inventory.java +@@ -643,17 +643,31 @@ public class Inventory implements Container, Nameable { + } + + public boolean contains(ItemStack stack) { +- Iterator iterator = this.compartments.iterator(); ++ // Leaves start - don't allocate iterators ++ if (org.leavesmc.leaves.LeavesConfig.removeInventoryContainsIterators) { ++ for (int i = 0; i < this.compartments.size(); i++) { ++ List list = this.compartments.get(i); ++ for (int j = 0; j < list.size(); j++) { ++ ItemStack itemstack = list.get(j); ++ ++ if (!itemstack.isEmpty() && ItemStack.isSameItemSameComponents(itemstack, stack)) { ++ return true; ++ } ++ } ++ } ++ } else { ++ Iterator iterator = this.compartments.iterator(); + +- while (iterator.hasNext()) { +- List list = (List) iterator.next(); +- Iterator iterator1 = list.iterator(); ++ while (iterator.hasNext()) { ++ List list = (List) iterator.next(); ++ Iterator iterator1 = list.iterator(); + +- while (iterator1.hasNext()) { +- ItemStack itemstack1 = (ItemStack) iterator1.next(); ++ while (iterator1.hasNext()) { ++ ItemStack itemstack1 = (ItemStack) iterator1.next(); + +- if (!itemstack1.isEmpty() && ItemStack.isSameItemSameComponents(itemstack1, stack)) { +- return true; ++ if (!itemstack1.isEmpty() && ItemStack.isSameItemSameComponents(itemstack1, stack)) { ++ return true; ++ } + } + } + } +@@ -662,17 +676,30 @@ public class Inventory implements Container, Nameable { + } + + public boolean contains(TagKey tag) { +- Iterator iterator = this.compartments.iterator(); ++ if (org.leavesmc.leaves.LeavesConfig.removeInventoryContainsIterators) { ++ for (int i = 0; i < this.compartments.size(); i++) { ++ List list = this.compartments.get(i); ++ for (int j = 0; j < list.size(); j++) { ++ ItemStack itemstack = list.get(j); + +- while (iterator.hasNext()) { +- List list = (List) iterator.next(); +- Iterator iterator1 = list.iterator(); ++ if (!itemstack.isEmpty() && itemstack.is(tag)) { ++ return true; ++ } ++ } ++ } ++ } else { ++ Iterator iterator = this.compartments.iterator(); ++ ++ while (iterator.hasNext()) { ++ List list = (List) iterator.next(); ++ Iterator iterator1 = list.iterator(); + +- while (iterator1.hasNext()) { +- ItemStack itemstack = (ItemStack) iterator1.next(); ++ while (iterator1.hasNext()) { ++ ItemStack itemstack = (ItemStack) iterator1.next(); + +- if (!itemstack.isEmpty() && itemstack.is(tag)) { +- return true; ++ if (!itemstack.isEmpty() && itemstack.is(tag)) { ++ return true; ++ } + } + } + } +@@ -681,21 +708,34 @@ public class Inventory implements Container, Nameable { + } + + public boolean contains(Predicate predicate) { +- Iterator iterator = this.compartments.iterator(); ++ if (org.leavesmc.leaves.LeavesConfig.removeInventoryContainsIterators) { ++ for (int i = 0; i < this.compartments.size(); i++) { ++ List list = this.compartments.get(i); ++ for (int j = 0; j < list.size(); j++) { ++ ItemStack itemstack = list.get(j); + +- while (iterator.hasNext()) { +- List list = (List) iterator.next(); +- Iterator iterator1 = list.iterator(); ++ if (predicate.test(itemstack)) { ++ return true; ++ } ++ } ++ } ++ } else { ++ Iterator iterator = this.compartments.iterator(); + +- while (iterator1.hasNext()) { +- ItemStack itemstack = (ItemStack) iterator1.next(); ++ while (iterator.hasNext()) { ++ List list = (List) iterator.next(); ++ Iterator iterator1 = list.iterator(); + +- if (predicate.test(itemstack)) { +- return true; ++ while (iterator1.hasNext()) { ++ ItemStack itemstack = (ItemStack) iterator1.next(); ++ ++ if (predicate.test(itemstack)) { ++ return true; ++ } + } + } + } +- ++ // Leaves end - don't allocate iterators + return false; + } + diff --git a/patches/server/0033-Remove-streams-and-iterators-from-range-check.patch b/patches/server/0031-Remove-streams-and-iterators-from-range-check.patch similarity index 94% rename from patches/server/0033-Remove-streams-and-iterators-from-range-check.patch rename to patches/server/0031-Remove-streams-and-iterators-from-range-check.patch index a260babe..487bffe6 100644 --- a/patches/server/0033-Remove-streams-and-iterators-from-range-check.patch +++ b/patches/server/0031-Remove-streams-and-iterators-from-range-check.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Remove streams and iterators from range check This patch is Powered by Pufferfish(https://github.com/pufferfish-gg/Pufferfish) diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index d1a42800e069fa89d3f3fb4dcb9948d1ac3ea577..da65f980f2145ea03341911ce75f7e61b358c9d7 100644 +index c6eeb3324fbf58eb7a6eb61aa7a8dfdc46bda4ae..0bcd9f3faba32c4dc1d115a9306594b9334657cb 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1451,19 +1451,45 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1203,19 +1203,45 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider return ChunkMap.this.level.getServer().getScaledTrackingDistance(initialDistance); } diff --git a/patches/server/0034-Cache-climbing-check-for-activation.patch b/patches/server/0032-Cache-climbing-check-for-activation.patch similarity index 89% rename from patches/server/0034-Cache-climbing-check-for-activation.patch rename to patches/server/0032-Cache-climbing-check-for-activation.patch index 7d1e76d0..e728dd73 100644 --- a/patches/server/0034-Cache-climbing-check-for-activation.patch +++ b/patches/server/0032-Cache-climbing-check-for-activation.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Cache climbing check for activation This patch is Powered by Pufferfish(https://github.com/pufferfish-gg/Pufferfish) diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 8d3ed01ba207900aeaa38f3b4f7a51a277b5686b..ef3e4667d0d38e19a595f83bf93af7a9f1ab4c13 100644 +index 8f5982465154ed03bfb724a57a6ac0dfe6ffc512..8af682d4aebbbd02816a5eb0a62d6ccfc8c1e6ff 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -2042,6 +2042,22 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2041,6 +2041,22 @@ public abstract class LivingEntity extends Entity implements Attackable { return this.lastClimbablePos; } @@ -33,7 +33,7 @@ index 8d3ed01ba207900aeaa38f3b4f7a51a277b5686b..ef3e4667d0d38e19a595f83bf93af7a9 if (this.isSpectator()) { return false; diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index e32e4ffa222fe72c3d3152a91057113c99d3b122..43d49801823c1221d27e89e66422e8748cdc383b 100644 +index 621bda8248e35f5a5730f89a4bcfbe6615ed969c..47c30ebb3ea6fab0a0d51211905217a1d2a0c770 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -295,7 +295,7 @@ public class ActivationRange diff --git a/patches/server/0032-Remove-iterators-from-inventory-contains.patch b/patches/server/0032-Remove-iterators-from-inventory-contains.patch deleted file mode 100644 index 020f6cc4..00000000 --- a/patches/server/0032-Remove-iterators-from-inventory-contains.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: violetc <58360096+s-yh-china@users.noreply.github.com> -Date: Wed, 17 Aug 2022 11:04:12 +0800 -Subject: [PATCH] Remove iterators from inventory contains - -This patch is Powered by Pufferfish(https://github.com/pufferfish-gg/Pufferfish) - -diff --git a/src/main/java/net/minecraft/world/entity/player/Inventory.java b/src/main/java/net/minecraft/world/entity/player/Inventory.java -index ca7fbe4f8c1e1d2fb90095aa35be4dda3029c23e..3c8f35f92ed7e9518d676087f82d1e4da963b779 100644 ---- a/src/main/java/net/minecraft/world/entity/player/Inventory.java -+++ b/src/main/java/net/minecraft/world/entity/player/Inventory.java -@@ -1,9 +1,11 @@ - package net.minecraft.world.entity.player; - - import com.google.common.collect.ImmutableList; -+ - import java.util.Iterator; - import java.util.List; - import java.util.function.Predicate; -+ - import net.minecraft.CrashReport; - import net.minecraft.CrashReportCategory; - import net.minecraft.ReportedException; -@@ -24,6 +26,7 @@ import net.minecraft.world.item.ItemStack; - import net.minecraft.world.level.block.state.BlockState; - // CraftBukkit start - import java.util.ArrayList; -+ - import org.bukkit.Location; - import org.bukkit.craftbukkit.entity.CraftHumanEntity; - import org.bukkit.entity.HumanEntity; -@@ -643,17 +646,31 @@ public class Inventory implements Container, Nameable { - } - - public boolean contains(ItemStack stack) { -- Iterator iterator = this.compartments.iterator(); -+ // Leaves start - don't allocate iterators -+ if (org.leavesmc.leaves.LeavesConfig.removeInventoryContainsIterators) { -+ for (int i = 0; i < this.compartments.size(); i++) { -+ List list = this.compartments.get(i); -+ for (int j = 0; j < list.size(); j++) { -+ ItemStack itemstack1 = list.get(j); -+ -+ if (!itemstack1.isEmpty() && ItemStack.isSameItemSameComponents(itemstack1, stack)) { -+ return true; -+ } -+ } -+ } -+ } else { -+ Iterator iterator = this.compartments.iterator(); - -- while (iterator.hasNext()) { -- List list = (List) iterator.next(); -- Iterator iterator1 = list.iterator(); -+ while (iterator.hasNext()) { -+ List list = (List) iterator.next(); -+ Iterator iterator1 = list.iterator(); - -- while (iterator1.hasNext()) { -- ItemStack itemstack1 = (ItemStack) iterator1.next(); -+ while (iterator1.hasNext()) { -+ ItemStack itemstack1 = (ItemStack) iterator1.next(); - -- if (!itemstack1.isEmpty() && ItemStack.isSameItemSameComponents(itemstack1, stack)) { -- return true; -+ if (!itemstack1.isEmpty() && ItemStack.isSameItemSameComponents(itemstack1, stack)) { -+ return true; -+ } - } - } - } -@@ -695,7 +712,7 @@ public class Inventory implements Container, Nameable { - } - } - } -- -+ // Leaves end - don't allocate iterators - return false; - } - diff --git a/patches/server/0035-Use-aging-cache-for-biome-temperatures.patch b/patches/server/0033-Use-aging-cache-for-biome-temperatures.patch similarity index 100% rename from patches/server/0035-Use-aging-cache-for-biome-temperatures.patch rename to patches/server/0033-Use-aging-cache-for-biome-temperatures.patch diff --git a/patches/server/0036-Reduce-entity-fluid-lookups-if-no-fluids.patch b/patches/server/0034-Reduce-entity-fluid-lookups-if-no-fluids.patch similarity index 92% rename from patches/server/0036-Reduce-entity-fluid-lookups-if-no-fluids.patch rename to patches/server/0034-Reduce-entity-fluid-lookups-if-no-fluids.patch index 78830598..d4a7288e 100644 --- a/patches/server/0036-Reduce-entity-fluid-lookups-if-no-fluids.patch +++ b/patches/server/0034-Reduce-entity-fluid-lookups-if-no-fluids.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Reduce entity fluid lookups if no fluids This patch is Powered by Pufferfish(https://github.com/pufferfish-gg/Pufferfish) diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index ea232cb815666032580a0c6d81e7a52ef92dbaaa..57edf910b4a1997f680896c050a192d01aef36bf 100644 +index 9e984f4bad722244d70d8b45755ca3abd0a22d4a..0653267c90fef463fa94f784012214809bc8c930 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -4492,16 +4492,18 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4292,16 +4292,18 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public boolean updateFluidHeightAndDoFluidPushing(TagKey tag, double speed) { @@ -35,7 +35,7 @@ index ea232cb815666032580a0c6d81e7a52ef92dbaaa..57edf910b4a1997f680896c050a192d0 double d1 = 0.0D; boolean flag = this.isPushedByFluid(); boolean flag1 = false; -@@ -4509,38 +4511,123 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4309,38 +4311,123 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess int k1 = 0; BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(); @@ -181,18 +181,18 @@ index ea232cb815666032580a0c6d81e7a52ef92dbaaa..57edf910b4a1997f680896c050a192d0 if (vec3d.length() > 0.0D) { if (k1 > 0) { diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java -index a2a5aef769ee8bb638a5a9f3da9812fa4a85dda5..73b0bd67b5d3506383df3be065375c9370cff570 100644 +index 8cd6c1d838e0332125fde3fc36475034aa4effa0..070821ae15ed1c4cd20129a983bbf73d17871799 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java -@@ -25,6 +25,7 @@ public class LevelChunkSection { - public final PalettedContainer states; +@@ -26,6 +26,7 @@ public class LevelChunkSection { // CraftBukkit start - read/write private PalettedContainer> biomes; -+ public short fluidStateCount; // Leaves public final com.destroystokyo.paper.util.maplist.IBlockDataList tickingList = new com.destroystokyo.paper.util.maplist.IBlockDataList(); // Paper - // Paper start - optimise collisions - private int specialCollidingBlocks; -@@ -102,6 +103,7 @@ public class LevelChunkSection { ++ public short fluidStateCount; // Leaves + + public LevelChunkSection(PalettedContainer datapaletteblock, PalettedContainer> palettedcontainerro) { + // CraftBukkit end +@@ -86,6 +87,7 @@ public class LevelChunkSection { if (!fluid.isEmpty()) { --this.tickingFluidCount; @@ -200,19 +200,19 @@ index a2a5aef769ee8bb638a5a9f3da9812fa4a85dda5..73b0bd67b5d3506383df3be065375c93 } if (!state.isAir()) { -@@ -116,6 +118,7 @@ public class LevelChunkSection { +@@ -100,6 +102,7 @@ public class LevelChunkSection { if (!fluid1.isEmpty()) { ++this.tickingFluidCount; + --this.fluidStateCount; // Leaves } - this.updateBlockCallback(x, y, z, iblockdata1, state); // Paper - optimise collisions -@@ -162,6 +165,7 @@ public class LevelChunkSection { + return iblockdata1; +@@ -145,6 +148,7 @@ public class LevelChunkSection { if (fluid.isRandomlyTicking()) { this.tickingFluidCount = (short) (this.tickingFluidCount + 1); } -+ this.fluidStateCount++; // Leaves ++ LevelChunkSection.this.fluidStateCount++; // Leaves } - // Paper start - optimise collisions + }); diff --git a/patches/server/0037-Reduce-chunk-loading-lookups.patch b/patches/server/0035-Reduce-chunk-loading-lookups.patch similarity index 93% rename from patches/server/0037-Reduce-chunk-loading-lookups.patch rename to patches/server/0035-Reduce-chunk-loading-lookups.patch index bd56adf5..81d2d1e0 100644 --- a/patches/server/0037-Reduce-chunk-loading-lookups.patch +++ b/patches/server/0035-Reduce-chunk-loading-lookups.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Reduce chunk loading & lookups This patch is Powered by Pufferfish(https://github.com/pufferfish-gg/Pufferfish) diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java -index 260202fab3ac300552c557b44dcf251f083c6a78..215176eb7152c11c4934c8576ac8c9fa9b2d0833 100644 +index 828c51477cd8f35d591367b30bf4feef6a250292..17a71bb3b65cc1030b70c931b1dc998d06713231 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java +++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java -@@ -318,11 +318,28 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -320,11 +320,28 @@ public class EnderMan extends Monster implements NeutralMob { private boolean teleport(double x, double y, double z) { BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(x, y, z); diff --git a/patches/server/0040-InstantBlockUpdater-Reintroduced.patch b/patches/server/0036-InstantBlockUpdater-Reintroduced.patch similarity index 61% rename from patches/server/0040-InstantBlockUpdater-Reintroduced.patch rename to patches/server/0036-InstantBlockUpdater-Reintroduced.patch index 64b6684c..fccaeb6e 100644 --- a/patches/server/0040-InstantBlockUpdater-Reintroduced.patch +++ b/patches/server/0036-InstantBlockUpdater-Reintroduced.patch @@ -6,25 +6,17 @@ Subject: [PATCH] InstantBlockUpdater Reintroduced This patch is Powered by Carpet-TIS-Addition(https://github.com/plusls/Carpet-TIS-Addition) diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index db64aef6cd6bc961c2b69853cb2f5a86a044d49d..099617d8aefc9b9f1bbcf2810af64b8152822291 100644 +index 6ff8be0ee869860d0afe0026f10aad1a108d0b56..133c90ee13587c441ecd47038d389353940ad3bf 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -73,6 +73,7 @@ import net.minecraft.world.level.lighting.LevelLightEngine; - import net.minecraft.world.level.material.FluidState; - import net.minecraft.world.level.material.Fluids; - import net.minecraft.world.level.redstone.CollectingNeighborUpdater; -+import net.minecraft.world.level.redstone.InstantNeighborUpdater; - import net.minecraft.world.level.redstone.NeighborUpdater; - import net.minecraft.world.level.saveddata.maps.MapId; - import net.minecraft.world.level.saveddata.maps.MapItemSavedData; -@@ -246,7 +247,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -303,7 +303,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl this.thread = Thread.currentThread(); this.biomeManager = new BiomeManager(this, i); this.isDebug = flag1; - this.neighborUpdater = new CollectingNeighborUpdater(this, j); + // Leaves start - instantBlockUpdaterReintroduced + if (org.leavesmc.leaves.LeavesConfig.instantBlockUpdaterReintroduced) { -+ this.neighborUpdater = new InstantNeighborUpdater(this); ++ this.neighborUpdater = new net.minecraft.world.level.redstone.InstantNeighborUpdater(this); + } else { + this.neighborUpdater = new CollectingNeighborUpdater(this, j); + } diff --git a/patches/server/0041-Random-flatten-triangular-distribution.patch b/patches/server/0037-Random-flatten-triangular-distribution.patch similarity index 100% rename from patches/server/0041-Random-flatten-triangular-distribution.patch rename to patches/server/0037-Random-flatten-triangular-distribution.patch diff --git a/patches/unapplied/server/0038-BBOR-Protocol.patch b/patches/server/0038-BBOR-Protocol.patch similarity index 94% rename from patches/unapplied/server/0038-BBOR-Protocol.patch rename to patches/server/0038-BBOR-Protocol.patch index d8f944ac..b0a9dd07 100644 --- a/patches/unapplied/server/0038-BBOR-Protocol.patch +++ b/patches/server/0038-BBOR-Protocol.patch @@ -5,22 +5,22 @@ Subject: [PATCH] BBOR Protocol diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index c1a50cedca731c08f793ba3eba4210bc26824e16..82751434c31fe8825f32921f498fd0156da15454 100644 +index 627c6b4bba6863ea89a2be2c3f163533e0d80147..4f3ae7cf3294583b738482964b78ebf2bd65cbbf 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -1623,6 +1623,7 @@ public abstract class PlayerList { +@@ -1563,6 +1563,7 @@ public abstract class PlayerList { entityplayer.getRecipeBook().sendInitialRecipeBook(entityplayer); } + org.leavesmc.leaves.protocol.BBORProtocol.onDataPackReload(); // Leaves - bbor } - public boolean isAllowCheatsForAllPlayers() { + public boolean isAllowCommandsForAllPlayers() { diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -index ae746ebde8ba2aded37bc1c9b3c4acdfd5f9def0..344ebb91a1cd4c74d398ded5edd8ef68047d19b2 100644 +index bfed0a72280631e6f20e6b5d493515c9b589db97..fa577dec9721c25f3c4897be939af7c2ba2e1c84 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -931,6 +931,11 @@ public class LevelChunk extends ChunkAccess { +@@ -746,6 +746,11 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p public void setLoaded(boolean loadedToWorld) { this.loaded = loadedToWorld; @@ -34,7 +34,7 @@ index ae746ebde8ba2aded37bc1c9b3c4acdfd5f9def0..344ebb91a1cd4c74d398ded5edd8ef68 public Level getLevel() { diff --git a/src/main/java/org/leavesmc/leaves/protocol/BBORProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/BBORProtocol.java new file mode 100644 -index 0000000000000000000000000000000000000000..4e1e099f6f480ae694405f0b1f98f429e2653d31 +index 0000000000000000000000000000000000000000..16ef00dde5a1c502449378829b1b6b85d6d145fd --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/BBORProtocol.java @@ -0,0 +1,227 @@ @@ -112,8 +112,8 @@ index 0000000000000000000000000000000000000000..4e1e099f6f480ae694405f0b1f98f429 + ServerLevel overworld = MinecraftServer.getServer().overworld(); + ProtocolUtils.sendPayloadPacket(player, INITIALIZE_CLIENT, buf -> { + buf.writeLong(overworld.getSeed()); -+ buf.writeInt(overworld.levelData.getXSpawn()); -+ buf.writeInt(overworld.levelData.getZSpawn()); ++ buf.writeInt(overworld.levelData.getSpawnPos().getX()); ++ buf.writeInt(overworld.levelData.getSpawnPos().getZ()); + }); + sendStructureList(player); + } diff --git a/patches/server/0038-Placeholder-of-PCA-sync-protocol.patch b/patches/server/0038-Placeholder-of-PCA-sync-protocol.patch deleted file mode 100644 index 222ec8fe..00000000 --- a/patches/server/0038-Placeholder-of-PCA-sync-protocol.patch +++ /dev/null @@ -1,15 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: MC_XiaoHei -Date: Tue, 7 May 2024 23:46:15 +0800 -Subject: [PATCH] Placeholder of PCA-sync-protocol - - -diff --git a/.gitignore b/.gitignore -index 3811c0d849a3eb028ed1a6b7a2d4747f7f570448..1ad93453221244f880855b510e888e759275b640 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -46,3 +46,4 @@ dependency-reduced-pom.xml - # vs code - /.vscode - /.factorypath -+ diff --git a/patches/unapplied/server/0037-PCA-sync-protocol.patch b/patches/server/0039-PCA-sync-protocol.patch similarity index 87% rename from patches/unapplied/server/0037-PCA-sync-protocol.patch rename to patches/server/0039-PCA-sync-protocol.patch index 0efadd62..e6dbec00 100644 --- a/patches/unapplied/server/0037-PCA-sync-protocol.patch +++ b/patches/server/0039-PCA-sync-protocol.patch @@ -6,10 +6,10 @@ Subject: [PATCH] PCA sync protocol This patch is Powered by plusls-carpet-addition(https://github.com/plusls/plusls-carpet-addition) diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java -index 815eb15086976b8f9e03bf8182d9ed50aec14720..50b690261be56ce1806c611c006d52c5ca02f9c5 100644 +index 1f5ed236fb7c0c1b0181675747d25d233f534284..08559ff5409d362bc674f63d6e46ced6c0474601 100644 --- a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java +++ b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java -@@ -373,6 +373,11 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, +@@ -436,6 +436,11 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, @Override public void containerChanged(Container sender) { @@ -20,15 +20,15 @@ index 815eb15086976b8f9e03bf8182d9ed50aec14720..50b690261be56ce1806c611c006d52c5 + // Leaves end - pca boolean flag = this.isSaddled(); - this.updateContainerEquipment(); + this.syncSaddleToClients(); diff --git a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java -index 4e6c2f6b2e54a4c126e9a026b9cad05ce835ad66..fd1648546542f146ba7b866873f105ed1427ef7d 100644 +index 49b35fab8ee98a384ee12d36bbe2ac813342f1d6..915b44434eebdd200bef38b4e5e8fcdf5cdcf5ad 100644 --- a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java +++ b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java -@@ -64,6 +64,15 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa +@@ -71,6 +71,15 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa super(type, world); - this.setPathfindingMalus(BlockPathTypes.DANGER_FIRE, 16.0F); - this.setPathfindingMalus(BlockPathTypes.DAMAGE_FIRE, -1.0F); + this.setPathfindingMalus(PathType.DANGER_FIRE, 16.0F); + this.setPathfindingMalus(PathType.DAMAGE_FIRE, -1.0F); + // Leaves start - pca + if (!this.level().isClientSide()) { + this.inventory.addListener(inventory -> { @@ -42,10 +42,10 @@ index 4e6c2f6b2e54a4c126e9a026b9cad05ce835ad66..fd1648546542f146ba7b866873f105ed @Override diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java -index 756d0434472921992c9d84597d7c9c824e93614c..efb69fdb0095c3d730f2a4608f15bf47a5a377a9 100644 +index 9549eee0d92f322bd5232abd7e695213660c2e22..6044de3b76e236e22d4d00f80dae0380ba82d354 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java -@@ -130,7 +130,13 @@ public abstract class AbstractMinecartContainer extends AbstractMinecart impleme +@@ -126,7 +126,13 @@ public abstract class AbstractMinecartContainer extends AbstractMinecart impleme } @Override @@ -61,10 +61,10 @@ index 756d0434472921992c9d84597d7c9c824e93614c..efb69fdb0095c3d730f2a4608f15bf47 @Override public boolean stillValid(Player player) { diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -index 89d06253b00604114e543ebbe12a9993ae95dc41..cb0cb894df65e6d4d65b369955a7d7d78fa7bc2b 100644 +index 730aca233f6e7564d4cb85b5b628d23c4f01d2f4..9ad4600ebee09d81b1785103ad17de47cf1f2ede 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -@@ -575,6 +575,16 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit +@@ -558,6 +558,16 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit } @@ -79,14 +79,14 @@ index 89d06253b00604114e543ebbe12a9993ae95dc41..cb0cb894df65e6d4d65b369955a7d7d7 + // Leaves end - pca + @Override - public boolean stillValid(net.minecraft.world.entity.player.Player player) { - return Container.stillValidBlockEntity(this, player); + public boolean canPlaceItem(int slot, ItemStack stack) { + if (slot == 2) { diff --git a/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java -index 416aa989ebb18a8741cc9d605a1180ab830f6643..213bc3c11ff4ed9bc761e8153aa669d1e2301960 100644 +index 6186e55014bbb9d5bedaa0e9d196879c55339d42..956c39ab508c2d8a7b9156aa53d655624db91f3d 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java -@@ -131,6 +131,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity { - this.items = list; +@@ -132,6 +132,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity { + this.items = inventory; } + // Leaves start - pca @@ -103,18 +103,10 @@ index 416aa989ebb18a8741cc9d605a1180ab830f6643..213bc3c11ff4ed9bc761e8153aa669d1 protected Component getDefaultName() { return Component.translatable("container.barrel"); diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java -index d445ed0895293dd45c36226051f5809be8587ebe..160df5cedf5d04c8a8d5d5375a898edc123684ac 100644 +index 7b263fab4f0014400b3b8e7e33db32f9a125f6ba..cb9d6f3f57192675dc18d9fa80b22498b29da368 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java -@@ -4,6 +4,7 @@ import com.google.common.collect.Lists; - import java.util.Arrays; - import java.util.Iterator; - import java.util.List; -+import java.util.Objects; - import javax.annotation.Nullable; - import net.minecraft.core.BlockPos; - import net.minecraft.core.Direction; -@@ -131,6 +132,11 @@ public class BeehiveBlockEntity extends BlockEntity { +@@ -143,6 +143,11 @@ public class BeehiveBlockEntity extends BlockEntity { super.setChanged(); } @@ -126,8 +118,8 @@ index d445ed0895293dd45c36226051f5809be8587ebe..160df5cedf5d04c8a8d5d5375a898edc return list; } -@@ -192,6 +198,12 @@ public class BeehiveBlockEntity extends BlockEntity { - this.level.gameEvent(GameEvent.BLOCK_CHANGE, blockposition, GameEvent.Context.of(entity, this.getBlockState())); +@@ -197,6 +202,12 @@ public class BeehiveBlockEntity extends BlockEntity { + this.level.gameEvent((Holder) GameEvent.BLOCK_CHANGE, blockposition, GameEvent.Context.of(entity, this.getBlockState())); } + // Leaves start - pca @@ -139,8 +131,8 @@ index d445ed0895293dd45c36226051f5809be8587ebe..160df5cedf5d04c8a8d5d5375a898edc entity.discard(EntityRemoveEvent.Cause.ENTER_BLOCK); // CraftBukkit - add Bukkit remove cause super.setChanged(); } -@@ -344,6 +356,11 @@ public class BeehiveBlockEntity extends BlockEntity { - if (BeehiveBlockEntity.releaseOccupant(world, pos, state, tileentitybeehive_hivebee, (List) null, tileentitybeehive_releasestatus, flowerPos)) { +@@ -312,6 +323,11 @@ public class BeehiveBlockEntity extends BlockEntity { + if (BeehiveBlockEntity.releaseOccupant(world, pos, state, tileentitybeehive_hivebee.toOccupant(), (List) null, tileentitybeehive_releasestatus, flowerPos)) { flag = true; iterator.remove(); + // Leaves start - pca @@ -150,8 +142,8 @@ index d445ed0895293dd45c36226051f5809be8587ebe..160df5cedf5d04c8a8d5d5375a898edc + // Leaves end - pca // CraftBukkit start } else { - tileentitybeehive_hivebee.exitTickCounter = tileentitybeehive_hivebee.minOccupationTicks / 2; // Not strictly Vanilla behaviour in cases where bees cannot spawn but still reasonable // Paper - Fix bees aging inside hives; use exitTickCounter to keep actual bee life -@@ -395,6 +412,11 @@ public class BeehiveBlockEntity extends BlockEntity { + tileentitybeehive_hivebee.exitTickCounter = tileentitybeehive_hivebee.occupant.minTicksInHive / 2; // Not strictly Vanilla behaviour in cases where bees cannot spawn but still reasonable // Paper - Fix bees aging inside hives; use exitTickCounter to keep actual bee life +@@ -357,6 +373,11 @@ public class BeehiveBlockEntity extends BlockEntity { this.maxBees = nbt.getInt("Bukkit.MaxEntities"); } // CraftBukkit end @@ -164,11 +156,11 @@ index d445ed0895293dd45c36226051f5809be8587ebe..160df5cedf5d04c8a8d5d5375a898edc @Override diff --git a/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java -index 9bb542ce3a8c52e1688bb1f66fc916dd23a5fd10..7356c6e03e4823a87a9918ef164b9438e0cec123 100644 +index a2fafef89d5354e2cb02f5672810909950a57777..54c18c771b96b30167cb5fb4ff1b0c9c63607d47 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java @@ -334,6 +334,16 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements - + return this.canPlaceItem(slot, stack); } + // Leaves start - pca @@ -182,14 +174,14 @@ index 9bb542ce3a8c52e1688bb1f66fc916dd23a5fd10..7356c6e03e4823a87a9918ef164b9438 + // Leaves end - pca + @Override - public boolean stillValid(Player player) { - return Container.stillValidBlockEntity(this, player); + public boolean canTakeItemThroughFace(int slot, ItemStack stack, Direction dir) { + return slot == 3 ? stack.is(Items.GLASS_BOTTLE) : true; diff --git a/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java -index 9b1243d96e0694c62fc9e82e9be540bce0d2b3ad..13e778bd47792deb571a5294bcf86cec5e04a5cc 100644 +index b88aa184cd06a0485146f58a5b61a56a50911209..4d4485f1007341a5303374b3facd033c87b887b3 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java -@@ -190,6 +190,16 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement - this.items = list; +@@ -191,6 +191,16 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement + this.items = inventory; } + // Leaves start - pca @@ -206,10 +198,10 @@ index 9b1243d96e0694c62fc9e82e9be540bce0d2b3ad..13e778bd47792deb571a5294bcf86cec public float getOpenNess(float tickDelta) { return this.chestLidController.getOpenness(tickDelta); diff --git a/src/main/java/net/minecraft/world/level/block/entity/ComparatorBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ComparatorBlockEntity.java -index 9b2c162c362fcf6093a3bf6da715ae8f18176c82..84b877a712a883b868b139d29da7e09c9552a1e5 100644 +index 7ea490a61321830c41dfa1bbd5480217dc62f478..d037adbe784d1b9e620d3c0798bc8b86061c5701 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/ComparatorBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/ComparatorBlockEntity.java -@@ -23,6 +23,16 @@ public class ComparatorBlockEntity extends BlockEntity { +@@ -24,6 +24,16 @@ public class ComparatorBlockEntity extends BlockEntity { this.output = nbt.getInt("OutputSignal"); } @@ -227,11 +219,11 @@ index 9b2c162c362fcf6093a3bf6da715ae8f18176c82..84b877a712a883b868b139d29da7e09c return this.output; } diff --git a/src/main/java/net/minecraft/world/level/block/entity/DispenserBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/DispenserBlockEntity.java -index 881379681c39230a00b3a1f11cd87498984396c7..e01eb2025458cf311348c58a1530854053af78f4 100644 +index 431fb6a658c6aac43b6f9dbd1f578b83f261a4e3..138c045dc694c596083bc2f23831ca22e9484297 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/DispenserBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/DispenserBlockEntity.java -@@ -92,6 +92,16 @@ public class DispenserBlockEntity extends RandomizableContainerBlockEntity { - return -1; +@@ -109,6 +109,16 @@ public class DispenserBlockEntity extends RandomizableContainerBlockEntity { + return stack; } + // Leaves start - pca @@ -248,11 +240,11 @@ index 881379681c39230a00b3a1f11cd87498984396c7..e01eb2025458cf311348c58a15308540 protected Component getDefaultName() { return Component.translatable("container.dispenser"); diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java -index cdb739df2a285032d25d84f4464f202a7a3fa578..cffc280655851e18439c9dfcb01ff69aab61e025 100644 +index 8310d132006043e93c612890514c4c7f3eb1c74d..f523f888f2a0ac04f25b30e18cdd765c395cfc18 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java -@@ -130,6 +130,16 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen - +@@ -134,6 +134,16 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen + this.facing = (Direction) state.getValue(HopperBlock.FACING); } + // Leaves start - pca @@ -268,7 +260,7 @@ index cdb739df2a285032d25d84f4464f202a7a3fa578..cffc280655851e18439c9dfcb01ff69a @Override protected Component getDefaultName() { return Component.translatable("container.hopper"); -@@ -209,6 +219,11 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen +@@ -212,6 +222,11 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen if (flag) { blockEntity.setCooldown(world.spigotConfig.hopperTransfer); // Spigot setChanged(world, pos, state); @@ -281,11 +273,11 @@ index cdb739df2a285032d25d84f4464f202a7a3fa578..cffc280655851e18439c9dfcb01ff69a } } diff --git a/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java -index 1fa22445a4ecc8c08dbcf0cc6bd39dc5003604c4..5c311270a39f6b4996c8b58822d24556c67adc41 100644 +index 0d68db20f5fbe5e834f12c1e8fd429099a44e4b6..5b62860cd64b5e6dc02dadb4651824ac04b00024 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java -@@ -269,6 +269,16 @@ public class ShulkerBoxBlockEntity extends RandomizableContainerBlockEntity impl - this.itemStacks = list; +@@ -270,6 +270,16 @@ public class ShulkerBoxBlockEntity extends RandomizableContainerBlockEntity impl + this.itemStacks = inventory; } + // Leaves start - pca @@ -303,16 +295,15 @@ index 1fa22445a4ecc8c08dbcf0cc6bd39dc5003604c4..5c311270a39f6b4996c8b58822d24556 return ShulkerBoxBlockEntity.SLOTS; diff --git a/src/main/java/org/leavesmc/leaves/protocol/PcaSyncProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/PcaSyncProtocol.java new file mode 100644 -index 0000000000000000000000000000000000000000..f4a7aed61511ad9557c8cc4779229b3bf79159dd +index 0000000000000000000000000000000000000000..7a86bdc3ddbed0399cdb909cb294d8f8bb5a894f --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/PcaSyncProtocol.java -@@ -0,0 +1,389 @@ +@@ -0,0 +1,391 @@ +package org.leavesmc.leaves.protocol; + +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.FriendlyByteBuf; -+import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; @@ -333,6 +324,7 @@ index 0000000000000000000000000000000000000000..f4a7aed61511ad9557c8cc4779229b3b +import org.leavesmc.leaves.LeavesConfig; +import org.leavesmc.leaves.LeavesLogger; +import org.leavesmc.leaves.bot.ServerBot; ++import org.leavesmc.leaves.protocol.core.LeavesCustomPayload; +import org.leavesmc.leaves.protocol.core.LeavesProtocol; +import org.leavesmc.leaves.protocol.core.ProtocolHandler; +import org.leavesmc.leaves.protocol.core.ProtocolUtils; @@ -522,7 +514,7 @@ index 0000000000000000000000000000000000000000..f4a7aed61511ad9557c8cc4779229b3b + ProtocolUtils.sendPayloadPacket(player, UPDATE_BLOCK_ENTITY, buf -> { + buf.writeResourceLocation(world.dimension().location()); + buf.writeBlockPos(blockEntity.getBlockPos()); -+ buf.writeNbt(blockEntity.saveWithId()); ++ buf.writeNbt(blockEntity.saveWithId(blockEntity.getLevel().registryAccess())); + }); + } + @@ -658,10 +650,11 @@ index 0000000000000000000000000000000000000000..f4a7aed61511ad9557c8cc4779229b3b + PcaSyncProtocol.clearPlayerWatchEntity(player); + } + -+ public record SyncBlockEntityPayload(BlockPos pos) implements CustomPacketPayload { ++ public record SyncBlockEntityPayload(BlockPos pos) implements LeavesCustomPayload { + + public static final ResourceLocation SYNC_BLOCK_ENTITY = PcaSyncProtocol.id("sync_block_entity"); + ++ @New + public SyncBlockEntityPayload(ResourceLocation id, FriendlyByteBuf buf) { + this(buf.readBlockPos()); + } @@ -677,10 +670,11 @@ index 0000000000000000000000000000000000000000..f4a7aed61511ad9557c8cc4779229b3b + } + } + -+ public record SyncEntityPayload(int entityId) implements CustomPacketPayload { ++ public record SyncEntityPayload(int entityId) implements LeavesCustomPayload { + + public static final ResourceLocation SYNC_ENTITY = PcaSyncProtocol.id("sync_entity"); + ++ @New + public SyncEntityPayload(ResourceLocation id, FriendlyByteBuf buf) { + this(buf.readInt()); + } diff --git a/patches/server/0039-Placeholder-of-BBOR-Protocol.patch b/patches/server/0039-Placeholder-of-BBOR-Protocol.patch deleted file mode 100644 index f756ecfe..00000000 --- a/patches/server/0039-Placeholder-of-BBOR-Protocol.patch +++ /dev/null @@ -1,15 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: MC_XiaoHei -Date: Tue, 7 May 2024 23:49:41 +0800 -Subject: [PATCH] Placeholder of BBOR-Protocol - - -diff --git a/.gitignore b/.gitignore -index 1ad93453221244f880855b510e888e759275b640..3811c0d849a3eb028ed1a6b7a2d4747f7f570448 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -46,4 +46,3 @@ dependency-reduced-pom.xml - # vs code - /.vscode - /.factorypath -- diff --git a/patches/server/0042-Jade-Protocol.patch b/patches/server/0040-Jade-Protocol.patch similarity index 99% rename from patches/server/0042-Jade-Protocol.patch rename to patches/server/0040-Jade-Protocol.patch index 29c22d7b..b0b0165a 100644 --- a/patches/server/0042-Jade-Protocol.patch +++ b/patches/server/0040-Jade-Protocol.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Jade Protocol This patch is Powered by Jade(https://github.com/Snownee/Jade) diff --git a/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java b/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java -index b38281f963377cc82b360e8457da7cad033b8c36..59f54bf1e86860a9fa35c444edc64ba141f4defb 100644 +index 792d9039ac0561464c666977ff8308e4c629e5eb..6510d70decdc32d3d9fa694ce9b4b1c7428bd282 100644 --- a/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java +++ b/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java -@@ -58,7 +58,7 @@ public class Armadillo extends Animal { +@@ -59,7 +59,7 @@ public class Armadillo extends Animal { public final AnimationState rollOutAnimationState = new AnimationState(); public final AnimationState rollUpAnimationState = new AnimationState(); public final AnimationState peekAnimationState = new AnimationState(); @@ -19,10 +19,10 @@ index b38281f963377cc82b360e8457da7cad033b8c36..59f54bf1e86860a9fa35c444edc64ba1 public Armadillo(EntityType type, Level world) { diff --git a/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java b/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java -index 290d41136f5ec7671bc4990dfe50da0a770c124d..600e03bf2bfbde245d53afa9ed312ebcd7ca8f03 100644 +index 43046f4a0cff620834ac4647efdcde227185b2ff..a08cd692e332a6caed33cd3db2373e847621ad6a 100644 --- a/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java +++ b/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java -@@ -255,7 +255,7 @@ public class Tadpole extends AbstractFish { +@@ -256,7 +256,7 @@ public class Tadpole extends AbstractFish { } @@ -32,10 +32,10 @@ index 290d41136f5ec7671bc4990dfe50da0a770c124d..600e03bf2bfbde245d53afa9ed312ebc } diff --git a/src/main/java/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java b/src/main/java/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java -index fca0131b9a90ac026a24cf579b17928c19173f3f..f8d0a8ea39cd90a9b45ff97e32e0e7224ddd8808 100644 +index 055f4b87c01ee7ecf7d2a111b72cc5aa85d9fbe8..5d9030f4787a43c56ae9455180badd5658dea35b 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java +++ b/src/main/java/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java -@@ -68,7 +68,7 @@ public class TrialSpawnerData { +@@ -72,7 +72,7 @@ public class TrialSpawnerData { }); public final Set detectedPlayers; public final Set currentMobs; @@ -46,7 +46,7 @@ index fca0131b9a90ac026a24cf579b17928c19173f3f..f8d0a8ea39cd90a9b45ff97e32e0e722 public Optional nextSpawnData; diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/JadeProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/jade/JadeProtocol.java new file mode 100644 -index 0000000000000000000000000000000000000000..cd5dfd55b6554e47a336c7aa4cb24db3cb4919dd +index 0000000000000000000000000000000000000000..33741d707715619929e5412a786470c5372f5978 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/jade/JadeProtocol.java @@ -0,0 +1,343 @@ @@ -160,7 +160,7 @@ index 0000000000000000000000000000000000000000..cd5dfd55b6554e47a336c7aa4cb24db3 + + @Contract("_ -> new") + public static @NotNull ResourceLocation mc_id(String path) { -+ return new ResourceLocation(path); ++ return ResourceLocation.withDefaultNamespace(path); + } + + private static boolean isPrimaryKey(ResourceLocation key) { @@ -824,7 +824,7 @@ index 0000000000000000000000000000000000000000..fd4112ed1911171b3c6b5840b7184b5f +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/provider/block/CampfireProvider.java b/src/main/java/org/leavesmc/leaves/protocol/jade/provider/block/CampfireProvider.java new file mode 100644 -index 0000000000000000000000000000000000000000..d22013480b53017db71697af37c0b3daa19c7ac5 +index 0000000000000000000000000000000000000000..a1a479987f2c0b6ff4cfd511cbcac1ea7b1c247b --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/jade/provider/block/CampfireProvider.java @@ -0,0 +1,52 @@ @@ -864,7 +864,7 @@ index 0000000000000000000000000000000000000000..d22013480b53017db71697af37c0b3da + stack = stack.copy(); + + CustomData customData = stack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY) -+ .update(COOKING_TIME_CODEC, campfire.cookingTime[i] - campfire.cookingProgress[i]) ++ .update(NbtOps.INSTANCE, COOKING_TIME_CODEC, campfire.cookingTime[i] - campfire.cookingProgress[i]) + .getOrThrow(); + stack.set(DataComponents.CUSTOM_DATA, customData); + diff --git a/patches/server/0043-Alternative-block-placement-Protocol.patch b/patches/server/0041-Alternative-block-placement-Protocol.patch similarity index 83% rename from patches/server/0043-Alternative-block-placement-Protocol.patch rename to patches/server/0041-Alternative-block-placement-Protocol.patch index 835b4654..eacc13b9 100644 --- a/patches/server/0043-Alternative-block-placement-Protocol.patch +++ b/patches/server/0041-Alternative-block-placement-Protocol.patch @@ -9,15 +9,34 @@ MasaGadget(https://github.com/plusls/MasaGadget) litematica(https://github.com/maruohon/litematica) diff --git a/src/main/java/net/minecraft/world/item/BlockItem.java b/src/main/java/net/minecraft/world/item/BlockItem.java -index 96fb69ec6db2e7c8c728435f0c537b076259b2fb..7632d5ac83c84e943654477b3f36e6605e28c9a7 100644 +index 96fb69ec6db2e7c8c728435f0c537b076259b2fb..29f38a0a87cb7e27ac18c09dd59e774cfd874592 100644 --- a/src/main/java/net/minecraft/world/item/BlockItem.java +++ b/src/main/java/net/minecraft/world/item/BlockItem.java -@@ -162,7 +162,7 @@ public class BlockItem extends Item { - +@@ -163,6 +163,27 @@ public class BlockItem extends Item { @Nullable protected BlockState getPlacementState(BlockPlaceContext context) { -- BlockState iblockdata = this.getBlock().getStateForPlacement(context); -+ BlockState iblockdata = this.getBlock().getRealStateForPlacement(context); // Leaves - alternativeBlockPlacement + BlockState iblockdata = this.getBlock().getStateForPlacement(context); ++ // Leaves start - alternativeBlockPlacement ++ switch (org.leavesmc.leaves.LeavesConfig.alternativeBlockPlacement) { ++ case CARPET -> { ++ BlockState tryState = org.leavesmc.leaves.protocol.CarpetAlternativeBlockPlacement.alternativeBlockPlacement(getBlock(), context); ++ if (tryState != null) { ++ iblockdata = tryState; ++ } ++ } ++ case CARPET_FIX -> { ++ BlockState tryState = org.leavesmc.leaves.protocol.CarpetAlternativeBlockPlacement.alternativeBlockPlacementFix(getBlock(), context); ++ if (tryState != null) { ++ iblockdata = tryState; ++ } ++ } ++ case LITEMATICA -> { ++ if (iblockdata != null && this.canPlace(context, iblockdata)) { ++ return org.leavesmc.leaves.protocol.LitematicaEasyPlaceProtocol.applyPlacementProtocol(iblockdata, context); ++ } ++ } ++ } ++ // Leaves end - alternativeBlockPlacement return iblockdata != null && this.canPlace(context, iblockdata) ? iblockdata : null; } @@ -44,10 +63,10 @@ index f8f909ebdad5e96379e8bd8c610164ef0697368e..0b761f3ae15ad4a3b8152f497a604032 if (iblockdata2 != null && this.canPlace(world, iblockdata2, blockposition)) { iblockdata1 = iblockdata2; 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 e27f2317e4e2f13b6ef12be727046497a750fd3a..549f77998274404b1b475230d88568fd3e27ac6d 100644 +index 992c778f4a826be8d7a5a5d96bf7968b741f490e..9fa6c828471bfba2209bd4903e7240e05b6ee2ec 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java -@@ -412,6 +412,33 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -411,6 +411,33 @@ public class Block extends BlockBehaviour implements ItemLike { public void stepOn(Level world, BlockPos pos, BlockState state, Entity entity) {} @@ -83,10 +102,10 @@ index e27f2317e4e2f13b6ef12be727046497a750fd3a..549f77998274404b1b475230d88568fd return this.defaultBlockState(); diff --git a/src/main/java/org/leavesmc/leaves/protocol/CarpetAlternativeBlockPlacement.java b/src/main/java/org/leavesmc/leaves/protocol/CarpetAlternativeBlockPlacement.java new file mode 100644 -index 0000000000000000000000000000000000000000..100356d5b0f62b62e1bcb02ca515225179fc0cc6 +index 0000000000000000000000000000000000000000..03978356d2716296f8c5e4173d10862db57a3193 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/CarpetAlternativeBlockPlacement.java -@@ -0,0 +1,161 @@ +@@ -0,0 +1,162 @@ +package org.leavesmc.leaves.protocol; + +import net.minecraft.core.BlockPos; @@ -127,8 +146,9 @@ index 0000000000000000000000000000000000000000..100356d5b0f62b62e1bcb02ca5152251 + BlockPos blockPos = context.getClickedPos(); + double relativeHitX = hitPos.x - blockPos.getX(); + BlockState state = block.getStateForPlacement(context); ++ Player player = context.getPlayer(); + -+ if (relativeHitX < 2 || state == null) { ++ if (relativeHitX < 2 || state == null || player == null) { + return null; + } + @@ -147,7 +167,7 @@ index 0000000000000000000000000000000000000000..100356d5b0f62b62e1bcb02ca5152251 + } + + if (!directionProp.getPossibleValues().contains(facing)) { -+ facing = context.getPlayer().getDirection().getOpposite(); ++ facing = player.getDirection().getOpposite(); + } + + if (facing != origFacing && directionProp.getPossibleValues().contains(facing)) { @@ -250,15 +270,16 @@ index 0000000000000000000000000000000000000000..100356d5b0f62b62e1bcb02ca5152251 +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/LitematicaEasyPlaceProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/LitematicaEasyPlaceProtocol.java new file mode 100644 -index 0000000000000000000000000000000000000000..7a49e2591e1eabf9d9444d530f631f038a7a47aa +index 0000000000000000000000000000000000000000..affe9b0aa16968ad8832d94af06fd84323830cbb --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/LitematicaEasyPlaceProtocol.java -@@ -0,0 +1,214 @@ +@@ -0,0 +1,195 @@ +package org.leavesmc.leaves.protocol; + +import com.google.common.collect.ImmutableSet; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; ++import net.minecraft.util.Mth; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.context.BlockPlaceContext; @@ -271,7 +292,6 @@ index 0000000000000000000000000000000000000000..7a49e2591e1eabf9d9444d530f631f03 +import net.minecraft.world.level.block.state.properties.SlabType; +import net.minecraft.world.phys.Vec3; +import org.leavesmc.leaves.LeavesLogger; -+import org.leavesmc.leaves.util.MathUtils; + +import javax.annotation.Nullable; +import java.util.ArrayList; @@ -281,42 +301,31 @@ index 0000000000000000000000000000000000000000..7a49e2591e1eabf9d9444d530f631f03 +public class LitematicaEasyPlaceProtocol { + + public static final ImmutableSet> WHITELISTED_PROPERTIES = ImmutableSet.of( -+ // BooleanProperty: -+ // INVERTED - DaylightDetector -+ // OPEN - Barrel, Door, FenceGate, Trapdoor -+ // PERSISTENT - Leaves + BlockStateProperties.INVERTED, + BlockStateProperties.OPEN, + BlockStateProperties.PERSISTENT, -+ // EnumProperty: -+ // AXIS - Pillar -+ // BLOCK_HALF - Stairs, Trapdoor -+ // CHEST_TYPE - Chest -+ // COMPARATOR_MODE - Comparator -+ // DOOR_HINGE - Door -+ // SLAB_TYPE - Slab - PARTIAL ONLY: TOP and BOTTOM, not DOUBLE -+ // STAIR_SHAPE - Stairs (needed to get the correct state, otherwise the player facing would be a factor) -+ // WALL_MOUNT_LOCATION - Button, Grindstone, Lever ++ BlockStateProperties.CAN_SUMMON, ++ BlockStateProperties.BELL_ATTACHMENT, + BlockStateProperties.AXIS, ++ BlockStateProperties.BED_PART, + BlockStateProperties.HALF, ++ BlockStateProperties.ATTACH_FACE, + BlockStateProperties.CHEST_TYPE, + BlockStateProperties.MODE_COMPARATOR, + BlockStateProperties.DOOR_HINGE, ++ BlockStateProperties.DOUBLE_BLOCK_HALF, ++ BlockStateProperties.ORIENTATION, ++ BlockStateProperties.RAIL_SHAPE, ++ BlockStateProperties.RAIL_SHAPE_STRAIGHT, + BlockStateProperties.SLAB_TYPE, + BlockStateProperties.STAIRS_SHAPE, -+ BlockStateProperties.ATTACH_FACE, -+ // IntProperty: -+ // BITES - Cake -+ // DELAY - Repeater -+ // NOTE - NoteBlock -+ // ROTATION - Banner, Sign, Skull + BlockStateProperties.BITES, + BlockStateProperties.DELAY, + BlockStateProperties.NOTE, + BlockStateProperties.ROTATION_16 + ); + -+ public static > BlockState applyPlacementProtocol(BlockState state, BlockPlaceContext context) { ++ public static BlockState applyPlacementProtocol(BlockState state, BlockPlaceContext context) { + return applyPlacementProtocolV3(state, UseContext.from(context, context.getHand())); + } + @@ -326,7 +335,7 @@ index 0000000000000000000000000000000000000000..7a49e2591e1eabf9d9444d530f631f03 + return state; + } + -+ @Nullable DirectionProperty property = getFirstDirectionProperty(state); ++ @Nullable DirectionProperty property = CarpetAlternativeBlockPlacement.getFirstDirectionProperty(state); + + if (property != null && property != BlockStateProperties.VERTICAL_DIRECTION) { + state = applyDirectionProperty(state, context, property, protocolValue); @@ -346,15 +355,16 @@ index 0000000000000000000000000000000000000000..7a49e2591e1eabf9d9444d530f631f03 + try { + for (Property p : propList) { + if (!(p instanceof DirectionProperty) && WHITELISTED_PROPERTIES.contains(p)) { -+ @SuppressWarnings("unchecked") Property prop = (Property) p; ++ @SuppressWarnings("unchecked") ++ Property prop = (Property) p; + List list = new ArrayList<>(prop.getPossibleValues()); + list.sort(Comparable::compareTo); + -+ int requiredBits = MathUtils.floorLog2(MathUtils.smallestEncompassingPowerOfTwo(list.size())); ++ int requiredBits = Mth.log2(Mth.smallestEncompassingPowerOfTwo(list.size())); + int bitMask = ~(0xFFFFFFFF << requiredBits); + int valueIndex = protocolValue & bitMask; + -+ if (valueIndex >= 0 && valueIndex < list.size()) { ++ if (valueIndex < list.size()) { + T value = list.get(valueIndex); + + if (!state.getValue(prop).equals(value) && value != SlabType.DOUBLE) { @@ -379,7 +389,7 @@ index 0000000000000000000000000000000000000000..7a49e2591e1eabf9d9444d530f631f03 + + if (decodedFacingIndex == 6) { + facing = facing.getOpposite(); -+ } else if (decodedFacingIndex >= 0 && decodedFacingIndex <= 5) { ++ } else if (decodedFacingIndex <= 5) { + facing = Direction.from3DDataValue(decodedFacingIndex); + + if (!property.getPossibleValues().contains(facing)) { @@ -403,15 +413,6 @@ index 0000000000000000000000000000000000000000..7a49e2591e1eabf9d9444d530f631f03 + return state; + } + -+ private static DirectionProperty getFirstDirectionProperty(BlockState state) { -+ for (Property prop : state.getProperties()) { -+ if (prop instanceof DirectionProperty) { -+ return (DirectionProperty) prop; -+ } -+ } -+ return null; -+ } -+ + public static class UseContext { + + private final Level world; @@ -468,37 +469,3 @@ index 0000000000000000000000000000000000000000..7a49e2591e1eabf9d9444d530f631f03 + } + } +} -diff --git a/src/main/java/org/leavesmc/leaves/util/MathUtils.java b/src/main/java/org/leavesmc/leaves/util/MathUtils.java -index 6c42b029d98ed293645f06dde6838761f87f20bb..cd66a5f1b544640de1277cef870a60b53e1a128b 100644 ---- a/src/main/java/org/leavesmc/leaves/util/MathUtils.java -+++ b/src/main/java/org/leavesmc/leaves/util/MathUtils.java -@@ -75,4 +75,29 @@ public class MathUtils { - - return vector; - } -+ -+ private static final int[] MULTIPLY_DE_BRUIJN_BIT_POSITION = new int[]{0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9}; -+ -+ public static int floorLog2(int value) { -+ return ceilLog2(value) - (isPowerOfTwo(value) ? 0 : 1); -+ } -+ -+ public static int ceilLog2(int value) { -+ value = isPowerOfTwo(value) ? value : smallestEncompassingPowerOfTwo(value); -+ return MULTIPLY_DE_BRUIJN_BIT_POSITION[(int)((long)value * 125613361L >> 27) & 31]; -+ } -+ -+ public static boolean isPowerOfTwo(int value) { -+ return value != 0 && (value & value - 1) == 0; -+ } -+ -+ public static int smallestEncompassingPowerOfTwo(int value) { -+ int i = value - 1; -+ i |= i >> 1; -+ i |= i >> 2; -+ i |= i >> 4; -+ i |= i >> 8; -+ i |= i >> 16; -+ return i + 1; -+ } - } diff --git a/patches/server/0044-Player-operation-limiter.patch b/patches/server/0042-Player-operation-limiter.patch similarity index 70% rename from patches/server/0044-Player-operation-limiter.patch rename to patches/server/0042-Player-operation-limiter.patch index 0968a6f9..82be8c39 100644 --- a/patches/server/0044-Player-operation-limiter.patch +++ b/patches/server/0042-Player-operation-limiter.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Player operation limiter This patch is Powered by plusls-carpet-addition(https://github.com/plusls/plusls-carpet-addition) diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 1b64253c30d1528f7401f15eaa336bbf183dc9d2..e74084548930664d4795d10a3f3448877128c88f 100644 +index 5afef331ec117adae0c29f5c4b9f43b7be7cdd4c..a873d07351f8909f71805eec16a2e8dc22de3bb4 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -299,6 +299,10 @@ public class ServerPlayer extends Player { +@@ -301,6 +301,10 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent public @Nullable String clientBrandName = null; // Paper - Brand support public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event @@ -18,9 +18,9 @@ index 1b64253c30d1528f7401f15eaa336bbf183dc9d2..e74084548930664d4795d10a3f344887 + private int placeBlockCountPerTick = 0; + // Leaves end - player operation limiter - // Paper start - replace player chunk loader - private final java.util.concurrent.atomic.AtomicReference viewDistances = new java.util.concurrent.atomic.AtomicReference<>(new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances(-1, -1, -1)); -@@ -774,6 +778,7 @@ public class ServerPlayer extends Player { + // Paper start - rewrite chunk system + private ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader; +@@ -764,6 +768,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple this.joining = false; } // CraftBukkit end @@ -28,7 +28,7 @@ index 1b64253c30d1528f7401f15eaa336bbf183dc9d2..e74084548930664d4795d10a3f344887 this.gameMode.tick(); this.wardenSpawnTracker.tick(); --this.spawnInvulnerableTime; -@@ -2883,5 +2888,32 @@ public class ServerPlayer extends Player { +@@ -2945,5 +2950,32 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple public CraftPlayer getBukkitEntity() { return (CraftPlayer) super.getBukkitEntity(); } @@ -62,18 +62,10 @@ index 1b64253c30d1528f7401f15eaa336bbf183dc9d2..e74084548930664d4795d10a3f344887 // CraftBukkit end } diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -index 1047027610624c9ba4bb5afd5d7f0714a062b198..2afa036e7dcd52ec71b62cd0e30ce1b539459c55 100644 +index 24b1715397ba8e6f5e9841a030d0e3d964356f89..c0d29abf5a21015a4a0334549c0fd9b9f585f834 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -@@ -43,6 +43,7 @@ import org.bukkit.event.Event; - import org.bukkit.event.block.Action; - import org.bukkit.event.player.PlayerGameModeChangeEvent; - import org.bukkit.event.player.PlayerInteractEvent; -+import org.leavesmc.leaves.event.player.PlayerOperationLimitEvent; - // CraftBukkit end - - public class ServerPlayerGameMode { -@@ -334,6 +335,19 @@ public class ServerPlayerGameMode { +@@ -339,6 +339,19 @@ public class ServerPlayerGameMode { } public void destroyAndAck(BlockPos pos, int sequence, String reason) { @@ -82,7 +74,7 @@ index 1047027610624c9ba4bb5afd5d7f0714a062b198..2afa036e7dcd52ec71b62cd0e30ce1b5 + if (reason.equals("insta mine")) { + player.addInstaBreakCountPerTick(); + if (!player.allowOperation()) { -+ MinecraftServer.getServer().server.getPluginManager().callEvent(new PlayerOperationLimitEvent(player.getBukkitEntity(), PlayerOperationLimitEvent.Operation.MINE, CraftBlock.at(level, pos))); ++ MinecraftServer.getServer().server.getPluginManager().callEvent(new org.leavesmc.leaves.event.player.PlayerOperationLimitEvent(player.getBukkitEntity(), org.leavesmc.leaves.event.player.PlayerOperationLimitEvent.Operation.MINE, CraftBlock.at(level, pos))); + this.player.connection.send(new ClientboundBlockUpdatePacket(pos, this.level.getBlockState(pos))); + this.debugLogging(pos, false, sequence, reason); + return; @@ -94,22 +86,10 @@ index 1047027610624c9ba4bb5afd5d7f0714a062b198..2afa036e7dcd52ec71b62cd0e30ce1b5 this.debugLogging(pos, true, sequence, reason); } else { diff --git a/src/main/java/net/minecraft/world/item/BlockItem.java b/src/main/java/net/minecraft/world/item/BlockItem.java -index 7632d5ac83c84e943654477b3f36e6605e28c9a7..c21a65d9637739f1040dd27b096101a7a7adc0df 100644 +index 29f38a0a87cb7e27ac18c09dd59e774cfd874592..2759a9eeef85b323b7e1ea78090f4f9d637c938a 100644 --- a/src/main/java/net/minecraft/world/item/BlockItem.java +++ b/src/main/java/net/minecraft/world/item/BlockItem.java -@@ -32,8 +32,11 @@ import net.minecraft.world.level.block.state.BlockState; - import net.minecraft.world.level.gameevent.GameEvent; - import net.minecraft.world.phys.shapes.CollisionContext; - import org.bukkit.craftbukkit.block.CraftBlock; -+import org.bukkit.craftbukkit.block.CraftBlockState; -+import org.bukkit.craftbukkit.CraftServer; - import org.bukkit.craftbukkit.block.data.CraftBlockData; - import org.bukkit.event.block.BlockCanBuildEvent; -+import org.leavesmc.leaves.event.player.PlayerOperationLimitEvent; - // CraftBukkit end - - public class BlockItem extends Item { -@@ -80,6 +83,20 @@ public class BlockItem extends Item { +@@ -80,6 +80,20 @@ public class BlockItem extends Item { final org.bukkit.block.BlockState oldBlockstate = blockstate != null ? blockstate : org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(blockactioncontext1.getLevel(), blockactioncontext1.getClickedPos()); // Paper - Reset placed block on exception // CraftBukkit end @@ -120,7 +100,7 @@ index 7632d5ac83c84e943654477b3f36e6605e28c9a7..c21a65d9637739f1040dd27b096101a7 + player.addPlaceBlockCountPerTick(); + if (!player.allowOperation()) { + if (blockstate != null) { -+ MinecraftServer.getServer().server.getPluginManager().callEvent(new PlayerOperationLimitEvent(player.getBukkitEntity(), PlayerOperationLimitEvent.Operation.PLACE, blockstate.getBlock())); ++ MinecraftServer.getServer().server.getPluginManager().callEvent(new org.leavesmc.leaves.event.player.PlayerOperationLimitEvent(player.getBukkitEntity(), org.leavesmc.leaves.event.player.PlayerOperationLimitEvent.Operation.PLACE, blockstate.getBlock())); + } + return InteractionResult.FAIL; + } diff --git a/patches/server/0045-Renewable-Elytra.patch b/patches/server/0043-Renewable-Elytra.patch similarity index 65% rename from patches/server/0045-Renewable-Elytra.patch rename to patches/server/0043-Renewable-Elytra.patch index 7d5c511f..d340ed4a 100644 --- a/patches/server/0045-Renewable-Elytra.patch +++ b/patches/server/0043-Renewable-Elytra.patch @@ -6,19 +6,10 @@ Subject: [PATCH] Renewable Elytra This patch is Powered by Carpet-TIS-Addition(https://github.com/plusls/Carpet-TIS-Addition) diff --git a/src/main/java/net/minecraft/world/entity/monster/Phantom.java b/src/main/java/net/minecraft/world/entity/monster/Phantom.java -index 68f8945292753535a3b73acb9f48c1594f0789a4..da5df2271a8192bf4c86772bd84107e55f3040aa 100644 +index c277dac448a64809e93dd7a447ee3dc2a86c860e..5641da81d6f00e153d847b9284251084d545e726 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java +++ b/src/main/java/net/minecraft/world/entity/monster/Phantom.java -@@ -35,6 +35,8 @@ import net.minecraft.world.entity.ai.goal.Goal; - import net.minecraft.world.entity.ai.targeting.TargetingConditions; - import net.minecraft.world.entity.animal.Cat; - import net.minecraft.world.entity.player.Player; -+import net.minecraft.world.item.ItemStack; -+import net.minecraft.world.item.Items; - import net.minecraft.world.level.Level; - import net.minecraft.world.level.ServerLevelAccessor; - import net.minecraft.world.level.levelgen.Heightmap; -@@ -233,6 +235,20 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -233,6 +233,20 @@ public class Phantom extends FlyingMob implements Enemy { return entitysize.scale(1.0F + 0.15F * (float) i); } @@ -28,7 +19,7 @@ index 68f8945292753535a3b73acb9f48c1594f0789a4..da5df2271a8192bf4c86772bd84107e5 + super.dropFromLootTable(source, causedByPlayer); + if (org.leavesmc.leaves.LeavesConfig.renewableElytra > 0.0D) { + if (source.getEntity() instanceof Shulker && this.random.nextDouble() < org.leavesmc.leaves.LeavesConfig.renewableElytra) { -+ ItemStack item = new ItemStack(Items.ELYTRA); ++ net.minecraft.world.item.ItemStack item = new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.ELYTRA); + item.setDamageValue(432); + this.spawnAtLocation(item); + } diff --git a/patches/server/0046-Stackable-ShulkerBoxes.patch b/patches/server/0044-Stackable-ShulkerBoxes.patch similarity index 95% rename from patches/server/0046-Stackable-ShulkerBoxes.patch rename to patches/server/0044-Stackable-ShulkerBoxes.patch index 73c8a458..7ad9b124 100644 --- a/patches/server/0046-Stackable-ShulkerBoxes.patch +++ b/patches/server/0044-Stackable-ShulkerBoxes.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Stackable ShulkerBoxes This patch is Powered by fabric-carpet(https://github.com/gnembon/fabric-carpet) and plusls-carpet-addition(https://github.com/plusls/plusls-carpet-addition) 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 8fd3845c4965843be9c37498760d93f1ebdff541..d3fa592892fc72c8fc8f23e8e477eb88902bba16 100644 +index ea0d9335446b20073b9aafb9de453097355db79c..38c2e27343d68d016621cf953222b915b56a0df2 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java @@ -22,10 +22,12 @@ import net.minecraft.world.entity.EntityType; @@ -20,9 +20,9 @@ index 8fd3845c4965843be9c37498760d93f1ebdff541..d3fa592892fc72c8fc8f23e8e477eb88 import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.ShulkerBoxBlock; import net.minecraft.world.level.gameevent.GameEvent; + import net.minecraft.world.level.portal.DimensionTransition; import net.minecraft.world.phys.Vec3; - // CraftBukkit start -@@ -35,6 +37,7 @@ import net.minecraft.sounds.SoundSource; +@@ -36,6 +38,7 @@ import net.minecraft.sounds.SoundSource; import net.minecraft.stats.Stats; import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.entity.Player; @@ -30,7 +30,7 @@ index 8fd3845c4965843be9c37498760d93f1ebdff541..d3fa592892fc72c8fc8f23e8e477eb88 import org.bukkit.event.entity.EntityPickupItemEvent; import org.bukkit.event.entity.EntityRemoveEvent; import org.bukkit.event.player.PlayerPickupItemEvent; -@@ -78,6 +81,13 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -79,6 +82,13 @@ public class ItemEntity extends Entity implements TraceableEntity { this.setDeltaMovement(this.random.nextDouble() * 0.2D - 0.1D, 0.2D, this.random.nextDouble() * 0.2D - 0.1D); this.setItem(stack); // Paper end - Don't use level random in entity constructors @@ -44,7 +44,7 @@ index 8fd3845c4965843be9c37498760d93f1ebdff541..d3fa592892fc72c8fc8f23e8e477eb88 } public ItemEntity(Level world, double x, double y, double z, ItemStack stack, double velocityX, double velocityY, double velocityZ) { -@@ -314,10 +324,49 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -315,10 +325,49 @@ public class ItemEntity extends Entity implements TraceableEntity { private boolean isMergable() { ItemStack itemstack = this.getItem(); @@ -96,10 +96,10 @@ index 8fd3845c4965843be9c37498760d93f1ebdff541..d3fa592892fc72c8fc8f23e8e477eb88 ItemStack itemstack1 = other.getItem(); diff --git a/src/main/java/net/minecraft/world/entity/player/Inventory.java b/src/main/java/net/minecraft/world/entity/player/Inventory.java -index 3c8f35f92ed7e9518d676087f82d1e4da963b779..9037c6c8f0947e72e02552557f3c47625927681e 100644 +index eb11482f48c9f330b7fa62a278fd6f07d3a642e1..8631f3a5ce5aa24f195d5031dad6d289e4389314 100644 --- a/src/main/java/net/minecraft/world/entity/player/Inventory.java +++ b/src/main/java/net/minecraft/world/entity/player/Inventory.java -@@ -114,7 +114,7 @@ public class Inventory implements Container, Nameable { +@@ -111,7 +111,7 @@ public class Inventory implements Container, Nameable { } private boolean hasRemainingSpaceForItem(ItemStack existingStack, ItemStack stack) { @@ -108,7 +108,7 @@ index 3c8f35f92ed7e9518d676087f82d1e4da963b779..9037c6c8f0947e72e02552557f3c4762 } // CraftBukkit start - Watch method above! :D -@@ -282,7 +282,9 @@ public class Inventory implements Container, Nameable { +@@ -279,7 +279,9 @@ public class Inventory implements Container, Nameable { this.setItem(slot, itemstack1); } @@ -119,7 +119,7 @@ index 3c8f35f92ed7e9518d676087f82d1e4da963b779..9037c6c8f0947e72e02552557f3c4762 int l = Math.min(j, k); if (l == 0) { -@@ -397,7 +399,7 @@ public class Inventory implements Container, Nameable { +@@ -394,7 +396,7 @@ public class Inventory implements Container, Nameable { } if (i != -1) { @@ -207,10 +207,10 @@ index c39c773112fb8b534b926f2f2b47fe6fbb69fcb2..ae9338b8a5598e7a257b469adae72858 @Nullable diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index f8589837070039b4911a9532b92fa959c7af6352..35e0aac4dc32227c48dc3a0f3a15c02a700fc402 100644 +index 312b57b4ef340935f4335989ce1d6a4b8b61532c..fa3dbb93a049962fe10cb0391d437acdb45c82af 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -228,7 +228,7 @@ public final class ItemStack implements DataComponentHolder { +@@ -225,7 +225,7 @@ public final class ItemStack implements DataComponentHolder { @Deprecated @Nullable private Item item; @@ -253,10 +253,10 @@ index 20f2b575c8131621edea0e75fbf38a9fe20a36c4..812856b02cab1c437550ba9c706da318 protected VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { return SHAPE; diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java -index 8310d132006043e93c612890514c4c7f3eb1c74d..592b330f187fb5eca51d60911bbebbaeaf46ef87 100644 +index f523f888f2a0ac04f25b30e18cdd765c395cfc18..d9421224778c72f8f9db3c9044bc28c2423bb09d 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java -@@ -728,9 +728,9 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen +@@ -743,9 +743,9 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen if (itemstack1.isEmpty()) { // Spigot start - SPIGOT-6693, InventorySubcontainer#setItem ItemStack leftover = ItemStack.EMPTY; // Paper - Make hoppers respect inventory max stack size diff --git a/patches/server/0047-Improve-fluid-direction-caching.patch b/patches/server/0045-Improve-fluid-direction-caching.patch similarity index 96% rename from patches/server/0047-Improve-fluid-direction-caching.patch rename to patches/server/0045-Improve-fluid-direction-caching.patch index 7b221e56..d92b446c 100644 --- a/patches/server/0047-Improve-fluid-direction-caching.patch +++ b/patches/server/0045-Improve-fluid-direction-caching.patch @@ -7,7 +7,7 @@ This patch is Powered by Pufferfish (https://github.com/pufferfish-gg/Pufferfish) diff --git a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java -index c2943d892b067b3f1fb3b93301a092e912d71f08..d5352883ee51dfc646352ae7e2b76af7efd0441e 100644 +index 1c0712295695727ee9c4d430d4157b8e17cbd71f..1687ab4965433459219bb5d8aaf5ec8e5baeb605 100644 --- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java +++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java @@ -53,6 +53,11 @@ public abstract class FlowingFluid extends Fluid { @@ -22,18 +22,12 @@ index c2943d892b067b3f1fb3b93301a092e912d71f08..d5352883ee51dfc646352ae7e2b76af7 private final Map shapes = Maps.newIdentityHashMap(); public FlowingFluid() {} -@@ -251,40 +256,71 @@ public abstract class FlowingFluid extends Fluid { - return false; - } - // Paper end - optimise collisions -- Object2ByteLinkedOpenHashMap object2bytelinkedopenhashmap; +@@ -240,40 +245,70 @@ public abstract class FlowingFluid extends Fluid { + } -- if (!state.getBlock().hasDynamicShape() && !fromState.getBlock().hasDynamicShape()) { -- object2bytelinkedopenhashmap = (Object2ByteLinkedOpenHashMap) FlowingFluid.OCCLUSION_CACHE.get(); -- } else { -- object2bytelinkedopenhashmap = null; -- } -+ // Leaves start - cache + private boolean canPassThroughWall(Direction face, BlockGetter world, BlockPos pos, BlockState state, BlockPos fromPos, BlockState fromState) { +- Object2ByteLinkedOpenHashMap object2bytelinkedopenhashmap; ++ // Leaves end - cache + if (!org.leavesmc.leaves.LeavesConfig.improveFluidDirectionCaching) { + Object2ByteLinkedOpenHashMap object2bytelinkedopenhashmap; + @@ -42,7 +36,12 @@ index c2943d892b067b3f1fb3b93301a092e912d71f08..d5352883ee51dfc646352ae7e2b76af7 + } else { + object2bytelinkedopenhashmap = null; + } -+ + +- if (!state.getBlock().hasDynamicShape() && !fromState.getBlock().hasDynamicShape()) { +- object2bytelinkedopenhashmap = (Object2ByteLinkedOpenHashMap) FlowingFluid.OCCLUSION_CACHE.get(); +- } else { +- object2bytelinkedopenhashmap = null; +- } + Block.BlockStatePairKey block_a; + + if (object2bytelinkedopenhashmap != null) { diff --git a/patches/server/0048-MC-Technical-Survival-Mode.patch b/patches/server/0046-MC-Technical-Survival-Mode.patch similarity index 81% rename from patches/server/0048-MC-Technical-Survival-Mode.patch rename to patches/server/0046-MC-Technical-Survival-Mode.patch index 922d5110..0fba3005 100644 --- a/patches/server/0048-MC-Technical-Survival-Mode.patch +++ b/patches/server/0046-MC-Technical-Survival-Mode.patch @@ -6,7 +6,7 @@ Subject: [PATCH] MC Technical Survival Mode Will automatically overwrite some configuration after startup diff --git a/src/main/java/io/papermc/paper/adventure/ChatProcessor.java b/src/main/java/io/papermc/paper/adventure/ChatProcessor.java -index 19d973a0582c487617fafadd3df4857f8a1819a4..9cf1ab96f4f249f542b6698301237a989d4b6ff8 100644 +index 8fe9a0bf5a6c27d8a505afc2f51b3dccc905423b..979d70561c1a3b9b539f413ba689a89ab03e413f 100644 --- a/src/main/java/io/papermc/paper/adventure/ChatProcessor.java +++ b/src/main/java/io/papermc/paper/adventure/ChatProcessor.java @@ -331,14 +331,14 @@ public final class ChatProcessor { @@ -26,19 +26,6 @@ index 19d973a0582c487617fafadd3df4857f8a1819a4..9cf1ab96f4f249f542b6698301237a98 return player.teamDisplayName(); } return player.displayName(); -diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java -index 5b446e6ac151f99f64f0c442d0b40b5e251bc4c4..b133b977bc7d452b5032809f84f8ac2ff96ae5bb 100644 ---- a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java -+++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java -@@ -608,7 +608,7 @@ public final class ChunkHolderManager { - // Delay unload chunk patch originally by Aikar, updated to 1.20 by jpenilla - // these days, the patch is mostly useful to keep chunks ticking when players teleport - // so that their pets can teleport with them as well. -- final long delayTimeout = this.world.paperConfig().chunks.delayChunkUnloadsBy.ticks(); -+ final long delayTimeout = org.leavesmc.leaves.LeavesConfig.mcTechnicalMode ? 0 : this.world.paperConfig().chunks.delayChunkUnloadsBy.ticks(); // Leaves - mc technical survival mode - final TicketType toAdd; - final long timeout; - if (type == RegionizedPlayerChunkLoader.REGION_PLAYER_TICKET && delayTimeout > 0) { diff --git a/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java b/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java index 83a726bcf8b7dce73a361b0d79dbd63a0afc7a12..12cf1f7ba7d6c14b8b31d939b6f281bd2135656a 100644 --- a/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java @@ -52,10 +39,10 @@ index 83a726bcf8b7dce73a361b0d79dbd63a0afc7a12..12cf1f7ba7d6c14b8b31d939b6f281bd throw new RuntimeException("Could not reload paper configuration files", ex); } diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 63652c3011c48c461c1b5be1889847b2f065e34c..0f3a92155fa0b4ed9d7fbc87202fd04dc01a0890 100644 +index 1ff888bdc9c83a7e84393711ff50c96e78a1d55a..2d21dbb62c720beead96bf9176c7bd22661592ac 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -2695,7 +2695,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2452,7 +2452,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. public void onTickingEnd(Entity entity) { ServerLevel.this.entityTickList.remove(entity); // Paper start - Reset pearls when they stop being ticked @@ -65,10 +52,10 @@ index 63652c3011c48c461c1b5be1889847b2f065e34c..0f3a92155fa0b4ed9d7fbc87202fd04d pearl.ownerUUID = null; } diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index e74084548930664d4795d10a3f3448877128c88f..05ee5e0bcefc25b771eac20e53a7b7a3e0fed944 100644 +index a873d07351f8909f71805eec16a2e8dc22de3bb4..8a5fbcdbef5d8e14ca09f6a23a19860d92258a5c 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -1611,7 +1611,7 @@ public class ServerPlayer extends Player { +@@ -1633,7 +1633,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple @Override public boolean isInvulnerableTo(DamageSource damageSource) { @@ -78,10 +65,10 @@ index e74084548930664d4795d10a3f3448877128c88f..05ee5e0bcefc25b771eac20e53a7b7a3 @Override diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java -index d8e440e14b72dc48ae97244f1bed2c06abd997ab..c207bb1aa756a68dfbd397aa7ed40e9647fc8fec 100644 +index a33d89fe9ca9e343edab8bb1cc88c54130ddb4a7..5efedc1cadf31f2b944ca5401ce0c21131a4ab94 100644 --- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java +++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java -@@ -68,7 +68,7 @@ public class EndCrystal extends Entity { +@@ -70,7 +70,7 @@ public class EndCrystal extends Entity { // CraftBukkit end } // Paper start - Fix invulnerable end crystals @@ -91,23 +78,23 @@ index d8e440e14b72dc48ae97244f1bed2c06abd997ab..c207bb1aa756a68dfbd397aa7ed40e96 || ((ServerLevel) this.level()).getDragonFight() == null || ((ServerLevel) this.level()).getDragonFight().respawnStage == null 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 f1f352ec0e51f5db59254841a06c176c5a876fc9..eb9529b4bf20f828fd7e8abf6895baf0c7900dcc 100644 +index 42bd2d9a1528b6210e4dfb56233062fd97c9743b..8d494b549abb452bb554220060cc9c5beec5edf6 100644 --- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java +++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java -@@ -75,7 +75,7 @@ public class PrimedTnt extends Entity implements TraceableEntity { +@@ -95,7 +95,7 @@ public class PrimedTnt extends Entity implements TraceableEntity { @Override public void tick() { - if (this.level().spigotConfig.maxTntTicksPerTick > 0 && ++this.level().spigotConfig.currentPrimedTnt > this.level().spigotConfig.maxTntTicksPerTick) { return; } // Spigot + if (this.level().spigotConfig.maxTntTicksPerTick > 0 && ++this.level().spigotConfig.currentPrimedTnt > (org.leavesmc.leaves.LeavesConfig.mcTechnicalMode ? 2000 : this.level().spigotConfig.maxTntTicksPerTick)) { return; } // Spigot // Leaves - mc technical survival mode + this.handlePortal(); this.applyGravity(); this.move(MoverType.SELF, this.getDeltaMovement()); - // Paper start - Configurable TNT height nerf 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 74c596264d4da551437bd2a23e1c70022cfc73fc..71d2f2a98ede3ba2992ae3745d78b33c9d999650 100644 +index 5f7d152f41eb85f17bcded4bc8099b998e5a338b..cfc7edcf24646d1605d05c3782c7694bb9f7c435 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -@@ -120,7 +120,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { +@@ -126,7 +126,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { if (nbt.hasUUID("Owner")) { this.ownerUUID = nbt.getUUID("Owner"); this.cachedOwner = null; @@ -130,10 +117,10 @@ index 9c72271382fa0b6be5f38b45577fb1ae81ce80a3..a9fda9cb7e8266c21aba70d5b1890b30 entity.spawnReason == org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.CHUNK_GEN)) { continue; diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java -index 592b330f187fb5eca51d60911bbebbaeaf46ef87..b08b7ffbcfbc6a12d74cadf878fd069f7a1345cb 100644 +index d9421224778c72f8f9db3c9044bc28c2423bb09d..82e8b560ee24ad262df4ad073e66cd129ccb7bb8 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java -@@ -280,7 +280,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen +@@ -295,7 +295,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen origItemStack.setCount(originalItemCount); } } @@ -142,7 +129,7 @@ index 592b330f187fb5eca51d60911bbebbaeaf46ef87..b08b7ffbcfbc6a12d74cadf878fd069f hopper.setCooldown(level.spigotConfig.hopperTransfer); } return false; -@@ -321,7 +321,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen +@@ -336,7 +336,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen } origItemStack.setCount(originalItemCount); @@ -153,10 +140,10 @@ index 592b330f187fb5eca51d60911bbebbaeaf46ef87..b08b7ffbcfbc6a12d74cadf878fd069f diff --git a/src/main/java/org/leavesmc/leaves/util/McTechnicalModeHelper.java b/src/main/java/org/leavesmc/leaves/util/McTechnicalModeHelper.java new file mode 100644 -index 0000000000000000000000000000000000000000..b6374842caec8c919839aaf403342208fa4b8f95 +index 0000000000000000000000000000000000000000..2fdcb75a1fb85ab2fc6759050b2e7ffa601dcfa0 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/util/McTechnicalModeHelper.java -@@ -0,0 +1,26 @@ +@@ -0,0 +1,27 @@ +package org.leavesmc.leaves.util; + +import io.papermc.paper.configuration.GlobalConfiguration; @@ -176,6 +163,7 @@ index 0000000000000000000000000000000000000000..b6374842caec8c919839aaf403342208 + GlobalConfiguration.get().unsupportedSettings.allowPistonDuplication = true; + GlobalConfiguration.get().unsupportedSettings.allowHeadlessPistons = true; + GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits = true; ++ GlobalConfiguration.get().unsupportedSettings.allowUnsafeEndPortalTeleportation = true; + GlobalConfiguration.get().packetLimiter.allPackets = new GlobalConfiguration.PacketLimiter.PacketLimit(GlobalConfiguration.get().packetLimiter.allPackets.interval(), + 5000.0, GlobalConfiguration.get().packetLimiter.allPackets.action()); + GlobalConfiguration.get().packetLimiter.overrides = Map.of(); diff --git a/patches/server/0049-Return-nether-portal-fix.patch b/patches/server/0047-Return-nether-portal-fix.patch similarity index 59% rename from patches/server/0049-Return-nether-portal-fix.patch rename to patches/server/0047-Return-nether-portal-fix.patch index 310d653a..74f24842 100644 --- a/patches/server/0049-Return-nether-portal-fix.patch +++ b/patches/server/0047-Return-nether-portal-fix.patch @@ -6,18 +6,10 @@ Subject: [PATCH] Return nether portal fix This patch is powered by NetherPortalFix(https://github.com/TwelveIterationMods/NetherPortalFix) diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 05ee5e0bcefc25b771eac20e53a7b7a3e0fed944..622e19594039b7fd0841221664c27426b10768cd 100644 +index 8a5fbcdbef5d8e14ca09f6a23a19860d92258a5c..8d54ab1d3091817c38f3ae8691a3686ad1ac01dc 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -19,6 +19,7 @@ import java.util.UUID; - import java.util.stream.Collectors; - import javax.annotation.Nullable; - import net.minecraft.BlockUtil; -+import org.leavesmc.leaves.util.ReturnPortalManager; - import net.minecraft.ChatFormatting; - import net.minecraft.CrashReport; - import net.minecraft.CrashReportCategory; -@@ -1371,6 +1372,24 @@ public class ServerPlayer extends Player { +@@ -1436,6 +1436,21 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple PlayerChangedWorldEvent changeEvent = new PlayerChangedWorldEvent(this.getBukkitEntity(), worldserver1.getWorld()); this.level().getCraftServer().getPluginManager().callEvent(changeEvent); // CraftBukkit end @@ -28,66 +20,24 @@ index 05ee5e0bcefc25b771eac20e53a7b7a3e0fed944..622e19594039b7fd0841221664c27426 + final ResourceKey OVERWORLD = Level.OVERWORLD; + final ResourceKey THE_NETHER = Level.NETHER; + if (!((fromDim != OVERWORLD || toDim != THE_NETHER) && (fromDim != THE_NETHER || toDim != OVERWORLD))) { -+ BlockPos lastPos = this.lastPos; -+ if (lastPos != null) { -+ BlockUtil.FoundRectangle fromPortal = ReturnPortalManager.findPortalAt(this, fromDim, lastPos); -+ BlockPos toPos = this.blockPosition(); -+ if (fromPortal != null) { -+ ReturnPortalManager.storeReturnPortal(this, toDim, toPos, fromPortal); -+ } ++ BlockPos fromPortal = org.leavesmc.leaves.util.ReturnPortalManager.findPortalAt(this, fromDim, lastPos); ++ BlockPos toPos = this.blockPosition(); ++ if (fromPortal != null) { ++ org.leavesmc.leaves.util.ReturnPortalManager.storeReturnPortal(this, toDim, toPos, fromPortal); + } + } + } + // Leaves end - nether portal fix - } - // Paper start - Reset shield blocking on dimension change - if (this.isBlocking()) { -@@ -1423,6 +1442,30 @@ public class ServerPlayer extends Player { - protected Optional getExitPortal(ServerLevel worldserver, BlockPos blockposition, boolean flag, WorldBorder worldborder, int searchRadius, boolean canCreatePortal, int createRadius) { // CraftBukkit - Optional optional = super.getExitPortal(worldserver, blockposition, flag, worldborder, searchRadius, canCreatePortal, createRadius); // CraftBukkit - -+ // Leaves start - nether portal fix -+ if (org.leavesmc.leaves.LeavesConfig.netherPortalFix) { -+ BlockPos fromPos = blockPosition(); -+ final ResourceKey fromDim = level().dimension(); -+ final ResourceKey toDim = level().dimension(); -+ final ResourceKey OVERWORLD = Level.OVERWORLD; -+ final ResourceKey THE_NETHER = Level.NETHER; -+ boolean isTeleportBetweenNetherAndOverworld = (fromDim == OVERWORLD && toDim == THE_NETHER) -+ || (fromDim == THE_NETHER && toDim == OVERWORLD); -+ if (isInsidePortal && isTeleportBetweenNetherAndOverworld) { -+ ReturnPortalManager.ReturnPortal returnPortal = ReturnPortalManager.findReturnPortal(this, fromDim, fromPos); -+ if (returnPortal != null) { -+ MinecraftServer server = getServer(); -+ if (server != null) { -+ Level toLevel = server.getLevel(toDim); -+ if (toLevel != null) { -+ return Optional.of(returnPortal.rectangle()); -+ } -+ } -+ } -+ } -+ } -+ // Leaves end - nether portal fix -+ - if (optional.isPresent() || !canCreatePortal) { // CraftBukkit - return optional; - } else { + // Paper start - Reset shield blocking on dimension change + if (this.isBlocking()) { + this.stopUsingItem(); diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 00809b615f65b2f4985856673430d8ba68525765..a65aede101004f23f76ce08781ab0a94d4c9113e 100644 +index 4f3ae7cf3294583b738482964b78ebf2bd65cbbf..f16d0a072ca78ddf3eeb3a483a73869e47ed8ce1 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -26,6 +26,7 @@ import java.util.function.Predicate; - import javax.annotation.Nullable; - import net.minecraft.ChatFormatting; - import net.minecraft.FileUtil; -+import org.leavesmc.leaves.util.ReturnPortalManager; // Leaves - return portal fix - import net.minecraft.commands.CommandSourceStack; - import net.minecraft.core.BlockPos; - import net.minecraft.core.LayeredRegistryAccess; -@@ -1003,6 +1004,24 @@ public abstract class PlayerList { - if (fromWorld != location.getWorld()) { - PlayerChangedWorldEvent event = new PlayerChangedWorldEvent(entityplayer.getBukkitEntity(), fromWorld); +@@ -940,6 +940,24 @@ public abstract class PlayerList { + if (fromWorld != worldserver) { + PlayerChangedWorldEvent event = new PlayerChangedWorldEvent(entityplayer.getBukkitEntity(), fromWorld.getWorld()); this.server.server.getPluginManager().callEvent(event); + // Leaves start - nether portal fix + if (org.leavesmc.leaves.LeavesConfig.netherPortalFix) { @@ -111,10 +61,10 @@ index 00809b615f65b2f4985856673430d8ba68525765..a65aede101004f23f76ce08781ab0a94 // Save player file again if they were disconnected diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index ef3e4667d0d38e19a595f83bf93af7a9f1ab4c13..9c7fdcd820fa40aa3f0b8fcebc103cbfe7e27450 100644 +index 8af682d4aebbbd02816a5eb0a62d6ccfc8c1e6ff..0c3e98a478de9524354ad5e3a02f8268b88d7083 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -251,7 +251,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -260,7 +260,7 @@ public abstract class LivingEntity extends Entity implements Attackable { protected ItemStack useItem; public int useItemRemaining; protected int fallFlyTicks; @@ -123,15 +73,38 @@ index ef3e4667d0d38e19a595f83bf93af7a9f1ab4c13..9c7fdcd820fa40aa3f0b8fcebc103cbf private Optional lastClimbablePos; @Nullable private DamageSource lastDamageSource; +diff --git a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java +index ddab7de1d376e9e486e2f920174397ea8804aa29..73b6e6f24852370268bdcb0b06027daa119b5091 100644 +--- a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java ++++ b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java +@@ -172,7 +172,18 @@ public class NetherPortalBlock extends Block implements Portal { + + @Nullable + private DimensionTransition getExitPortal(ServerLevel worldserver, Entity entity, BlockPos blockposition, BlockPos blockposition1, boolean flag, WorldBorder worldborder, int searchRadius, boolean canCreatePortal, int createRadius) { +- Optional optional = worldserver.getPortalForcer().findClosestPortalPosition(blockposition1, worldborder, searchRadius); ++ // Leaves start - fix return portal ++ Optional optional = Optional.empty(); ++ if (org.leavesmc.leaves.LeavesConfig.netherPortalFix && entity instanceof net.minecraft.server.level.ServerPlayer player) { ++ org.leavesmc.leaves.util.ReturnPortalManager.ReturnPortal portal = org.leavesmc.leaves.util.ReturnPortalManager.findReturnPortal(player, entity.level().dimension(), entity.blockPosition()); ++ if (portal != null && worldserver.getBlockState(portal.pos()).is(Blocks.NETHER_PORTAL)) { ++ optional = Optional.of(portal.pos()); ++ } ++ } ++ if (optional.isEmpty()) { ++ optional = worldserver.getPortalForcer().findClosestPortalPosition(blockposition1, worldborder, searchRadius); ++ } ++ // Leaves end - fix return portal + BlockUtil.FoundRectangle blockutil_rectangle; + DimensionTransition.PostDimensionTransition dimensiontransition_a; + diff --git a/src/main/java/org/leavesmc/leaves/util/ReturnPortalManager.java b/src/main/java/org/leavesmc/leaves/util/ReturnPortalManager.java new file mode 100644 -index 0000000000000000000000000000000000000000..d7066d268e7a3b4b2c1b1ef28491078997989d4c +index 0000000000000000000000000000000000000000..67eb48e5b30d1dfa93aacbeb31f1b650b5ecb763 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/util/ReturnPortalManager.java -@@ -0,0 +1,105 @@ +@@ -0,0 +1,98 @@ +package org.leavesmc.leaves.util; + -+import net.minecraft.BlockUtil; +import net.minecraft.core.BlockPos; +import net.minecraft.core.registries.Registries; +import net.minecraft.nbt.CompoundTag; @@ -157,17 +130,15 @@ index 0000000000000000000000000000000000000000..d7066d268e7a3b4b2c1b1ef284910789 + private static final String RETURN_PORTAL_UID = "UID"; + private static final String FROM_DIM = "FromDim"; + private static final String FROM_POS = "FromPos"; -+ private static final String TO_MIN_CORNER = "ToMinCorner"; -+ private static final String TO_AXIS_1_SIZE = "ToAxis1Size"; -+ private static final String TO_AXIS_2_SIZE = "ToAxis2Size"; ++ private static final String TO_POS = "ToPos"; + -+ public static BlockUtil.FoundRectangle findPortalAt(Player player, ResourceKey dim, BlockPos pos) { ++ public static BlockPos findPortalAt(Player player, ResourceKey dim, BlockPos pos) { + MinecraftServer server = player.level().getServer(); + if (server != null) { + ServerLevel fromWorld = server.getLevel(dim); + if (fromWorld != null) { + PortalForcer portalForcer = fromWorld.getPortalForcer(); -+ return portalForcer.findPortalAround(pos, false, fromWorld.getWorldBorder()).orElse(null); ++ return portalForcer.findClosestPortalPosition(pos, false, fromWorld.getWorldBorder()).orElse(null); + } + } + @@ -186,15 +157,13 @@ index 0000000000000000000000000000000000000000..d7066d268e7a3b4b2c1b1ef284910789 + ListTag portalList = getPlayerPortalList(player); + for (Tag entry : portalList) { + CompoundTag portal = (CompoundTag) entry; -+ ResourceKey entryFromDim = ResourceKey.create(Registries.DIMENSION, new ResourceLocation(portal.getString(FROM_DIM))); ++ ResourceKey entryFromDim = ResourceKey.create(Registries.DIMENSION, ResourceLocation.parse(portal.getString(FROM_DIM))); + if (entryFromDim == fromDim) { + BlockPos portalTrigger = BlockPos.of(portal.getLong(FROM_POS)); + if (portalTrigger.distSqr(fromPos) <= MAX_PORTAL_DISTANCE_SQ) { -+ UUID uid = portal.hasUUID(RETURN_PORTAL_UID) ? portal.getUUID(RETURN_PORTAL_UID) : UUID.randomUUID(); -+ BlockPos minCorner = BlockPos.of(portal.getLong(TO_MIN_CORNER)); -+ int axis1Size = portal.getInt(TO_AXIS_1_SIZE); -+ int axis2Size = portal.getInt(TO_AXIS_2_SIZE); -+ return new ReturnPortal(uid, new BlockUtil.FoundRectangle(minCorner, axis1Size, axis2Size)); ++ final var uid = portal.hasUUID(RETURN_PORTAL_UID) ? portal.getUUID(RETURN_PORTAL_UID) : UUID.randomUUID(); ++ final var pos = BlockPos.of(portal.getLong(TO_POS)); ++ return new ReturnPortal(uid, pos); + } + } + } @@ -202,7 +171,7 @@ index 0000000000000000000000000000000000000000..d7066d268e7a3b4b2c1b1ef284910789 + return null; + } + -+ public static void storeReturnPortal(ServerPlayer player, ResourceKey fromDim, BlockPos fromPos, BlockUtil.FoundRectangle toPortal) { ++ public static void storeReturnPortal(ServerPlayer player, ResourceKey fromDim, BlockPos fromPos, BlockPos toPos) { + ListTag portalList = getPlayerPortalList(player); + ReturnPortal returnPortal = findReturnPortal(player, fromDim, fromPos); + if (returnPortal != null) { @@ -213,9 +182,7 @@ index 0000000000000000000000000000000000000000..d7066d268e7a3b4b2c1b1ef284910789 + portalCompound.putUUID(RETURN_PORTAL_UID, UUID.randomUUID()); + portalCompound.putString(FROM_DIM, String.valueOf(fromDim.location())); + portalCompound.putLong(FROM_POS, fromPos.asLong()); -+ portalCompound.putLong(TO_MIN_CORNER, toPortal.minCorner.asLong()); -+ portalCompound.putInt(TO_AXIS_1_SIZE, toPortal.axis1Size); -+ portalCompound.putInt(TO_AXIS_2_SIZE, toPortal.axis2Size); ++ portalCompound.putLong(TO_POS, toPos.asLong()); + portalList.add(portalCompound); + } + @@ -224,13 +191,13 @@ index 0000000000000000000000000000000000000000..d7066d268e7a3b4b2c1b1ef284910789 + ListTag portalList = getPlayerPortalList(player); + for (int i = 0; i < portalList.size(); i++) { + CompoundTag entry = (CompoundTag) portalList.get(i); -+ if (entry.hasUUID(RETURN_PORTAL_UID) && entry.getUUID(RETURN_PORTAL_UID).equals(portal.uid())) { ++ if (entry.hasUUID(RETURN_PORTAL_UID) && entry.getUUID(RETURN_PORTAL_UID).equals(portal.uid)) { + portalList.remove(i); + break; + } + } + } + -+ public record ReturnPortal(UUID uid, BlockUtil.FoundRectangle rectangle) { ++ public record ReturnPortal(UUID uid, BlockPos pos) { + } +} diff --git a/patches/server/0050-Appleskin-Protocol.patch b/patches/server/0048-Appleskin-Protocol.patch similarity index 100% rename from patches/server/0050-Appleskin-Protocol.patch rename to patches/server/0048-Appleskin-Protocol.patch diff --git a/patches/server/0051-Xaero-Map-Protocol.patch b/patches/server/0049-Xaero-Map-Protocol.patch similarity index 95% rename from patches/server/0051-Xaero-Map-Protocol.patch rename to patches/server/0049-Xaero-Map-Protocol.patch index fbf19f72..036916ad 100644 --- a/patches/server/0051-Xaero-Map-Protocol.patch +++ b/patches/server/0049-Xaero-Map-Protocol.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Xaero Map Protocol diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index a65aede101004f23f76ce08781ab0a94d4c9113e..c9e904ab960739c5b64f44ef92e3a02159149e66 100644 +index f16d0a072ca78ddf3eeb3a483a73869e47ed8ce1..5c47209505af8e9bea3f20effa4e176c32e5109a 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -1322,6 +1322,7 @@ public abstract class PlayerList { +@@ -1262,6 +1262,7 @@ public abstract class PlayerList { player.connection.send(new ClientboundInitializeBorderPacket(worldborder)); player.connection.send(new ClientboundSetTimePacket(world.getGameTime(), world.getDayTime(), world.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT))); player.connection.send(new ClientboundSetDefaultSpawnPositionPacket(world.getSharedSpawnPos(), world.getSharedSpawnAngle())); diff --git a/patches/server/0052-Leaves-Extra-Yggdrasil-Service.patch b/patches/server/0050-Leaves-Extra-Yggdrasil-Service.patch similarity index 98% rename from patches/server/0052-Leaves-Extra-Yggdrasil-Service.patch rename to patches/server/0050-Leaves-Extra-Yggdrasil-Service.patch index 09093bca..5e948980 100644 --- a/patches/server/0052-Leaves-Extra-Yggdrasil-Service.patch +++ b/patches/server/0050-Leaves-Extra-Yggdrasil-Service.patch @@ -44,10 +44,10 @@ index 244a19ecd0234fa1d7a6ecfea20751595688605d..7a1f7714616913cbb9d2dfc017567895 String s = (String) Optional.ofNullable((String) optionset.valueOf("world")).orElse(dedicatedserversettings.getProperties().levelName); LevelStorageSource convertable = LevelStorageSource.createDefault(file.toPath()); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index b22d0b0a2cb7e877875739abd87a3beac977c82a..b55cde303e18898ec791eb6d529ed4434ae70675 100644 +index 8806c9612e81f53241f5f16663aa781b8e03a98f..bbea145c85a6c96e44bb174c5a3d1f54705ff4c9 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -259,7 +259,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop type, Level world) { super(type, world); @@ -44,10 +44,10 @@ index 43b4ea96c5c4a6234e5b83d41db9b85c1fe27b8f..7e5294d856a757e55fe873d92d1de00a } 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 d3fa592892fc72c8fc8f23e8e477eb88902bba16..1bb762349c868e6a68b46366710dbbee60466eaf 100644 +index 38c2e27343d68d016621cf953222b915b56a0df2..a1d4d8b6fe488a7056c6613acbd35d3be71ae039 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -@@ -78,7 +78,13 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -79,7 +79,13 @@ public class ItemEntity extends Entity implements TraceableEntity { // Paper start - Don't use level random in entity constructors (to make them thread-safe) this(EntityType.ITEM, world); this.setPos(x, y, z); @@ -63,10 +63,10 @@ index d3fa592892fc72c8fc8f23e8e477eb88902bba16..1bb762349c868e6a68b46366710dbbee // Paper end - Don't use level random in entity constructors // Leaves start - stackable shulker boxes 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 eb9529b4bf20f828fd7e8abf6895baf0c7900dcc..248a94f366d9fb30112c65d151b19879c684b803 100644 +index 8d494b549abb452bb554220060cc9c5beec5edf6..ac05fe9a17f67a4cb12cdb9c381896d7bb0b3f6a 100644 --- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java +++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java -@@ -42,7 +42,7 @@ public class PrimedTnt extends Entity implements TraceableEntity { +@@ -62,7 +62,7 @@ public class PrimedTnt extends Entity implements TraceableEntity { public PrimedTnt(Level world, double x, double y, double z, @Nullable LivingEntity igniter) { this(EntityType.TNT, world); this.setPos(x, y, z); diff --git a/patches/server/0054-Fix-update-suppression-crash.patch b/patches/server/0052-Fix-update-suppression-crash.patch similarity index 90% rename from patches/server/0054-Fix-update-suppression-crash.patch rename to patches/server/0052-Fix-update-suppression-crash.patch index 0c21de2b..c9665bb5 100644 --- a/patches/server/0054-Fix-update-suppression-crash.patch +++ b/patches/server/0052-Fix-update-suppression-crash.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix update suppression crash diff --git a/src/main/java/net/minecraft/network/protocol/PacketUtils.java b/src/main/java/net/minecraft/network/protocol/PacketUtils.java -index d6daa27a8d7aca00b181e90d789f4249e8437d29..61b0e26a34bf94b10ce0ac78a662d5e97ad4cc9a 100644 +index f7197f1347251a37dd0f6d9ffa2f09bc3a4e1233..8909f4f65864935f86608b0e00149c57833395aa 100644 --- a/src/main/java/net/minecraft/network/protocol/PacketUtils.java +++ b/src/main/java/net/minecraft/network/protocol/PacketUtils.java -@@ -52,6 +52,10 @@ public class PacketUtils { +@@ -33,6 +33,10 @@ public class PacketUtils { if (listener.shouldHandleMessage(packet)) { try { packet.handle(listener); @@ -20,10 +20,10 @@ index d6daa27a8d7aca00b181e90d789f4249e8437d29..61b0e26a34bf94b10ce0ac78a662d5e9 if (exception instanceof ReportedException) { ReportedException reportedexception = (ReportedException) exception; diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index b55cde303e18898ec791eb6d529ed4434ae70675..aa7f001a3f75f7981e8aa27d24041d9a2e0493db 100644 +index bbea145c85a6c96e44bb174c5a3d1f54705ff4c9..7dc6b8096379360c9a32ae66c5bfde9d2612f3cb 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1756,7 +1756,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0.512F) { + // Leaves start - noFeatherFallingTrample + if (org.leavesmc.leaves.LeavesConfig.noFeatherFallingTrample) { -+ if (net.minecraft.world.item.enchantment.EnchantmentHelper.getEnchantmentLevel(Enchantments.FEATHER_FALLING, (LivingEntity) entity) > 0) { ++ if (net.minecraft.world.item.enchantment.EnchantmentHelper.getEnchantmentLevel(world.registryAccess().registryOrThrow(net.minecraft.core.registries.Registries.ENCHANTMENT).getHolder(net.minecraft.world.item.enchantment.Enchantments.FEATHER_FALLING).get(), (LivingEntity) entity) > 0) { + return; + } + } diff --git a/patches/server/0057-Placeholder-for-Syncmatica-Protocol.patch b/patches/server/0057-Placeholder-for-Syncmatica-Protocol.patch deleted file mode 100644 index fec7798c..00000000 --- a/patches/server/0057-Placeholder-for-Syncmatica-Protocol.patch +++ /dev/null @@ -1,15 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: MC_XiaoHei -Date: Wed, 8 May 2024 22:26:38 +0800 -Subject: [PATCH] Placeholder for Syncmatica-Protocol - - -diff --git a/.gitignore b/.gitignore -index 3811c0d849a3eb028ed1a6b7a2d4747f7f570448..1ad93453221244f880855b510e888e759275b640 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -46,3 +46,4 @@ dependency-reduced-pom.xml - # vs code - /.vscode - /.factorypath -+ diff --git a/patches/unapplied/server/0056-Syncmatica-Protocol.patch b/patches/server/0057-Syncmatica-Protocol.patch similarity index 96% rename from patches/unapplied/server/0056-Syncmatica-Protocol.patch rename to patches/server/0057-Syncmatica-Protocol.patch index 20b4ba69..f8583ff6 100644 --- a/patches/unapplied/server/0056-Syncmatica-Protocol.patch +++ b/patches/server/0057-Syncmatica-Protocol.patch @@ -6,18 +6,18 @@ Subject: [PATCH] Syncmatica Protocol This patch is Powered by Syncmatica(https://github.com/End-Tech/syncmatica) diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 98b0cee150e9e27e6bafc7c2afc9d5008ca8ef82..2d388dcafc02a04348a1c07d970b7a8bb8fdf014 100644 +index bef88d547aefa9c5b701aa91ffc58114309a7db7..51a1be78de7a794d13b64db6958977e2e9d20553 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -312,6 +312,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -314,6 +314,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl Objects.requireNonNull(server); this.signedMessageDecoder = SignedMessageChain.Decoder.unsigned(uuid, server::enforceSecureProfile); this.chatMessageChain = new FutureChain(server.chatExecutor); // CraftBukkit - async chat + this.exchangeTarget = new org.leavesmc.leaves.protocol.syncmatica.exchange.ExchangeTarget(this); // Leaves - Syncmatica Protocol } - // CraftBukkit start - add fields -@@ -330,6 +331,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + // CraftBukkit start - add fields and methods +@@ -332,6 +333,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl private boolean justTeleported = false; // CraftBukkit end @@ -28,10 +28,10 @@ index 98b0cee150e9e27e6bafc7c2afc9d5008ca8ef82..2d388dcafc02a04348a1c07d970b7a8b if (this.ackBlockChangesUpTo > -1) { diff --git a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/CommunicationManager.java b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/CommunicationManager.java new file mode 100644 -index 0000000000000000000000000000000000000000..4c2aa74795b0883f280eaa721a83ea6891ffdab2 +index 0000000000000000000000000000000000000000..8c0fd40a89681ef71d9dd2ad63d858e1aad82ceb --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/CommunicationManager.java -@@ -0,0 +1,391 @@ +@@ -0,0 +1,397 @@ +package org.leavesmc.leaves.protocol.syncmatica; + +import com.mojang.authlib.GameProfile; @@ -39,13 +39,12 @@ index 0000000000000000000000000000000000000000..4c2aa74795b0883f280eaa721a83ea68 +import net.minecraft.core.BlockPos; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.chat.Component; -+import net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerPlayer; -+import net.minecraft.server.network.ServerGamePacketListenerImpl; +import net.minecraft.world.level.block.Mirror; +import net.minecraft.world.level.block.Rotation; +import org.jetbrains.annotations.NotNull; ++import org.leavesmc.leaves.LeavesConfig; +import org.leavesmc.leaves.protocol.core.LeavesProtocol; +import org.leavesmc.leaves.protocol.core.LeavesProtocolManager; +import org.leavesmc.leaves.protocol.core.ProtocolHandler; @@ -102,6 +101,9 @@ index 0000000000000000000000000000000000000000..4c2aa74795b0883f280eaa721a83ea68 + + @ProtocolHandler.PlayerJoin + public static void onPlayerJoin(ServerPlayer player) { ++ if (!LeavesConfig.syncmaticaProtocol) { ++ return; ++ } + final ExchangeTarget newPlayer = player.connection.exchangeTarget; + final VersionHandshakeServer hi = new VersionHandshakeServer(newPlayer); + playerMap.put(newPlayer, player); @@ -112,6 +114,9 @@ index 0000000000000000000000000000000000000000..4c2aa74795b0883f280eaa721a83ea68 + + @ProtocolHandler.PlayerLeave + public static void onPlayerLeave(ServerPlayer player) { ++ if (!LeavesConfig.syncmaticaProtocol) { ++ return; ++ } + final ExchangeTarget oldPlayer = player.connection.exchangeTarget; + final Collection potentialMessageTarget = oldPlayer.getExchanges(); + if (potentialMessageTarget != null) { @@ -124,8 +129,11 @@ index 0000000000000000000000000000000000000000..4c2aa74795b0883f280eaa721a83ea68 + playerMap.remove(oldPlayer); + } + -+ @ProtocolHandler.PayloadReceiver(payload = LeavesProtocolManager.LeavesPayload.class, ignoreId = true, payloadId = "") ++ @ProtocolHandler.PayloadReceiver(payload = LeavesProtocolManager.LeavesPayload.class, ignoreId = true) + public static void onPacketGet(ServerPlayer player, LeavesProtocolManager.LeavesPayload payload) { ++ if (!LeavesConfig.syncmaticaProtocol) { ++ return; ++ } + onPacket(player.connection.exchangeTarget, payload.id(), payload.data()); + } + @@ -266,9 +274,7 @@ index 0000000000000000000000000000000000000000..4c2aa74795b0883f280eaa721a83ea68 + final FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer()); + buf.writeUUID(placement.getId()); + client.sendPacket(PacketType.REMOVE_SYNCMATIC.identifier, buf); -+ final FriendlyByteBuf buf2 = new FriendlyByteBuf(Unpooled.buffer()); -+ putMetaData(placement, buf2, client); -+ client.sendPacket(PacketType.REGISTER_METADATA.identifier, buf2); ++ sendMetaData(placement, client); + } + } + } @@ -425,7 +431,7 @@ index 0000000000000000000000000000000000000000..4c2aa74795b0883f280eaa721a83ea68 +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/Feature.java b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/Feature.java new file mode 100644 -index 0000000000000000000000000000000000000000..1125755d7d78a118d1fe407e9ca554a89f4d9a9a +index 0000000000000000000000000000000000000000..7cb3465b88411c46e79ce661ac7a4bddcf5b33e2 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/Feature.java @@ -0,0 +1,23 @@ @@ -454,7 +460,7 @@ index 0000000000000000000000000000000000000000..1125755d7d78a118d1fe407e9ca554a8 +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/FeatureSet.java b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/FeatureSet.java new file mode 100644 -index 0000000000000000000000000000000000000000..3d851913e2016fcd384b6a8b1e91753cb8ea91ef +index 0000000000000000000000000000000000000000..ddd0f498feb2ad62134ae15a3ddb21527f2f24bf --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/FeatureSet.java @@ -0,0 +1,67 @@ @@ -527,7 +533,7 @@ index 0000000000000000000000000000000000000000..3d851913e2016fcd384b6a8b1e91753c +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/FileStorage.java b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/FileStorage.java new file mode 100644 -index 0000000000000000000000000000000000000000..5dccbce7287fe436de9436f35a7d1ffcfc5d74ab +index 0000000000000000000000000000000000000000..9139394e87e23190fbfdd82295314b0d50f1acca --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/FileStorage.java @@ -0,0 +1,80 @@ @@ -613,7 +619,7 @@ index 0000000000000000000000000000000000000000..5dccbce7287fe436de9436f35a7d1ffc +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/LocalLitematicState.java b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/LocalLitematicState.java new file mode 100644 -index 0000000000000000000000000000000000000000..82ffc8cbd1b488c8723693b685a91c2a4149fb47 +index 0000000000000000000000000000000000000000..299c57397371b368461a532d2eab695cf4f01fff --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/LocalLitematicState.java @@ -0,0 +1,24 @@ @@ -643,7 +649,7 @@ index 0000000000000000000000000000000000000000..82ffc8cbd1b488c8723693b685a91c2a +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/MessageType.java b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/MessageType.java new file mode 100644 -index 0000000000000000000000000000000000000000..04d785846be3670b741d90634f5f691899127835 +index 0000000000000000000000000000000000000000..b56ca12c650edd13dd7ff52e13c9d3aa465c32ec --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/MessageType.java @@ -0,0 +1,8 @@ @@ -657,7 +663,7 @@ index 0000000000000000000000000000000000000000..04d785846be3670b741d90634f5f6918 +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/PacketType.java b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/PacketType.java new file mode 100644 -index 0000000000000000000000000000000000000000..8f3227d36da0a3055cc25e538437de58fd5730e3 +index 0000000000000000000000000000000000000000..36c87c5cc586ad247e9aed26518c890f884010ae --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/PacketType.java @@ -0,0 +1,30 @@ @@ -693,7 +699,7 @@ index 0000000000000000000000000000000000000000..8f3227d36da0a3055cc25e538437de58 +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/PlayerIdentifier.java b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/PlayerIdentifier.java new file mode 100644 -index 0000000000000000000000000000000000000000..f9ba2a41ab1e0d50bf85fd024b6d29e65b3a5cf7 +index 0000000000000000000000000000000000000000..b5891b0b49173acfb1a94051b98cb03b7a5ec9cd --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/PlayerIdentifier.java @@ -0,0 +1,37 @@ @@ -736,7 +742,7 @@ index 0000000000000000000000000000000000000000..f9ba2a41ab1e0d50bf85fd024b6d29e6 +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/PlayerIdentifierProvider.java b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/PlayerIdentifierProvider.java new file mode 100644 -index 0000000000000000000000000000000000000000..f4fc3bac20359ecf17a25d7b8e8f34cfebcf4b24 +index 0000000000000000000000000000000000000000..df2254edf89e17eec73a692577e77c613cd4c8e4 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/PlayerIdentifierProvider.java @@ -0,0 +1,46 @@ @@ -788,7 +794,7 @@ index 0000000000000000000000000000000000000000..f4fc3bac20359ecf17a25d7b8e8f34cf +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/ServerPlacement.java b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/ServerPlacement.java new file mode 100644 -index 0000000000000000000000000000000000000000..8c5bc7d6244d6ccd9a561030fff44ccdecc1ed5c +index 0000000000000000000000000000000000000000..70759c9d3c01959169230503954f1f48c5392075 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/ServerPlacement.java @@ -0,0 +1,166 @@ @@ -960,7 +966,7 @@ index 0000000000000000000000000000000000000000..8c5bc7d6244d6ccd9a561030fff44ccd +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/ServerPosition.java b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/ServerPosition.java new file mode 100644 -index 0000000000000000000000000000000000000000..3f6ee21ce72943e11f8d924321eb286652c5c533 +index 0000000000000000000000000000000000000000..9775c6c42a253aaaf1ac7576dba3764c8593d7fe --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/ServerPosition.java @@ -0,0 +1,51 @@ @@ -1017,7 +1023,7 @@ index 0000000000000000000000000000000000000000..3f6ee21ce72943e11f8d924321eb2866 +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/SubRegionData.java b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/SubRegionData.java new file mode 100644 -index 0000000000000000000000000000000000000000..6903c26742f5e10aa75f52b7abd5273e7116600b +index 0000000000000000000000000000000000000000..22fdf92dd686a2dc573eb60cd4d9a08ba7faec5a --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/SubRegionData.java @@ -0,0 +1,90 @@ @@ -1113,7 +1119,7 @@ index 0000000000000000000000000000000000000000..6903c26742f5e10aa75f52b7abd5273e +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/SubRegionPlacementModification.java b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/SubRegionPlacementModification.java new file mode 100644 -index 0000000000000000000000000000000000000000..0d67b562ed06f8de990c2f3d545e2839837f853d +index 0000000000000000000000000000000000000000..a52e299be26d1ec13507dac8d68f7e5736117762 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/SubRegionPlacementModification.java @@ -0,0 +1,65 @@ @@ -1184,7 +1190,7 @@ index 0000000000000000000000000000000000000000..0d67b562ed06f8de990c2f3d545e2839 +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/SyncmaticManager.java b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/SyncmaticManager.java new file mode 100644 -index 0000000000000000000000000000000000000000..9fbeef1ef528504276895faed4dba41ee0789e77 +index 0000000000000000000000000000000000000000..27a056b306daa91400946a30e68ce01d47089ac8 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/SyncmaticManager.java @@ -0,0 +1,108 @@ @@ -1298,7 +1304,7 @@ index 0000000000000000000000000000000000000000..9fbeef1ef528504276895faed4dba41e +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/SyncmaticaProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/SyncmaticaProtocol.java new file mode 100644 -index 0000000000000000000000000000000000000000..2f44c35e199205ac2a9430c68a6ada3ef92d5d38 +index 0000000000000000000000000000000000000000..d91c913a283cef1f152c23653d48a85c42f9655b --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/SyncmaticaProtocol.java @@ -0,0 +1,123 @@ @@ -1427,7 +1433,7 @@ index 0000000000000000000000000000000000000000..2f44c35e199205ac2a9430c68a6ada3e +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/exchange/AbstractExchange.java b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/exchange/AbstractExchange.java new file mode 100644 -index 0000000000000000000000000000000000000000..625974f9ce0791b476336abafa6aa1af2f2ffbac +index 0000000000000000000000000000000000000000..b06ffeacf699b78f34253a26018ccdf723d5d0ce --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/exchange/AbstractExchange.java @@ -0,0 +1,66 @@ @@ -1499,7 +1505,7 @@ index 0000000000000000000000000000000000000000..625974f9ce0791b476336abafa6aa1af +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/exchange/DownloadExchange.java b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/exchange/DownloadExchange.java new file mode 100644 -index 0000000000000000000000000000000000000000..7303769570656f36a3a76215e22020b1292007fb +index 0000000000000000000000000000000000000000..b0463dc8dc6f204cd48b73056dc4eb321e7ba602 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/exchange/DownloadExchange.java @@ -0,0 +1,125 @@ @@ -1630,7 +1636,7 @@ index 0000000000000000000000000000000000000000..7303769570656f36a3a76215e22020b1 +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/exchange/Exchange.java b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/exchange/Exchange.java new file mode 100644 -index 0000000000000000000000000000000000000000..26482e63b7c24c80bdc111cea51b8d7b8052d64e +index 0000000000000000000000000000000000000000..0f45ef7f4abcd7cff627e5a3df2a9fca8d6e7585 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/exchange/Exchange.java @@ -0,0 +1,20 @@ @@ -1656,7 +1662,7 @@ index 0000000000000000000000000000000000000000..26482e63b7c24c80bdc111cea51b8d7b +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/exchange/ExchangeTarget.java b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/exchange/ExchangeTarget.java new file mode 100644 -index 0000000000000000000000000000000000000000..706680a3d7fae22f94cb86b8da2e306cfcf4cb1b +index 0000000000000000000000000000000000000000..1ce637d91f12f8fdd54fce38534861836b6a93ca --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/exchange/ExchangeTarget.java @@ -0,0 +1,40 @@ @@ -1702,7 +1708,7 @@ index 0000000000000000000000000000000000000000..706680a3d7fae22f94cb86b8da2e306c +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/exchange/FeatureExchange.java b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/exchange/FeatureExchange.java new file mode 100644 -index 0000000000000000000000000000000000000000..f92739dbfa00de0e078834818dab79e34fc3d245 +index 0000000000000000000000000000000000000000..45fc01915b18a47bcdf7a7ce55161266e5cd1221 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/exchange/FeatureExchange.java @@ -0,0 +1,48 @@ @@ -1756,7 +1762,7 @@ index 0000000000000000000000000000000000000000..f92739dbfa00de0e078834818dab79e3 +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/exchange/ModifyExchangeServer.java b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/exchange/ModifyExchangeServer.java new file mode 100644 -index 0000000000000000000000000000000000000000..d87602fa78a8e599b71556f3dd103ff71ee83ae0 +index 0000000000000000000000000000000000000000..c691201f0af82c4ac19df27639b32637b7f46caf --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/exchange/ModifyExchangeServer.java @@ -0,0 +1,81 @@ @@ -1843,7 +1849,7 @@ index 0000000000000000000000000000000000000000..d87602fa78a8e599b71556f3dd103ff7 +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/exchange/UploadExchange.java b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/exchange/UploadExchange.java new file mode 100644 -index 0000000000000000000000000000000000000000..9a1b37c69a3946b8f042a1118bf7dcf6ff0967ae +index 0000000000000000000000000000000000000000..065a39942603f7b884cca40d8d7b4b47b46d7985 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/exchange/UploadExchange.java @@ -0,0 +1,101 @@ @@ -1950,7 +1956,7 @@ index 0000000000000000000000000000000000000000..9a1b37c69a3946b8f042a1118bf7dcf6 +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/exchange/VersionHandshakeServer.java b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/exchange/VersionHandshakeServer.java new file mode 100644 -index 0000000000000000000000000000000000000000..448d5e8423347c0154a146906617e32e18fbc30f +index 0000000000000000000000000000000000000000..9614fce87e2522690aac0af4c04d9fbcb72167af --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/exchange/VersionHandshakeServer.java @@ -0,0 +1,65 @@ diff --git a/patches/server/0060-Shared-villager-discounts.patch b/patches/server/0058-Shared-villager-discounts.patch similarity index 100% rename from patches/server/0060-Shared-villager-discounts.patch rename to patches/server/0058-Shared-villager-discounts.patch diff --git a/patches/server/0061-Redstone-wire-dont-connect-if-on-trapdoor.patch b/patches/server/0059-Redstone-wire-dont-connect-if-on-trapdoor.patch similarity index 100% rename from patches/server/0061-Redstone-wire-dont-connect-if-on-trapdoor.patch rename to patches/server/0059-Redstone-wire-dont-connect-if-on-trapdoor.patch diff --git a/patches/server/0062-Disable-check-out-of-order-command.patch b/patches/server/0060-Disable-check-out-of-order-command.patch similarity index 100% rename from patches/server/0062-Disable-check-out-of-order-command.patch rename to patches/server/0060-Disable-check-out-of-order-command.patch diff --git a/patches/server/0063-Despawn-enderman-with-block.patch b/patches/server/0061-Despawn-enderman-with-block.patch similarity index 85% rename from patches/server/0063-Despawn-enderman-with-block.patch rename to patches/server/0061-Despawn-enderman-with-block.patch index 3757b00f..2f87917a 100644 --- a/patches/server/0063-Despawn-enderman-with-block.patch +++ b/patches/server/0061-Despawn-enderman-with-block.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Despawn enderman with block diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java -index 215176eb7152c11c4934c8576ac8c9fa9b2d0833..675a504ac428aaa130dc607bb8e759e156523f33 100644 +index 17a71bb3b65cc1030b70c931b1dc998d06713231..2a26fb795ca8d71f02d7d991dd28c34118266f02 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java +++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java -@@ -469,7 +469,7 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -471,7 +471,7 @@ public class EnderMan extends Monster implements NeutralMob { @Override public boolean requiresCustomPersistence() { diff --git a/patches/server/0064-Leaves-carpet-support.patch b/patches/server/0062-Leaves-carpet-support.patch similarity index 100% rename from patches/server/0064-Leaves-carpet-support.patch rename to patches/server/0062-Leaves-carpet-support.patch diff --git a/patches/server/0065-Creative-fly-no-clip.patch b/patches/server/0063-Creative-fly-no-clip.patch similarity index 81% rename from patches/server/0065-Creative-fly-no-clip.patch rename to patches/server/0063-Creative-fly-no-clip.patch index 882f6153..5e971dfe 100644 --- a/patches/server/0065-Creative-fly-no-clip.patch +++ b/patches/server/0063-Creative-fly-no-clip.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Creative fly no clip 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 25595bef64199c4ddbe69c65fd149eec33e778ad..7f733ed26ada22c64897c4df84af6eb680d9a02f 100644 +index 54ba25632c2a9e1c93a5b3a0b92e5280864c49d6..eff9284b853f6771b6d44c851643621897e18a17 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java -@@ -250,8 +250,8 @@ public abstract class Player extends LivingEntity { +@@ -251,8 +251,8 @@ public abstract class Player extends LivingEntity { @Override public void tick() { @@ -19,7 +19,7 @@ index 25595bef64199c4ddbe69c65fd149eec33e778ad..7f733ed26ada22c64897c4df84af6eb6 this.setOnGround(false); } -@@ -430,7 +430,7 @@ public abstract class Player extends LivingEntity { +@@ -435,7 +435,7 @@ public abstract class Player extends LivingEntity { Pose entitypose1; @@ -28,7 +28,7 @@ index 25595bef64199c4ddbe69c65fd149eec33e778ad..7f733ed26ada22c64897c4df84af6eb6 if (this.canPlayerFitWithinBlocksAndEntitiesWhen(Pose.CROUCHING)) { entitypose1 = Pose.CROUCHING; } else { -@@ -577,7 +577,7 @@ public abstract class Player extends LivingEntity { +@@ -581,7 +581,7 @@ public abstract class Player extends LivingEntity { } this.bob += (f - this.bob) * 0.4F; @@ -37,7 +37,7 @@ index 25595bef64199c4ddbe69c65fd149eec33e778ad..7f733ed26ada22c64897c4df84af6eb6 AABB axisalignedbb; if (this.isPassenger() && !this.getVehicle().isRemoved()) { -@@ -2099,6 +2099,21 @@ public abstract class Player extends LivingEntity { +@@ -2110,6 +2110,21 @@ public abstract class Player extends LivingEntity { @Override public abstract boolean isSpectator(); @@ -60,10 +60,10 @@ index 25595bef64199c4ddbe69c65fd149eec33e778ad..7f733ed26ada22c64897c4df84af6eb6 public boolean canBeHitByProjectile() { return !this.isSpectator() && super.canBeHitByProjectile(); diff --git a/src/main/java/net/minecraft/world/item/BlockItem.java b/src/main/java/net/minecraft/world/item/BlockItem.java -index c21a65d9637739f1040dd27b096101a7a7adc0df..6dec706a2cadedfad0dff5e7784fe9bec65aad6c 100644 +index 2759a9eeef85b323b7e1ea78090f4f9d637c938a..4b044d76e803027bfc2df7dab9878eca01e62f5a 100644 --- a/src/main/java/net/minecraft/world/item/BlockItem.java +++ b/src/main/java/net/minecraft/world/item/BlockItem.java -@@ -205,7 +205,7 @@ public class BlockItem extends Item { +@@ -223,7 +223,7 @@ public class BlockItem extends Item { CollisionContext voxelshapecollision = entityhuman == null ? CollisionContext.empty() : CollisionContext.of(entityhuman); // CraftBukkit start - store default return Level world = context.getLevel(); // Paper - Cancel hit for vanished players @@ -86,7 +86,7 @@ index 0b761f3ae15ad4a3b8152f497a60403212109534..fdb2bb8a5e6c5d69692804adb086a2d4 BlockCanBuildEvent event = new BlockCanBuildEvent(CraftBlock.at(world, blockposition), player, CraftBlockData.fromData(iblockdata1), defaultReturn, org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(context.getHand())); // Paper - Expose hand in BlockCanBuildEvent diff --git a/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java -index 0d68db20f5fbe5e834f12c1e8fd429099a44e4b6..193673d2b70035dac69422aaae185315a901effc 100644 +index 5b62860cd64b5e6dc02dadb4651824ac04b00024..6c23de5ebcfaf378b1ab97689e50add07d37ff03 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java @@ -163,7 +163,7 @@ public class ShulkerBoxBlockEntity extends RandomizableContainerBlockEntity impl @@ -98,27 +98,6 @@ index 0d68db20f5fbe5e834f12c1e8fd429099a44e4b6..193673d2b70035dac69422aaae185315 entity.move(MoverType.SHULKER_BOX, new Vec3((axisalignedbb.getXsize() + 0.01D) * (double) enumdirection.getStepX(), (axisalignedbb.getYsize() + 0.01D) * (double) enumdirection.getStepY(), (axisalignedbb.getZsize() + 0.01D) * (double) enumdirection.getStepZ())); } } -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 93bd70c1dc2ba8b893a6087730071c81fb1132f4..4af071ff2d0a29ad9315e1076436f70f848c89b8 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 -@@ -19,6 +19,7 @@ import net.minecraft.util.Mth; - import net.minecraft.util.RandomSource; - import net.minecraft.world.entity.Entity; - import net.minecraft.world.entity.EntitySelector; -+import net.minecraft.world.entity.player.Player; - import net.minecraft.world.entity.projectile.ThrownEnderpearl; - import net.minecraft.world.level.BlockGetter; - import net.minecraft.world.level.ChunkPos; -@@ -117,7 +118,7 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity { - } - - public static boolean canEntityTeleport(Entity entity) { -- return EntitySelector.NO_SPECTATORS.test(entity) && !entity.getRootVehicle().isOnPortalCooldown(); -+ return EntitySelector.NO_SPECTATORS.test(entity) && !entity.getRootVehicle().isOnPortalCooldown() && !(entity instanceof Player player && player.isCreativeFlyOrSpectator()); // Leaves - creative no clip - } - - public boolean isSpawning() { 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 b35f476e26a020cf75e53a5eb488717d996a6935..73651a8ae9341807ec96300914d49329fb8a4e90 100644 --- a/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java diff --git a/patches/server/0066-Optimized-dragon-respawn.patch b/patches/server/0064-Optimized-dragon-respawn.patch similarity index 90% rename from patches/server/0066-Optimized-dragon-respawn.patch rename to patches/server/0064-Optimized-dragon-respawn.patch index d3a434e2..27499377 100644 --- a/patches/server/0066-Optimized-dragon-respawn.patch +++ b/patches/server/0064-Optimized-dragon-respawn.patch @@ -18,18 +18,10 @@ index ee99519ebd46b1db3e76e7eb86e5cc121c867dc4..63f6f1328c4e39cc1f35480166ae5e22 for (int j = 0; j < this.height; j++) { for (int k = 0; k < this.depth; k++) { diff --git a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java -index 18a1b4325cac81b040596071dab99ef9bf6f3142..cc08fbadde12ad9f2193811f75628d4bd8d59a0f 100644 +index 18a1b4325cac81b040596071dab99ef9bf6f3142..478cba8137d153fe922ca7f402d306d8c12bcb31 100644 --- a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java +++ b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java -@@ -45,6 +45,7 @@ import net.minecraft.world.entity.boss.enderdragon.phases.EnderDragonPhase; - import net.minecraft.world.level.ChunkPos; - import net.minecraft.world.level.block.Blocks; - import net.minecraft.world.level.block.entity.BlockEntity; -+import net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity; - import net.minecraft.world.level.block.entity.TheEndPortalBlockEntity; - import net.minecraft.world.level.block.state.pattern.BlockInWorld; - import net.minecraft.world.level.block.state.pattern.BlockPattern; -@@ -289,8 +290,67 @@ public class EndDragonFight { +@@ -289,8 +289,67 @@ public class EndDragonFight { return false; } @@ -46,7 +38,7 @@ index 18a1b4325cac81b040596071dab99ef9bf6f3142..cc08fbadde12ad9f2193811f75628d4b + for (j = cachePortalChunkIteratorZ; j <= 8; ++j) { + LevelChunk worldChunk = this.level.getChunk(i, j); + for (BlockEntity blockEntity : worldChunk.getBlockEntities().values()) { -+ if (blockEntity instanceof TheEndGatewayBlockEntity) { ++ if (blockEntity instanceof net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity) { + continue; + } + if (blockEntity instanceof TheEndPortalBlockEntity) { @@ -97,7 +89,7 @@ index 18a1b4325cac81b040596071dab99ef9bf6f3142..cc08fbadde12ad9f2193811f75628d4b ChunkPos chunkcoordintpair = new ChunkPos(this.origin); int i; -@@ -619,6 +679,11 @@ public class EndDragonFight { +@@ -619,6 +678,11 @@ public class EndDragonFight { } public boolean respawnDragon(List list) { // CraftBukkit - return boolean diff --git a/patches/server/0068-Shave-snow-layers.patch b/patches/server/0065-Shave-snow-layers.patch similarity index 51% rename from patches/server/0068-Shave-snow-layers.patch rename to patches/server/0065-Shave-snow-layers.patch index 1c4bcf6d..08abe683 100644 --- a/patches/server/0068-Shave-snow-layers.patch +++ b/patches/server/0065-Shave-snow-layers.patch @@ -5,52 +5,28 @@ Subject: [PATCH] Shave snow layers diff --git a/src/main/java/net/minecraft/world/item/ShovelItem.java b/src/main/java/net/minecraft/world/item/ShovelItem.java -index 24f6a158e4759aac3be8da4cf5e0d40bd295355b..8c15f74cc5f3c4dfc499e6bdab75f10f66ea36b1 100644 +index 24f6a158e4759aac3be8da4cf5e0d40bd295355b..97c3a9281ef10c88947febf152a005b0cd05cc64 100644 --- a/src/main/java/net/minecraft/world/item/ShovelItem.java +++ b/src/main/java/net/minecraft/world/item/ShovelItem.java -@@ -2,20 +2,25 @@ package net.minecraft.world.item; - - import com.google.common.collect.Maps; - import com.google.common.collect.ImmutableMap.Builder; -+ - import java.util.Map; -+ - import net.minecraft.core.BlockPos; - import net.minecraft.core.Direction; - import net.minecraft.sounds.SoundEvents; - import net.minecraft.sounds.SoundSource; - import net.minecraft.tags.BlockTags; - import net.minecraft.world.InteractionResult; -+import net.minecraft.world.entity.EquipmentSlot; - import net.minecraft.world.entity.LivingEntity; - import net.minecraft.world.entity.player.Player; - import net.minecraft.world.item.context.UseOnContext; -+import net.minecraft.world.item.enchantment.EnchantmentHelper; - import net.minecraft.world.level.Level; - import net.minecraft.world.level.block.Block; - import net.minecraft.world.level.block.Blocks; - import net.minecraft.world.level.block.CampfireBlock; -+import net.minecraft.world.level.block.SnowLayerBlock; - import net.minecraft.world.level.block.state.BlockState; - import net.minecraft.world.level.gameevent.GameEvent; - -@@ -44,6 +49,24 @@ public class ShovelItem extends DiggerItem { +@@ -44,6 +44,26 @@ public class ShovelItem extends DiggerItem { return InteractionResult.PASS; } else { Player player = context.getPlayer(); + // Leaves start - shaveSnowLayers + if (org.leavesmc.leaves.LeavesConfig.shaveSnowLayers && blockState.is(Blocks.SNOW)) { -+ int layers = blockState.getValue(SnowLayerBlock.LAYERS); -+ level.setBlock(blockPos, layers > 1 ? blockState.setValue(SnowLayerBlock.LAYERS, layers - 1) : Blocks.AIR.defaultBlockState(), 11); -+ Block.popResource(level, blockPos, new ItemStack(EnchantmentHelper.hasSilkTouch(context.getItemInHand()) ? Items.SNOW : Items.SNOWBALL)); ++ int layers = blockState.getValue(net.minecraft.world.level.block.SnowLayerBlock.LAYERS); ++ ItemStack tool = context.getItemInHand(); ++ boolean hasSilkTouch = net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(level.registryAccess().registryOrThrow(net.minecraft.core.registries.Registries.ENCHANTMENT).getHolder(net.minecraft.world.item.enchantment.Enchantments.SILK_TOUCH).get(), tool) > 0; ++ BlockState shavedBlockState = layers > 1 ? blockState.setValue(net.minecraft.world.level.block.SnowLayerBlock.LAYERS, layers - 1) : Blocks.AIR.defaultBlockState(); ++ ++ level.setBlock(blockPos, shavedBlockState, Block.UPDATE_ALL_IMMEDIATE); ++ level.gameEvent(GameEvent.BLOCK_CHANGE, blockPos, GameEvent.Context.of(player, shavedBlockState)); ++ ++ Block.popResource(level, blockPos, new ItemStack(hasSilkTouch ? Items.SNOW : Items.SNOWBALL)); + level.playSound(player, blockPos, SoundEvents.SNOW_BREAK, SoundSource.BLOCKS, 1.0F, 1.0F); + + if (player != null) { -+ context.getItemInHand().hurtAndBreak(1, player.getRandom(), player, () -> -+ player.broadcastBreakEvent(switch (context.getHand()) { -+ case MAIN_HAND -> EquipmentSlot.MAINHAND; -+ case OFF_HAND -> EquipmentSlot.OFFHAND; -+ })); ++ tool.hurtAndBreak(1, player, LivingEntity.getSlotForHand(context.getHand())); + } + + return InteractionResult.SUCCESS; @@ -59,7 +35,7 @@ index 24f6a158e4759aac3be8da4cf5e0d40bd295355b..8c15f74cc5f3c4dfc499e6bdab75f10f BlockState blockState2 = FLATTENABLES.get(blockState.getBlock()); BlockState blockState3 = null; Runnable afterAction = null; // Paper -@@ -52,11 +75,11 @@ public class ShovelItem extends DiggerItem { +@@ -52,11 +72,11 @@ public class ShovelItem extends DiggerItem { blockState3 = blockState2; } else if (blockState.getBlock() instanceof CampfireBlock && blockState.getValue(CampfireBlock.LIT)) { afterAction = () -> { // Paper diff --git a/patches/server/0069-Spawn-ignore-lc.patch b/patches/server/0066-Spawn-ignore-lc.patch similarity index 74% rename from patches/server/0069-Spawn-ignore-lc.patch rename to patches/server/0066-Spawn-ignore-lc.patch index b28d4d52..85bc3e72 100644 --- a/patches/server/0069-Spawn-ignore-lc.patch +++ b/patches/server/0066-Spawn-ignore-lc.patch @@ -5,18 +5,10 @@ Subject: [PATCH] Spawn ignore lc diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index a9fda9cb7e8266c21aba70d5b1890b30900a5b00..083a8a7dd99e447904dbac161dd3a1de663d6011 100644 +index a9fda9cb7e8266c21aba70d5b1890b30900a5b00..a8f792c1ac5740219f014bec5a3875be92b43be9 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -@@ -38,6 +38,7 @@ import net.minecraft.world.level.block.state.BlockState; - import net.minecraft.world.level.chunk.ChunkAccess; - import net.minecraft.world.level.chunk.ChunkGenerator; - import net.minecraft.world.level.chunk.LevelChunk; -+import net.minecraft.world.level.chunk.LevelChunkSection; - import net.minecraft.world.level.levelgen.Heightmap; - import net.minecraft.world.level.levelgen.structure.BuiltinStructures; - import net.minecraft.world.level.levelgen.structure.Structure; -@@ -199,6 +200,19 @@ public final class NaturalSpawner { +@@ -199,6 +199,19 @@ public final class NaturalSpawner { } public static int spawnCategoryForChunk(MobCategory group, ServerLevel world, LevelChunk chunk, NaturalSpawner.SpawnPredicate checker, NaturalSpawner.AfterSpawnCallback runner, int maxSpawns, Consumer trackEntity) { // Paper end - Optional per player mob spawns @@ -24,7 +16,7 @@ index a9fda9cb7e8266c21aba70d5b1890b30900a5b00..083a8a7dd99e447904dbac161dd3a1de + if (org.leavesmc.leaves.LeavesConfig.ignoreLC) { + int spawnN = 0; + for (int i = chunk.getMinBuildHeight(); i < chunk.getMaxBuildHeight(); i += 16) { -+ LevelChunkSection section = chunk.getSections()[chunk.getSectionIndex(i)]; ++ net.minecraft.world.level.chunk.LevelChunkSection section = chunk.getSections()[chunk.getSectionIndex(i)]; + if (section != null && !section.hasOnlyAir()) { + BlockPos pos = getRandomPosInChunk(world, chunk).offset(0, i, 0); + spawnN += spawnCategoryForPosition(group, world, chunk, pos, checker, runner, maxSpawns, trackEntity); @@ -36,7 +28,7 @@ index a9fda9cb7e8266c21aba70d5b1890b30900a5b00..083a8a7dd99e447904dbac161dd3a1de BlockPos blockposition = NaturalSpawner.getRandomPosWithin(world, chunk); if (blockposition.getY() >= world.getMinBuildHeight() + 1) { -@@ -207,6 +221,16 @@ public final class NaturalSpawner { +@@ -207,6 +220,16 @@ public final class NaturalSpawner { return 0; // Paper - Optional per player mob spawns } diff --git a/patches/server/0070-Elytra-aeronautics-no-chunk-load.patch b/patches/server/0067-Elytra-aeronautics-no-chunk-load.patch similarity index 85% rename from patches/server/0070-Elytra-aeronautics-no-chunk-load.patch rename to patches/server/0067-Elytra-aeronautics-no-chunk-load.patch index 3da7b994..f2c4140d 100644 --- a/patches/server/0070-Elytra-aeronautics-no-chunk-load.patch +++ b/patches/server/0067-Elytra-aeronautics-no-chunk-load.patch @@ -5,20 +5,19 @@ Subject: [PATCH] Elytra aeronautics no chunk load diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index da65f980f2145ea03341911ce75f7e61b358c9d7..7dcdc9b40c594234d87bef3e75a68ddaa58506a3 100644 +index 0bcd9f3faba32c4dc1d115a9306594b9334657cb..bab8dbff18bd8435ed86336de067df0de3ca9145 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -166,7 +166,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - } - // Paper end - use distance map to optimise tracker +@@ -169,14 +169,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + // Paper start - distance maps + private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>(); - void addPlayerToDistanceMaps(ServerPlayer player) { + public void addPlayerToDistanceMaps(ServerPlayer player) { // Leaves - package -> public int chunkX = io.papermc.paper.util.MCUtil.getChunkCoordinate(player.getX()); int chunkZ = io.papermc.paper.util.MCUtil.getChunkCoordinate(player.getZ()); // Note: players need to be explicitly added to distance maps before they can be updated -@@ -182,7 +182,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - // Paper end - use distance map to optimise entity tracker + this.nearbyPlayers.addPlayer(player); } - void removePlayerFromDistanceMaps(ServerPlayer player) { @@ -26,7 +25,7 @@ index da65f980f2145ea03341911ce75f7e61b358c9d7..7dcdc9b40c594234d87bef3e75a68dda int chunkX = io.papermc.paper.util.MCUtil.getChunkCoordinate(player.getX()); int chunkZ = io.papermc.paper.util.MCUtil.getChunkCoordinate(player.getZ()); // Note: players need to be explicitly added to distance maps before they can be updated -@@ -994,7 +994,8 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -782,7 +782,8 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } private boolean skipPlayer(ServerPlayer player) { @@ -36,19 +35,19 @@ index da65f980f2145ea03341911ce75f7e61b358c9d7..7dcdc9b40c594234d87bef3e75a68dda } void updatePlayerStatus(ServerPlayer player, boolean added) { -@@ -1031,6 +1032,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -820,6 +821,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public void move(ServerPlayer player) { + if (player.elytraAeronauticsNoChunk) return; // Leaves - no chunk - // Paper - delay this logic for the entity tracker tick, no need to duplicate it + ObjectIterator objectiterator = this.entityMap.values().iterator(); - SectionPos sectionposition = player.getLastSectionPos(); + while (objectiterator.hasNext()) { diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index d833c9da7b5132485a450bb752bd988ee91e4cf1..f605051b11eb23e41c1f0339917a6731c1e6b2f3 100644 +index 51a1be78de7a794d13b64db6958977e2e9d20553..31ad4e4aaf321ab3c3909145e36a67744d906c65 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -556,7 +556,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -559,7 +559,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl speed *= 2f; // TODO: Get the speed of the vehicle instead of the player // Paper start - Prevent moving into unloaded chunks @@ -58,10 +57,10 @@ index d833c9da7b5132485a450bb752bd988ee91e4cf1..f605051b11eb23e41c1f0339917a6731 !worldserver.areChunksLoadedForMove(entity.getBoundingBox().expandTowards(new Vec3(toX, toY, toZ).subtract(entity.position()))) )) { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index bff5bdd0ea231c889fd8bab4f68b5bcbdcda2190..a13843368d161fd252a95a620463d7040fd98308 100644 +index 0bf2a2a5ccb558632c70d77b852167c3c90e5f49..f9a90bddb0bec8b67da3f9d05a0f3056048c8272 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -1156,7 +1156,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1081,7 +1081,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return; } } @@ -76,7 +75,7 @@ index bff5bdd0ea231c889fd8bab4f68b5bcbdcda2190..a13843368d161fd252a95a620463d704 this.level().getProfiler().push("move"); if (this.stuckSpeedMultiplier.lengthSqr() > 1.0E-7D) { movement = movement.multiply(this.stuckSpeedMultiplier); -@@ -2104,6 +2110,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1993,6 +1999,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.yo = y; this.zo = d4; this.setPos(d3, y, d4); @@ -85,14 +84,13 @@ index bff5bdd0ea231c889fd8bab4f68b5bcbdcda2190..a13843368d161fd252a95a620463d704 } 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 7f733ed26ada22c64897c4df84af6eb680d9a02f..24bed620cb7cdb5104d3bdf8f87eb69122e8092c 100644 +index eff9284b853f6771b6d44c851643621897e18a17..191aeecdf355e94758ed1f8bb7ca1a91a492eab5 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java -@@ -195,6 +195,8 @@ public abstract class Player extends LivingEntity { - public boolean ignoreFallDamageFromCurrentImpulse; +@@ -196,6 +196,7 @@ public abstract class Player extends LivingEntity { + private int currentImpulseContextResetGraceTime; public boolean affectsSpawning = true; // Paper - Affects Spawning API public net.kyori.adventure.util.TriState flyingFallDamage = net.kyori.adventure.util.TriState.NOT_SET; // Paper - flying fall damage -+ // Paper end + public boolean elytraAeronauticsNoChunk = false; // Leaves - Elytra aeronautics // CraftBukkit start diff --git a/patches/server/0067-Enchantment-mending-compatibility-infinity.patch b/patches/server/0067-Enchantment-mending-compatibility-infinity.patch deleted file mode 100644 index 1eb5059f..00000000 --- a/patches/server/0067-Enchantment-mending-compatibility-infinity.patch +++ /dev/null @@ -1,18 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: violetc <58360096+s-yh-china@users.noreply.github.com> -Date: Tue, 27 Jun 2023 13:48:36 +0800 -Subject: [PATCH] Enchantment mending compatibility infinity - - -diff --git a/src/main/java/net/minecraft/world/item/enchantment/ArrowInfiniteEnchantment.java b/src/main/java/net/minecraft/world/item/enchantment/ArrowInfiniteEnchantment.java -index 81cc05c929d612898609965d82454b89cd18f9f5..96bfa0098a903aca604308877c53336e6269b059 100644 ---- a/src/main/java/net/minecraft/world/item/enchantment/ArrowInfiniteEnchantment.java -+++ b/src/main/java/net/minecraft/world/item/enchantment/ArrowInfiniteEnchantment.java -@@ -7,6 +7,6 @@ public class ArrowInfiniteEnchantment extends Enchantment { - - @Override - public boolean checkCompatibility(Enchantment other) { -- return !(other instanceof MendingEnchantment) && super.checkCompatibility(other); -+ return (org.leavesmc.leaves.LeavesConfig.mendingCompatibilityInfinity || !(other instanceof MendingEnchantment)) && super.checkCompatibility(other); // Leaves - mendingCompatibilityInfinity - } - } diff --git a/patches/server/0071-Cache-ignite-odds.patch b/patches/server/0068-Cache-ignite-odds.patch similarity index 100% rename from patches/server/0071-Cache-ignite-odds.patch rename to patches/server/0068-Cache-ignite-odds.patch diff --git a/patches/server/0069-Lava-riptide.patch b/patches/server/0069-Lava-riptide.patch new file mode 100644 index 00000000..284a3923 --- /dev/null +++ b/patches/server/0069-Lava-riptide.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: violetc <58360096+s-yh-china@users.noreply.github.com> +Date: Fri, 7 Jul 2023 16:53:32 +0800 +Subject: [PATCH] Lava riptide + + +diff --git a/src/main/java/net/minecraft/world/item/TridentItem.java b/src/main/java/net/minecraft/world/item/TridentItem.java +index f1b2d388a1a40a1d909a2e726f32d6c15e1eb0eb..da3887eec5b1e2b8151d71ddb759d083993d54bb 100644 +--- a/src/main/java/net/minecraft/world/item/TridentItem.java ++++ b/src/main/java/net/minecraft/world/item/TridentItem.java +@@ -72,7 +72,7 @@ public class TridentItem extends Item implements ProjectileItem { + if (j >= 10) { + float f = EnchantmentHelper.getTridentSpinAttackStrength(stack, entityhuman); + +- if (f <= 0.0F || entityhuman.isInWaterOrRain()) { ++ if (f <= 0.0F || entityhuman.isInWaterOrRain() || (org.leavesmc.leaves.LeavesConfig.lavaRiptide && entityhuman.isInLava())) { // Leaves - lava riptide + if (!TridentItem.isTooDamagedToUse(stack)) { + Holder holder = (Holder) EnchantmentHelper.pickHighestLevel(stack, EnchantmentEffectComponents.TRIDENT_SOUND).orElse(SoundEvents.TRIDENT_THROW); + +@@ -150,7 +150,7 @@ public class TridentItem extends Item implements ProjectileItem { + + if (TridentItem.isTooDamagedToUse(itemstack)) { + return InteractionResultHolder.fail(itemstack); +- } else if (EnchantmentHelper.getTridentSpinAttackStrength(itemstack, user) > 0.0F && !user.isInWaterOrRain()) { ++ } else if (EnchantmentHelper.getTridentSpinAttackStrength(itemstack, user) > 0.0F && !user.isInWaterOrRain() && !(org.leavesmc.leaves.LeavesConfig.lavaRiptide && user.isInLava())) { // Leaves - lava riptide + return InteractionResultHolder.fail(itemstack); + } else { + user.startUsingItem(hand); diff --git a/patches/server/0073-No-block-update-command.patch b/patches/server/0070-No-block-update-command.patch similarity index 92% rename from patches/server/0073-No-block-update-command.patch rename to patches/server/0070-No-block-update-command.patch index ac4a737a..2398ba3a 100644 --- a/patches/server/0073-No-block-update-command.patch +++ b/patches/server/0070-No-block-update-command.patch @@ -5,10 +5,10 @@ Subject: [PATCH] No block update command diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 0f3a92155fa0b4ed9d7fbc87202fd04dc01a0890..3bb53128f6919712f0a88ec11c1bce25bf5b8b84 100644 +index 2d21dbb62c720beead96bf9176c7bd22661592ac..0f1fef8f6e3b89f61b98358c6c8d84af4af2fa5e 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -2464,6 +2464,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2243,6 +2243,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. @Override public void blockUpdated(BlockPos pos, Block block) { @@ -17,10 +17,10 @@ index 0f3a92155fa0b4ed9d7fbc87202fd04dc01a0890..3bb53128f6919712f0a88ec11c1bce25 // CraftBukkit start if (this.populating) { diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index 35e0aac4dc32227c48dc3a0f3a15c02a700fc402..0522368deaa13f13fad4e2f00346f3910a064618 100644 +index fa3dbb93a049962fe10cb0391d437acdb45c82af..d9217d2a2be6bfa8eb099effac8587af715b975c 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -506,7 +506,7 @@ public final class ItemStack implements DataComponentHolder { +@@ -527,7 +527,7 @@ public final class ItemStack implements DataComponentHolder { net.minecraft.world.level.block.state.BlockState block = world.getBlockState(newblockposition); if (!(block.getBlock() instanceof BaseEntityBlock)) { // Containers get placed automatically @@ -30,10 +30,10 @@ index 35e0aac4dc32227c48dc3a0f3a15c02a700fc402..0522368deaa13f13fad4e2f00346f391 world.notifyAndUpdatePhysics(newblockposition, null, oldBlock, block, world.getBlockState(newblockposition), updateFlag, 512); // send null chunk as chunk.k() returns false by this point diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -index f94ca04e55e02f2d8fcb98ad1868319d55da7468..11fadf105e59b4cddc8c4fa4f02b1ce69abfc7c7 100644 +index fa577dec9721c25f3c4897be939af7c2ba2e1c84..94015519f379fab094b4b24c4b3a1900c1194e17 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -481,7 +481,7 @@ public class LevelChunk extends ChunkAccess { +@@ -370,7 +370,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p } else { // CraftBukkit - Don't place while processing the BlockPlaceEvent, unless it's a BlockContainer. Prevents blocks such as TNT from activating when cancelled. if (!this.level.isClientSide && doPlace && (!this.level.captureBlockStates || block instanceof net.minecraft.world.level.block.BaseEntityBlock)) { @@ -43,10 +43,10 @@ index f94ca04e55e02f2d8fcb98ad1868319d55da7468..11fadf105e59b4cddc8c4fa4f02b1ce6 if (iblockdata.hasBlockEntity()) { diff --git a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java -index d5352883ee51dfc646352ae7e2b76af7efd0441e..57f952323639c1ce409032b8023a7911b4fee9b2 100644 +index 1687ab4965433459219bb5d8aaf5ec8e5baeb605..36d49bd355b9c061b1663bcac7c9f590173f34df 100644 --- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java +++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java -@@ -518,6 +518,7 @@ public abstract class FlowingFluid extends Fluid { +@@ -506,6 +506,7 @@ public abstract class FlowingFluid extends Fluid { @Override public void tick(Level world, BlockPos pos, FluidState state) { diff --git a/patches/server/0074-Raider-die-skip-self-raid-check.patch b/patches/server/0071-Raider-die-skip-self-raid-check.patch similarity index 83% rename from patches/server/0074-Raider-die-skip-self-raid-check.patch rename to patches/server/0071-Raider-die-skip-self-raid-check.patch index 11b9c1b1..4d1e047f 100644 --- a/patches/server/0074-Raider-die-skip-self-raid-check.patch +++ b/patches/server/0071-Raider-die-skip-self-raid-check.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Raider die skip self raid check diff --git a/src/main/java/net/minecraft/world/entity/raid/Raider.java b/src/main/java/net/minecraft/world/entity/raid/Raider.java -index 98e558338b5d9fb03869d2cc21b3e90eb45b95f6..d9e3c0ff607cc55dbe0df4519279889bcb30e1b2 100644 +index bbf21ea433f9e3963aac0ede597ed8d3c8e50ed8..6e68f8fa8280a106b1a262d86aa130e89d4f5cce 100644 --- a/src/main/java/net/minecraft/world/entity/raid/Raider.java +++ b/src/main/java/net/minecraft/world/entity/raid/Raider.java -@@ -128,7 +128,7 @@ public abstract class Raider extends PatrollingMonster { +@@ -121,7 +121,7 @@ public abstract class Raider extends PatrollingMonster { Raid raid = this.getCurrentRaid(); if (raid != null) { diff --git a/patches/server/0075-Container-open-passthrough.patch b/patches/server/0072-Container-open-passthrough.patch similarity index 94% rename from patches/server/0075-Container-open-passthrough.patch rename to patches/server/0072-Container-open-passthrough.patch index 3a0043e3..7bb8125a 100644 --- a/patches/server/0075-Container-open-passthrough.patch +++ b/patches/server/0072-Container-open-passthrough.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Container open passthrough diff --git a/src/main/java/net/minecraft/world/level/block/SignBlock.java b/src/main/java/net/minecraft/world/level/block/SignBlock.java -index f7bae8060d993176799ff3ff4653d760a137faba..01dcc910e9151fb28828f99afa0adc21f5a700d7 100644 +index 73874cd18a5b335e895ea0b2fefbd521209afe08..0f560a03676571e1ebf3811a7caa4faba0e7ef95 100644 --- a/src/main/java/net/minecraft/world/level/block/SignBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SignBlock.java -@@ -113,6 +113,18 @@ public abstract class SignBlock extends BaseEntityBlock implements SimpleWaterlo +@@ -110,6 +110,18 @@ public abstract class SignBlock extends BaseEntityBlock implements SimpleWaterlo } else { return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; } @@ -27,7 +27,7 @@ index f7bae8060d993176799ff3ff4653d760a137faba..01dcc910e9151fb28828f99afa0adc21 } else { return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; } -@@ -141,6 +153,25 @@ public abstract class SignBlock extends BaseEntityBlock implements SimpleWaterlo +@@ -138,6 +150,25 @@ public abstract class SignBlock extends BaseEntityBlock implements SimpleWaterlo return InteractionResult.SUCCESS; } else if (flag1) { return InteractionResult.SUCCESS; diff --git a/patches/server/0072-Lava-riptide.patch b/patches/server/0072-Lava-riptide.patch deleted file mode 100644 index b91aec9e..00000000 --- a/patches/server/0072-Lava-riptide.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: violetc <58360096+s-yh-china@users.noreply.github.com> -Date: Fri, 7 Jul 2023 16:53:32 +0800 -Subject: [PATCH] Lava riptide - - -diff --git a/src/main/java/net/minecraft/world/item/TridentItem.java b/src/main/java/net/minecraft/world/item/TridentItem.java -index 47de500fddb0716d142f8f5876a82a95afaa06fa..b01e85c9665fef476acdde74f08beaba168561db 100644 ---- a/src/main/java/net/minecraft/world/item/TridentItem.java -+++ b/src/main/java/net/minecraft/world/item/TridentItem.java -@@ -70,7 +70,7 @@ public class TridentItem extends Item implements ProjectileItem { - if (j >= 10) { - int k = EnchantmentHelper.getRiptide(stack); - -- if (k <= 0 || entityhuman.isInWaterOrRain()) { -+ if (k <= 0 || entityhuman.isInWaterOrRain() || (org.leavesmc.leaves.LeavesConfig.lavaRiptide && entityhuman.isInLava())) { // Leaves - lava riptide - if (!world.isClientSide) { - // itemstack.hurtAndBreak(1, entityhuman, EntityLiving.getSlotForHand(entityliving.getUsedItemHand())); // CraftBukkit - moved down - if (k == 0) { -@@ -155,7 +155,7 @@ public class TridentItem extends Item implements ProjectileItem { - - if (itemstack.getDamageValue() >= itemstack.getMaxDamage() - 1) { - return InteractionResultHolder.fail(itemstack); -- } else if (EnchantmentHelper.getRiptide(itemstack) > 0 && !user.isInWaterOrRain()) { -+ } else if (EnchantmentHelper.getRiptide(itemstack) > 0 && !user.isInWaterOrRain() && !(org.leavesmc.leaves.LeavesConfig.lavaRiptide && user.isInLava())) { // Leaves - lava riptide - return InteractionResultHolder.fail(itemstack); - } else { - user.startUsingItem(hand); diff --git a/patches/server/0078-SIMD-support.patch b/patches/server/0073-SIMD-support.patch similarity index 90% rename from patches/server/0078-SIMD-support.patch rename to patches/server/0073-SIMD-support.patch index cddbc9e3..99dcdf4a 100644 --- a/patches/server/0078-SIMD-support.patch +++ b/patches/server/0073-SIMD-support.patch @@ -5,7 +5,7 @@ Subject: [PATCH] SIMD support diff --git a/build.gradle.kts b/build.gradle.kts -index fe1f6f1a97ab35c44f596596d16765b8b81753a9..28baa9a192a6fd83563b57a411e9bc905ba6b7e1 100644 +index 268193499b9f1fae0c01963e8004a3e7422f77ca..b35bc56ca35e7ada015e011ab4c3136b4803e48c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -73,6 +73,7 @@ tasks.withType { diff --git a/patches/server/0079-Dont-respond-ping-before-start-fully.patch b/patches/server/0074-Dont-respond-ping-before-start-fully.patch similarity index 89% rename from patches/server/0079-Dont-respond-ping-before-start-fully.patch rename to patches/server/0074-Dont-respond-ping-before-start-fully.patch index 18103663..bbb76a19 100644 --- a/patches/server/0079-Dont-respond-ping-before-start-fully.patch +++ b/patches/server/0074-Dont-respond-ping-before-start-fully.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Dont respond ping before start fully This patch is Powered by Gale(https://github.com/GaleMC/Gale) diff --git a/src/main/java/net/minecraft/server/network/ServerStatusPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerStatusPacketListenerImpl.java -index 6f1c9fa89e718cbc01a8d72de34154f49c5f46db..093d0cea2fa37c96086afdb026bf988a7ea3c9ed 100644 +index 385457c7151f7e636e1ea2e38ef983f4f532b9b5..b35b0fcd5405c64d15f907ca4d3b33ae204a8d1e 100644 --- a/src/main/java/net/minecraft/server/network/ServerStatusPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerStatusPacketListenerImpl.java -@@ -153,6 +153,12 @@ public class ServerStatusPacketListenerImpl implements ServerStatusPacketListene +@@ -154,6 +154,12 @@ public class ServerStatusPacketListenerImpl implements ServerStatusPacketListene this.connection.send(new ClientboundStatusResponsePacket(ping)); // CraftBukkit end */ diff --git a/patches/server/0080-Faster-chunk-serialization.patch b/patches/server/0075-Faster-chunk-serialization.patch similarity index 99% rename from patches/server/0080-Faster-chunk-serialization.patch rename to patches/server/0075-Faster-chunk-serialization.patch index 865cf981..1dbdc491 100644 --- a/patches/server/0080-Faster-chunk-serialization.patch +++ b/patches/server/0075-Faster-chunk-serialization.patch @@ -6,18 +6,18 @@ Subject: [PATCH] Faster chunk serialization This patch is Powered by Gale(https://github.com/GaleMC/Gale) diff --git a/src/main/java/net/minecraft/util/BitStorage.java b/src/main/java/net/minecraft/util/BitStorage.java -index 8bafd5fd7499ba4a04bf706cfd1e156073716e21..7082022412dc75e3d84c74acd19bb8452e477d0c 100644 +index 8bafd5fd7499ba4a04bf706cfd1e156073716e21..91554e0f496a2df9cfe3131fbe3d9706e0a73a38 100644 --- a/src/main/java/net/minecraft/util/BitStorage.java +++ b/src/main/java/net/minecraft/util/BitStorage.java -@@ -1,6 +1,7 @@ +@@ -1,5 +1,7 @@ package net.minecraft.util; - import java.util.function.IntConsumer; +import net.minecraft.world.level.chunk.Palette; ++ + import java.util.function.IntConsumer; public interface BitStorage { - int getAndSet(int index, int value); -@@ -31,4 +32,6 @@ public interface BitStorage { +@@ -31,4 +33,6 @@ public interface BitStorage { } // Paper end diff --git a/patches/server/0082-Cache-world-generator-sea-level.patch b/patches/server/0076-Cache-world-generator-sea-level.patch similarity index 90% rename from patches/server/0082-Cache-world-generator-sea-level.patch rename to patches/server/0076-Cache-world-generator-sea-level.patch index 3fae06ad..96ae4546 100644 --- a/patches/server/0082-Cache-world-generator-sea-level.patch +++ b/patches/server/0076-Cache-world-generator-sea-level.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Cache world generator sea level This patch is Powered by Gale(https://github.com/GaleMC/Gale) diff --git a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java -index 8ce870a5341a61fbbaf42021ef7f7f615a6a3e09..d217bccc5af50360e3b3b265953fba91aaf204db 100644 +index 68be0d51aa64b5d917fb53dbbbdf8966d4f4abd8..4adac668fb3d02ed43a89da446a71503d0380c73 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java +++ b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java -@@ -62,12 +62,17 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { +@@ -61,12 +61,17 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { private static final BlockState AIR = Blocks.AIR.defaultBlockState(); public final Holder settings; private final Supplier globalFluidPicker; @@ -28,7 +28,7 @@ index 8ce870a5341a61fbbaf42021ef7f7f615a6a3e09..d217bccc5af50360e3b3b265953fba91 }); } -@@ -394,7 +399,13 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { +@@ -409,7 +414,13 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { @Override public int getSeaLevel() { diff --git a/patches/server/0076-Placeholder-for-Bladeren-Protocol.patch b/patches/server/0076-Placeholder-for-Bladeren-Protocol.patch deleted file mode 100644 index 1526b462..00000000 --- a/patches/server/0076-Placeholder-for-Bladeren-Protocol.patch +++ /dev/null @@ -1,15 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: MC_XiaoHei -Date: Wed, 8 May 2024 22:28:35 +0800 -Subject: [PATCH] Placeholder for Bladeren-Protocol - - -diff --git a/.gitignore b/.gitignore -index 1ad93453221244f880855b510e888e759275b640..3811c0d849a3eb028ed1a6b7a2d4747f7f570448 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -46,4 +46,3 @@ dependency-reduced-pom.xml - # vs code - /.vscode - /.factorypath -- diff --git a/patches/unapplied/server/0075-Bladeren-Protocol.patch b/patches/server/0077-Bladeren-Protocol.patch similarity index 91% rename from patches/unapplied/server/0075-Bladeren-Protocol.patch rename to patches/server/0077-Bladeren-Protocol.patch index c4f810b5..fd8af844 100644 --- a/patches/unapplied/server/0075-Bladeren-Protocol.patch +++ b/patches/server/0077-Bladeren-Protocol.patch @@ -6,20 +6,21 @@ Subject: [PATCH] Bladeren Protocol diff --git a/src/main/java/org/leavesmc/leaves/protocol/bladeren/BladerenProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/bladeren/BladerenProtocol.java new file mode 100644 -index 0000000000000000000000000000000000000000..a91011c7a2c56646053bb9d158ff0c265c658c00 +index 0000000000000000000000000000000000000000..4d9285d69724e8600fd7a3f9a6c31ecd579de6ad --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/bladeren/BladerenProtocol.java -@@ -0,0 +1,145 @@ +@@ -0,0 +1,150 @@ +package org.leavesmc.leaves.protocol.bladeren; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.FriendlyByteBuf; -+import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerPlayer; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.LeavesConfig; ++import org.leavesmc.leaves.LeavesLogger; ++import org.leavesmc.leaves.protocol.core.LeavesCustomPayload; +import org.leavesmc.leaves.protocol.core.LeavesProtocol; +import org.leavesmc.leaves.protocol.core.ProtocolHandler; +import org.leavesmc.leaves.protocol.core.ProtocolUtils; @@ -50,6 +51,8 @@ index 0000000000000000000000000000000000000000..a91011c7a2c56646053bb9d158ff0c26 + String clientVersion = payload.version; + CompoundTag tag = payload.nbt; + ++ LeavesLogger.LOGGER.info("Player " + player.getScoreboardName() + " joined with bladeren " + clientVersion); ++ + if (tag != null) { + CompoundTag featureNbt = tag.getCompound("Features"); + for (String name : featureNbt.getAllKeys()) { @@ -117,8 +120,9 @@ index 0000000000000000000000000000000000000000..a91011c7a2c56646053bb9d158ff0c26 + } + } + -+ public record BladerenFeatureModifyPayload(String name, CompoundTag nbt) implements CustomPacketPayload { ++ public record BladerenFeatureModifyPayload(String name, CompoundTag nbt) implements LeavesCustomPayload { + ++ @New + public BladerenFeatureModifyPayload(ResourceLocation location, FriendlyByteBuf buf) { + this(buf.readUtf(), buf.readNbt()); + } @@ -136,8 +140,9 @@ index 0000000000000000000000000000000000000000..a91011c7a2c56646053bb9d158ff0c26 + } + } + -+ public record BladerenHelloPayload(String version, CompoundTag nbt) implements CustomPacketPayload { ++ public record BladerenHelloPayload(String version, CompoundTag nbt) implements LeavesCustomPayload { + ++ @New + public BladerenHelloPayload(ResourceLocation location, @NotNull FriendlyByteBuf buf) { + this(buf.readUtf(64), buf.readNbt()); + } diff --git a/patches/server/0077-Placeholder-for-Bladeren-mspt-sync-protocol.patch b/patches/server/0077-Placeholder-for-Bladeren-mspt-sync-protocol.patch deleted file mode 100644 index 0a0343e3..00000000 --- a/patches/server/0077-Placeholder-for-Bladeren-mspt-sync-protocol.patch +++ /dev/null @@ -1,15 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: MC_XiaoHei -Date: Wed, 8 May 2024 22:28:54 +0800 -Subject: [PATCH] Placeholder for Bladeren-mspt-sync-protocol - - -diff --git a/.gitignore b/.gitignore -index 3811c0d849a3eb028ed1a6b7a2d4747f7f570448..1ad93453221244f880855b510e888e759275b640 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -46,3 +46,4 @@ dependency-reduced-pom.xml - # vs code - /.vscode - /.factorypath -+ diff --git a/patches/server/0083-Skip-secondary-POI-sensor-if-absent.patch b/patches/server/0078-Skip-secondary-POI-sensor-if-absent.patch similarity index 100% rename from patches/server/0083-Skip-secondary-POI-sensor-if-absent.patch rename to patches/server/0078-Skip-secondary-POI-sensor-if-absent.patch diff --git a/patches/unapplied/server/0076-Bladeren-mspt-sync-protocol.patch b/patches/server/0079-Bladeren-mspt-sync-protocol.patch similarity index 79% rename from patches/unapplied/server/0076-Bladeren-mspt-sync-protocol.patch rename to patches/server/0079-Bladeren-mspt-sync-protocol.patch index a2765c8e..8e8342dd 100644 --- a/patches/unapplied/server/0076-Bladeren-mspt-sync-protocol.patch +++ b/patches/server/0079-Bladeren-mspt-sync-protocol.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Bladeren mspt sync protocol diff --git a/src/main/java/org/leavesmc/leaves/protocol/bladeren/MsptSyncProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/bladeren/MsptSyncProtocol.java new file mode 100644 -index 0000000000000000000000000000000000000000..cf909f22f0860e6f56a86510dfcbd949a4c1fc32 +index 0000000000000000000000000000000000000000..8bbcb87cf327ac3b85b8134231a23cb6092c5afb --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/bladeren/MsptSyncProtocol.java -@@ -0,0 +1,73 @@ +@@ -0,0 +1,77 @@ +package org.leavesmc.leaves.protocol.bladeren; + +import net.minecraft.resources.ResourceLocation; @@ -25,6 +25,7 @@ index 0000000000000000000000000000000000000000..cf909f22f0860e6f56a86510dfcbd949 +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; ++import java.util.OptionalDouble; + +@LeavesProtocol(namespace = "bladeren") +public class MsptSyncProtocol { @@ -43,7 +44,7 @@ index 0000000000000000000000000000000000000000..cf909f22f0860e6f56a86510dfcbd949 + @ProtocolHandler.Init + public static void init() { + BladerenProtocol.registerFeature("mspt_sync", (player, compoundTag) -> { -+ if (compoundTag.getString("Value").equals("true")) { ++ if (compoundTag.getString("Value").equals("true")) { + onPlayerSubmit(player); + } else { + onPlayerLoggedOut(player); @@ -67,12 +68,15 @@ index 0000000000000000000000000000000000000000..cf909f22f0860e6f56a86510dfcbd949 + + MinecraftServer server = MinecraftServer.getServer(); + if (server.getTickCount() % LeavesConfig.msptSyncTickInterval == 0) { -+ double mspt = Arrays.stream(server.getTickTimesNanos()).average().getAsDouble() * 1.0E-6D; -+ double tps = 1000.0D / Math.max(mspt, 50); -+ players.forEach(player -> ProtocolUtils.sendPayloadPacket(player, MSPT_SYNC, buf -> { -+ buf.writeDouble(mspt); -+ buf.writeDouble(tps); -+ })); ++ OptionalDouble msptArr = Arrays.stream(server.getTickTimesNanos()).average(); ++ if (msptArr.isPresent()) { ++ double mspt = msptArr.getAsDouble() * 1.0E-6D; ++ double tps = 1000.0D / Math.max(mspt, 50); ++ players.forEach(player -> ProtocolUtils.sendPayloadPacket(player, MSPT_SYNC, buf -> { ++ buf.writeDouble(mspt); ++ buf.writeDouble(tps); ++ })); ++ } + } + } + } diff --git a/patches/server/0085-Store-mob-counts-in-an-array.patch b/patches/server/0080-Store-mob-counts-in-an-array.patch similarity index 95% rename from patches/server/0085-Store-mob-counts-in-an-array.patch rename to patches/server/0080-Store-mob-counts-in-an-array.patch index 78303a6e..8dbb7568 100644 --- a/patches/server/0085-Store-mob-counts-in-an-array.patch +++ b/patches/server/0080-Store-mob-counts-in-an-array.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Store mob counts in an array This patch is Powered by Gale(https://github.com/GaleMC/Gale) diff --git a/src/main/java/net/minecraft/world/level/LocalMobCapCalculator.java b/src/main/java/net/minecraft/world/level/LocalMobCapCalculator.java -index 09199c574169057ae6e52ee7df277c03fa6ba5c2..388c2e43a46bdf4ac98279955560c6639e70f4de 100644 +index 2039b16e5e9bc0797b3f31081d221bb8b34a4dc7..ed3ef016bf22772f30c9f02d574405948e68d2af 100644 --- a/src/main/java/net/minecraft/world/level/LocalMobCapCalculator.java +++ b/src/main/java/net/minecraft/world/level/LocalMobCapCalculator.java @@ -43,13 +43,26 @@ public class LocalMobCapCalculator { diff --git a/patches/server/0086-Cache-BlockStatePairKey-hash.patch b/patches/server/0081-Cache-BlockStatePairKey-hash.patch similarity index 90% rename from patches/server/0086-Cache-BlockStatePairKey-hash.patch rename to patches/server/0081-Cache-BlockStatePairKey-hash.patch index a2d970b1..89da3143 100644 --- a/patches/server/0086-Cache-BlockStatePairKey-hash.patch +++ b/patches/server/0081-Cache-BlockStatePairKey-hash.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Cache BlockStatePairKey hash This patch is Powered by Gale(https://github.com/GaleMC/Gale) 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 549f77998274404b1b475230d88568fd3e27ac6d..8a610aad29e40a282ed16513c76a089722cb5762 100644 +index 9fa6c828471bfba2209bd4903e7240e05b6ee2ec..fc92ee39038cc4218741aca78294b4b0757796d5 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java -@@ -629,11 +629,18 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -626,11 +626,18 @@ public class Block extends BlockBehaviour implements ItemLike { private final BlockState first; private final BlockState second; private final Direction direction; @@ -28,7 +28,7 @@ index 549f77998274404b1b475230d88568fd3e27ac6d..8a610aad29e40a282ed16513c76a0897 } public boolean equals(Object object) { -@@ -649,11 +656,17 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -646,11 +653,17 @@ public class Block extends BlockBehaviour implements ItemLike { } public int hashCode() { diff --git a/patches/server/0081-Optimize-world-generation-chunk-and-block-access.patch b/patches/server/0081-Optimize-world-generation-chunk-and-block-access.patch deleted file mode 100644 index a4210f46..00000000 --- a/patches/server/0081-Optimize-world-generation-chunk-and-block-access.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: violetc <58360096+s-yh-china@users.noreply.github.com> -Date: Tue, 18 Jul 2023 13:36:25 +0800 -Subject: [PATCH] Optimize world generation chunk and block access - -This patch is Powered by Gale(https://github.com/GaleMC/Gale) - -diff --git a/src/main/java/net/minecraft/server/level/WorldGenRegion.java b/src/main/java/net/minecraft/server/level/WorldGenRegion.java -index a6c31a558794a6e626e83176a1cbe78b6bd90f6e..4a4b8ea0e8ba89d5a5ad890493d525a0f2a596fc 100644 ---- a/src/main/java/net/minecraft/server/level/WorldGenRegion.java -+++ b/src/main/java/net/minecraft/server/level/WorldGenRegion.java -@@ -86,6 +86,10 @@ public class WorldGenRegion implements WorldGenLevel { - private Supplier currentlyGenerating; - private final AtomicLong subTickCount = new AtomicLong(); - private static final ResourceLocation WORLDGEN_REGION_RANDOM = new ResourceLocation("worldgen_region_random"); -+ // Leaves start - optimize world generation chunk and block access -+ private ChunkAccess[] chunksArr; -+ private int minChunkX, minChunkZ; -+ // Leaves end - optimize world generation chunk and block access - - public WorldGenRegion(ServerLevel world, List chunks, ChunkStatus status, int placementRadius) { - this.generatingStatus = status; -@@ -107,6 +111,11 @@ public class WorldGenRegion implements WorldGenLevel { - this.firstPos = ((ChunkAccess) chunks.get(0)).getPos(); - this.lastPos = ((ChunkAccess) chunks.get(chunks.size() - 1)).getPos(); - } -+ // Leaves start - optimize world generation chunk and block access -+ this.minChunkX = this.firstPos.x; -+ this.minChunkZ = this.firstPos.z; -+ this.chunksArr = chunks.toArray(new ChunkAccess[0]); -+ // Leaves end - optimize world generation chunk and block access - } - - // Paper start - starlight -@@ -145,8 +154,29 @@ public class WorldGenRegion implements WorldGenLevel { - - @Override - public ChunkAccess getChunk(int chunkX, int chunkZ) { -- return this.getChunk(chunkX, chunkZ, ChunkStatus.EMPTY); -+ // Leaves start - optimize world generation chunk and block access -+ if (!org.leavesmc.leaves.LeavesConfig.optimizeWorldGenerationAccess) { -+ return this.getChunk(chunkX, chunkZ, ChunkStatus.EMPTY); -+ } else { -+ int x = chunkX - this.minChunkX; -+ int z = chunkZ - this.minChunkZ; -+ int w = this.size; -+ -+ if (x >= 0 && z >= 0 && x < w && z < w) { -+ return this.chunksArr[x + z * w]; -+ } else { -+ throw new NullPointerException("No chunk exists at " + new ChunkPos(chunkX, chunkZ)); -+ } -+ } -+ // Leaves end - optimize world generation chunk and block access -+ } -+ -+ // Leaves start - optimize world generation chunk and block access -+ public ChunkAccess getChunk(BlockPos pos) { -+ // Skip checking chunk.getStatus().isAtLeast(ChunkStatus.EMPTY) here, because it is always true -+ return this.getChunk(SectionPos.blockToSectionCoord(pos.getX()), SectionPos.blockToSectionCoord(pos.getZ())); - } -+ // Leaves end - optimize world generation chunk and block access - - @Nullable - @Override -@@ -211,7 +241,21 @@ public class WorldGenRegion implements WorldGenLevel { - - @Override - public BlockState getBlockState(BlockPos pos) { -- return this.getChunk(SectionPos.blockToSectionCoord(pos.getX()), SectionPos.blockToSectionCoord(pos.getZ())).getBlockState(pos); -+ // Leaves start - optimize world generation chunk and block access -+ if (!org.leavesmc.leaves.LeavesConfig.optimizeWorldGenerationAccess) { -+ return this.getChunk(SectionPos.blockToSectionCoord(pos.getX()), SectionPos.blockToSectionCoord(pos.getZ())).getBlockState(pos); -+ } else { -+ int x = SectionPos.blockToSectionCoord(pos.getX()) - this.minChunkX; -+ int z = SectionPos.blockToSectionCoord(pos.getZ()) - this.minChunkZ; -+ int w = this.size; -+ -+ if (x >= 0 && z >= 0 && x < w && z < w) { -+ return this.chunksArr[x + z * w].getBlockState(pos); -+ } else { -+ throw new NullPointerException("No chunk exists at " + new ChunkPos(pos)); -+ } -+ } -+ // Leaves end - optimize world generation chunk and block access - } - - @Override diff --git a/patches/server/0087-Optimize-noise-generation.patch b/patches/server/0082-Optimize-noise-generation.patch similarity index 100% rename from patches/server/0087-Optimize-noise-generation.patch rename to patches/server/0082-Optimize-noise-generation.patch diff --git a/patches/server/0088-Disable-packet-limit.patch b/patches/server/0083-Disable-packet-limit.patch similarity index 84% rename from patches/server/0088-Disable-packet-limit.patch rename to patches/server/0083-Disable-packet-limit.patch index 766d005e..bc50930f 100644 --- a/patches/server/0088-Disable-packet-limit.patch +++ b/patches/server/0083-Disable-packet-limit.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Disable packet limit diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 0cb47b5fee85230989293d430c02e53391e0ef67..124ea4b5894022df757578ce89374c33d5768a52 100644 +index 0a3f2f5b474910af3cabf3bab5310c0e970aed68..14239b07c85db85de2b76d83d2d1b573ce4cdf8a 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -@@ -265,7 +265,7 @@ public class GlobalConfiguration extends ConfigurationPart { +@@ -267,7 +267,7 @@ public class GlobalConfiguration extends ConfigurationPart { } public boolean isEnabled() { diff --git a/patches/server/0089-Reduce-array-allocations.patch b/patches/server/0084-Reduce-array-allocations.patch similarity index 74% rename from patches/server/0089-Reduce-array-allocations.patch rename to patches/server/0084-Reduce-array-allocations.patch index c0ce1f2e..929805a7 100644 --- a/patches/server/0089-Reduce-array-allocations.patch +++ b/patches/server/0084-Reduce-array-allocations.patch @@ -5,6 +5,45 @@ Subject: [PATCH] Reduce array allocations This patch is Powered by Gale(https://github.com/GaleMC/Gale) +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java +index 87d2b3ec165e2e9e4bdbedd7adddaa2130ed507b..aa17f322c6d5bfcada09d32f67f5df8f13f579ca 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java +@@ -27,6 +27,7 @@ import java.util.Iterator; + import java.util.List; + import java.util.function.Predicate; + import org.bukkit.event.entity.EntityRemoveEvent; ++import org.leavesmc.leaves.util.ArrayConstants; + + public final class ChunkEntitySlices { + +@@ -408,7 +409,7 @@ public final class ChunkEntitySlices { + + private static final class BasicEntityList { + +- private static final Entity[] EMPTY = new Entity[0]; ++ // protected static final Entity[] EMPTY = new Entity[0]; // Leaves - reduce array allocations + private static final int DEFAULT_CAPACITY = 4; + + private E[] storage; +@@ -419,7 +420,7 @@ public final class ChunkEntitySlices { + } + + public BasicEntityList(final int cap) { +- this.storage = (E[])(cap <= 0 ? EMPTY : new Entity[cap]); ++ this.storage = (E[])(cap <= 0 ? ArrayConstants.emptyEntityArray : new Entity[cap]); // Leaves - reduce array allocations + } + + public boolean isEmpty() { +@@ -431,7 +432,7 @@ public final class ChunkEntitySlices { + } + + private void resize() { +- if (this.storage == EMPTY) { ++ if (this.storage == ArrayConstants.emptyEntityArray) { // Leaves - reduce array allocations + this.storage = (E[])new Entity[DEFAULT_CAPACITY]; + } else { + this.storage = Arrays.copyOf(this.storage, this.storage.length * 2); diff --git a/src/main/java/com/destroystokyo/paper/util/maplist/EntityList.java b/src/main/java/com/destroystokyo/paper/util/maplist/EntityList.java index 0133ea6feb1ab88f021f66855669f58367e7420b..f56c2491fb2e84e459073ad128abf0dc699d45e9 100644 --- a/src/main/java/com/destroystokyo/paper/util/maplist/EntityList.java @@ -72,54 +111,6 @@ index ae60bd96b5284d54676d8e7e4dd5d170b526ec1e..0c474b1eb4dbef547890b7db5fcf9c13 } return true; } -diff --git a/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java b/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java -index c78cbec447032de9fe69748591bef6be300160ed..d00ddb838eb3ab5871449e591a80cb012b03d20f 100644 ---- a/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java -+++ b/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java -@@ -25,6 +25,7 @@ import java.util.Iterator; - import java.util.List; - import java.util.function.Predicate; - import org.bukkit.event.entity.EntityRemoveEvent; -+import org.leavesmc.leaves.util.ArrayConstants; - - public final class ChunkEntitySlices { - -@@ -83,7 +84,7 @@ public final class ChunkEntitySlices { - } - } - -- return ret.toArray(new org.bukkit.entity.Entity[0]); -+ return ret.toArray(ArrayConstants.emptyBukkitEntityArray); // Leaves - reduce array allocations - } - - public CompoundTag save() { -@@ -304,7 +305,7 @@ public final class ChunkEntitySlices { - - protected static final class BasicEntityList { - -- protected static final Entity[] EMPTY = new Entity[0]; -+ // protected static final Entity[] EMPTY = new Entity[0]; // Leaves - reduce array allocations - protected static final int DEFAULT_CAPACITY = 4; - - protected E[] storage; -@@ -315,7 +316,7 @@ public final class ChunkEntitySlices { - } - - public BasicEntityList(final int cap) { -- this.storage = (E[])(cap <= 0 ? EMPTY : new Entity[cap]); -+ this.storage = (E[])(cap <= 0 ? ArrayConstants.emptyEntityArray : new Entity[cap]); // Leaves - reduce array allocations - } - - public boolean isEmpty() { -@@ -327,7 +328,7 @@ public final class ChunkEntitySlices { - } - - private void resize() { -- if (this.storage == EMPTY) { -+ if (this.storage == ArrayConstants.emptyEntityArray) { // Leaves - reduce array allocations - this.storage = (E[])new Entity[DEFAULT_CAPACITY]; - } else { - this.storage = Arrays.copyOf(this.storage, this.storage.length * 2); diff --git a/src/main/java/net/minecraft/nbt/ByteArrayTag.java b/src/main/java/net/minecraft/nbt/ByteArrayTag.java index 06648f9751fd8a322d0809ffebf6a544596ee1a4..d6761bdb37619b91f147ff7a9197b730b90bd6cb 100644 --- a/src/main/java/net/minecraft/nbt/ByteArrayTag.java @@ -202,7 +193,7 @@ index ff13d67151c50ea11a45117e524c7524e2b1a202..8c3ee4c9aa22bcc46f2dc3a5bc35bdde @Override diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java -index 27dbea917d1a03aaa0d8de3db49d3cd25e76448f..e436a82b8db72f28ec9e614ae32ca32d36f1a32f 100644 +index 90a2c61c42cba7e38f167eccdd7a951a947963c4..2d6b221899a40e9bb4a52b21a62b71f7d1c26a80 100644 --- a/src/main/java/net/minecraft/network/Connection.java +++ b/src/main/java/net/minecraft/network/Connection.java @@ -66,6 +66,7 @@ import org.apache.commons.lang3.Validate; @@ -214,10 +205,10 @@ index 27dbea917d1a03aaa0d8de3db49d3cd25e76448f..e436a82b8db72f28ec9e614ae32ca32d public class Connection extends SimpleChannelInboundHandler> { diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java -index 6177fd5c7e1719a1618388f55b8510d8984a5bf2..04c4f86b63f479821f5757e790808440121f13bc 100644 +index 0c6ee6a22768d3cdd9ddad1c6fbf9bdffd8b4257..c6b7cd3035e9e222993438bac7e4774cd2c4f203 100644 --- a/src/main/java/net/minecraft/server/level/ServerEntity.java +++ b/src/main/java/net/minecraft/server/level/ServerEntity.java -@@ -369,7 +369,7 @@ public class ServerEntity { +@@ -356,7 +356,7 @@ public class ServerEntity { if (this.entity instanceof LivingEntity) { List> list = Lists.newArrayList(); @@ -227,37 +218,19 @@ index 6177fd5c7e1719a1618388f55b8510d8984a5bf2..04c4f86b63f479821f5757e790808440 for (int j = 0; j < i; ++j) { diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 3bb53128f6919712f0a88ec11c1bce25bf5b8b84..8593af5223c1e8de3684cb89957835dd0d23f111 100644 +index 0f1fef8f6e3b89f61b98358c6c8d84af4af2fa5e..c97a9096e6b0fcb8f336a745b812b5cf0ea682ed 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -180,6 +180,7 @@ import org.bukkit.event.server.MapInitializeEvent; +@@ -181,6 +181,7 @@ import org.bukkit.event.server.MapInitializeEvent; import org.bukkit.event.weather.LightningStrikeEvent; import org.bukkit.event.world.TimeSkipEvent; // CraftBukkit end +import org.leavesmc.leaves.util.ArrayConstants; - public class ServerLevel extends Level implements WorldGenLevel { + public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel, ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevelReader { // Paper - rewrite chunk system -@@ -1075,7 +1076,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.immutable(), this.randomTickRandom); // Leaves - reduce array allocations - } - // We drop the fluid tick since LAVA is ALREADY TICKED by the above method (See LiquidBlock). - // TODO CHECK ON UPDATE (ping the Canadian) -@@ -1381,7 +1382,7 @@ public class ServerLevel extends Level implements WorldGenLevel { - - public static List getCurrentlyTickingEntities() { - Entity ticking = currentlyTickingEntity.get(); -- List ret = java.util.Arrays.asList(ticking == null ? new Entity[0] : new Entity[] { ticking }); -+ List ret = java.util.Arrays.asList(ticking == null ? ArrayConstants.emptyEntityArray : new Entity[] { ticking }); // Leaves - reduce array allocations - - return ret; - } diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index f605051b11eb23e41c1f0339917a6731c1e6b2f3..27aecb9282460b7744638d282f4504fb9e8ce897 100644 +index 31ad4e4aaf321ab3c3909145e36a67744d906c65..7ba4f9926a8945651e55aeca99e3badaf258546e 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -249,6 +249,7 @@ import org.bukkit.inventory.EquipmentSlot; @@ -268,7 +241,7 @@ index f605051b11eb23e41c1f0339917a6731c1e6b2f3..27aecb9282460b7744638d282f4504fb public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl implements ServerGamePacketListener, ServerPlayerConnection, TickablePacketListener { -@@ -800,7 +801,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -772,7 +773,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // Paper start final int index; if (packet.getCommand().length() > 64 && ((index = packet.getCommand().indexOf(' ')) == -1 || index >= 64)) { @@ -278,10 +251,10 @@ index f605051b11eb23e41c1f0339917a6731c1e6b2f3..27aecb9282460b7744638d282f4504fb } // Paper end diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index b656741eb68adeb04bf995f1045902cb6bd5f2e7..73a2857af7c6b6d4578ce879ebe3713ebe55acdf 100644 +index b0f7a378f19b9837c060c891002cd5db756cdae1..8b13bd7aec76f30c5b5920758393066540798ab3 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -@@ -49,6 +49,7 @@ import org.bukkit.craftbukkit.entity.CraftPlayer; +@@ -51,6 +51,7 @@ import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.craftbukkit.util.Waitable; import org.bukkit.event.player.AsyncPlayerPreLoginEvent; import org.bukkit.event.player.PlayerPreLoginEvent; @@ -289,7 +262,7 @@ index b656741eb68adeb04bf995f1045902cb6bd5f2e7..73a2857af7c6b6d4578ce879ebe3713e public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, TickablePacketListener, CraftPlayer.TransferCookieConnection { -@@ -165,12 +166,12 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, +@@ -167,12 +168,12 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, @Override public void handleHello(ServerboundHelloPacket packet) { @@ -304,7 +277,7 @@ index b656741eb68adeb04bf995f1045902cb6bd5f2e7..73a2857af7c6b6d4578ce879ebe3713e } // Paper end - Validate usernames this.requestedUsername = packet.name(); -@@ -268,7 +269,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, +@@ -270,7 +271,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, @Override public void handleKey(ServerboundKeyPacket packet) { @@ -314,17 +287,26 @@ index b656741eb68adeb04bf995f1045902cb6bd5f2e7..73a2857af7c6b6d4578ce879ebe3713e final String s; diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index c9e904ab960739c5b64f44ef92e3a02159149e66..c4aac957906ff3bf28b29e58e30decc608562e6a 100644 +index 5c47209505af8e9bea3f20effa4e176c32e5109a..fedeaf43f7b61a7ca6dc2a99bb76a47f4c640a1d 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -27,6 +27,7 @@ import javax.annotation.Nullable; - import net.minecraft.ChatFormatting; - import net.minecraft.FileUtil; - import org.leavesmc.leaves.util.ReturnPortalManager; // Leaves - return portal fix -+import org.leavesmc.leaves.util.ArrayConstants; - import net.minecraft.commands.CommandSourceStack; - import net.minecraft.core.BlockPos; - import net.minecraft.core.LayeredRegistryAccess; +@@ -947,13 +947,9 @@ public abstract class PlayerList { + final ResourceKey OVERWORLD = Level.OVERWORLD; + final ResourceKey THE_NETHER = Level.NETHER; + if (!((fromDim != OVERWORLD || toDim != THE_NETHER) && (fromDim != THE_NETHER || toDim != OVERWORLD))) { +- BlockPos lastPos = entityplayer1.lastPos; +- if (lastPos != null) { +- net.minecraft.BlockUtil.FoundRectangle fromPortal = ReturnPortalManager.findPortalAt(entityplayer1, fromDim, lastPos); +- BlockPos toPos = entityplayer1.blockPosition(); +- if (fromPortal != null) { +- ReturnPortalManager.storeReturnPortal(entityplayer1, toDim, toPos, fromPortal); +- } ++ BlockPos fromPortal = org.leavesmc.leaves.util.ReturnPortalManager.findPortalAt(entityplayer1, fromDim, entityplayer1.lastPos); ++ if (fromPortal != null) { ++ org.leavesmc.leaves.util.ReturnPortalManager.storeReturnPortal(entityplayer1, toDim, entityplayer1.blockPosition(), fromPortal); + } + } + } diff --git a/src/main/java/net/minecraft/server/players/StoredUserList.java b/src/main/java/net/minecraft/server/players/StoredUserList.java index c038da20b76c0b7b1c18471b20be01e849d29f3a..603007a376dc76c46d34f265283dda693cbf6c88 100644 --- a/src/main/java/net/minecraft/server/players/StoredUserList.java @@ -363,22 +345,22 @@ index 54c7d9bed0fead691d06691086f04cc2521dbe07..0c6007c9dbd053cba641038955ef1ca1 public ZeroBitStorage(int size) { diff --git a/src/main/java/net/minecraft/world/entity/EquipmentSlot.java b/src/main/java/net/minecraft/world/entity/EquipmentSlot.java -index eb3c12e03c0d5c9cec84d97e2c51c50ce59c23a4..0593d76c67f4475d624c5289b65c5d4a3c91e4cd 100644 +index 2fa2a4eef21e786f738f36616c3160defa95bce8..36c98f611f043ebadffd1b110ba3002b29731a52 100644 --- a/src/main/java/net/minecraft/world/entity/EquipmentSlot.java +++ b/src/main/java/net/minecraft/world/entity/EquipmentSlot.java -@@ -16,6 +16,7 @@ public enum EquipmentSlot implements StringRepresentable { - private final int index; +@@ -19,6 +19,7 @@ public enum EquipmentSlot implements StringRepresentable { + private final int countLimit; private final int filterFlag; private final String name; + public static final EquipmentSlot[] VALUES = EquipmentSlot.values(); // Leaves - reduce array allocations - private EquipmentSlot(final EquipmentSlot.Type type, final int entityId, final int armorStandId, final String name) { + private EquipmentSlot(final EquipmentSlot.Type type, final int entityId, final int maxCount, final int armorStandId, final String name) { this.type = type; diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 9c7fdcd820fa40aa3f0b8fcebc103cbfe7e27450..8bfbe0b23a1bba49b4c96425dd10eee1153a5697 100644 +index 0c3e98a478de9524354ad5e3a02f8268b88d7083..eb1ab66ebe14db9a425b65652ef9deace8ea80fa 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3222,7 +3222,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3230,7 +3230,7 @@ public abstract class LivingEntity extends Entity implements Attackable { @Nullable private Map collectEquipmentChanges() { Map map = null; @@ -388,19 +370,19 @@ index 9c7fdcd820fa40aa3f0b8fcebc103cbfe7e27450..8bfbe0b23a1bba49b4c96425dd10eee1 for (int j = 0; j < i; ++j) { diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index a773e3f208b54fac46e5fd532d80fb66f56a5e3c..7892c0d43f49d058be25e9c6b62bebfb9aa62229 100644 +index 5c20fad61b81189ad45623346fa2b79ea8aa9b2a..2634a4cb8a880363829ecffa85cb57ac22f9a632 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java -@@ -1201,7 +1201,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti +@@ -1152,7 +1152,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab @Override - protected void dropCustomDeathLoot(DamageSource source, int lootingMultiplier, boolean allowDrops) { - super.dropCustomDeathLoot(source, lootingMultiplier, allowDrops); + protected void dropCustomDeathLoot(ServerLevel world, DamageSource source, boolean causedByPlayer) { + super.dropCustomDeathLoot(world, source, causedByPlayer); - EquipmentSlot[] aenumitemslot = EquipmentSlot.values(); + EquipmentSlot[] aenumitemslot = EquipmentSlot.VALUES; // Leaves - reduce array allocations - int j = aenumitemslot.length; + int i = aenumitemslot.length; - for (int k = 0; k < j; ++k) { -@@ -1284,7 +1284,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti + for (int j = 0; j < i; ++j) { +@@ -1282,7 +1282,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab } boolean flag = true; @@ -409,16 +391,16 @@ index a773e3f208b54fac46e5fd532d80fb66f56a5e3c..7892c0d43f49d058be25e9c6b62bebfb int j = aenumitemslot.length; for (int k = 0; k < j; ++k) { -@@ -1371,7 +1371,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti - float f = localDifficulty.getSpecialMultiplier(); +@@ -1367,7 +1367,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab - this.enchantSpawnedWeapon(random, f); + protected void populateDefaultEquipmentEnchantments(ServerLevelAccessor world, RandomSource random, DifficultyInstance localDifficulty) { + this.enchantSpawnedWeapon(world, random, localDifficulty); - EquipmentSlot[] aenumitemslot = EquipmentSlot.values(); + EquipmentSlot[] aenumitemslot = EquipmentSlot.VALUES; // Leaves - reduce array allocations int i = aenumitemslot.length; for (int j = 0; j < i; ++j) { -@@ -1591,7 +1591,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti +@@ -1572,7 +1572,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab t0.setInvulnerable(this.isInvulnerable()); if (flag) { t0.setCanPickUpLoot(this.canPickUpLoot()); @@ -427,76 +409,20 @@ index a773e3f208b54fac46e5fd532d80fb66f56a5e3c..7892c0d43f49d058be25e9c6b62bebfb int i = aenumitemslot.length; for (int j = 0; j < i; ++j) { -diff --git a/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java b/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java -index f38acc96f71298e40ce9433e7759fd223ca55e48..03652ec451109d2026fc313f143d78d4b855dd51 100644 ---- a/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java -+++ b/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java -@@ -238,7 +238,7 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder { - return; - } - // CraftBukkit end -- EquipmentSlot[] aenumitemslot = EquipmentSlot.values(); -+ EquipmentSlot[] aenumitemslot = EquipmentSlot.VALUES; // Leaves - reduce array allocations - int i = aenumitemslot.length; - - for (int j = 0; j < i; ++j) { -diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index 0522368deaa13f13fad4e2f00346f3910a064618..99acee6f58ac532694859cf0a71c56f3ef8b402b 100644 ---- a/src/main/java/net/minecraft/world/item/ItemStack.java -+++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -1111,7 +1111,7 @@ public final class ItemStack implements DataComponentHolder { - ItemAttributeModifiers itemattributemodifiers = (ItemAttributeModifiers) this.getOrDefault(DataComponents.ATTRIBUTE_MODIFIERS, ItemAttributeModifiers.EMPTY); - - if (itemattributemodifiers.showInTooltip()) { -- EquipmentSlot[] aenumitemslot = EquipmentSlot.values(); -+ EquipmentSlot[] aenumitemslot = EquipmentSlot.VALUES; // Leaves - reduce array allocations - int i = aenumitemslot.length; - - for (int j = 0; j < i; ++j) { diff --git a/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java b/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java -index fb4c8a2a15e8e3e26454b7da920454e9861336c6..af13503a1e6e25893889705a48cef60d99a7e04f 100644 +index 1bf54b0142fe41b29b21c8b97d3f52bb24a36a92..f19ace4f9027260ded3ee37c1bda91c56d2a086c 100644 --- a/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java +++ b/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java -@@ -17,6 +17,7 @@ import org.bukkit.craftbukkit.inventory.CraftRecipe; +@@ -16,6 +16,7 @@ import org.bukkit.craftbukkit.inventory.CraftRecipe; import org.bukkit.craftbukkit.inventory.CraftShapedRecipe; import org.bukkit.inventory.RecipeChoice; // CraftBukkit end +import org.leavesmc.leaves.util.ArrayConstants; - public class ShapedRecipe extends io.papermc.paper.inventory.recipe.RecipeBookExactChoiceRecipe implements CraftingRecipe { // Paper - improve exact recipe choices + public class ShapedRecipe extends io.papermc.paper.inventory.recipe.RecipeBookExactChoiceRecipe implements CraftingRecipe { // Paper - improve exact recipe choices -diff --git a/src/main/java/net/minecraft/world/item/enchantment/Enchantments.java b/src/main/java/net/minecraft/world/item/enchantment/Enchantments.java -index e158ff1a9dbd054985873e854fcf6c433102059c..e061322fed6adf49a506ea13db50cdf25eb0fb33 100644 ---- a/src/main/java/net/minecraft/world/item/enchantment/Enchantments.java -+++ b/src/main/java/net/minecraft/world/item/enchantment/Enchantments.java -@@ -303,20 +303,22 @@ public class Enchantments { - public static final Enchantment DENSITY = register("density", new DensityEnchantment()); - public static final Enchantment BREACH = register("breach", new BreachEnchantment()); - public static final Enchantment WIND_BURST = register("wind_burst", new WindBurstEnchantment()); -- public static final Enchantment MENDING = register( -+ // Leaves start - reduce array allocations -+ public static final Enchantment MENDING = Enchantments.register( - "mending", - new MendingEnchantment( - Enchantment.definition( -- ItemTags.DURABILITY_ENCHANTABLE, 2, 1, Enchantment.dynamicCost(25, 25), Enchantment.dynamicCost(75, 25), 4, EquipmentSlot.values() -+ ItemTags.DURABILITY_ENCHANTABLE, 2, 1, Enchantment.dynamicCost(25, 25), Enchantment.dynamicCost(75, 25), 4, EquipmentSlot.VALUES - ) - ) - ); - public static final Enchantment VANISHING_CURSE = register( - "vanishing_curse", - new VanishingCurseEnchantment( -- Enchantment.definition(ItemTags.VANISHING_ENCHANTABLE, 1, 1, Enchantment.constantCost(25), Enchantment.constantCost(50), 8, EquipmentSlot.values()) -+ Enchantment.definition(ItemTags.VANISHING_ENCHANTABLE, 1, 1, Enchantment.constantCost(25), Enchantment.constantCost(50), 8, EquipmentSlot.VALUES) - ) - ); -+ // Leaves end - reduce array allocations - - private static Enchantment register(String name, Enchantment enchantment) { - return Registry.register(BuiltInRegistries.ENCHANTMENT, name, enchantment); diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 099617d8aefc9b9f1bbcf2810af64b8152822291..ac9647b7232a860b87c0a15aa7971e243d311152 100644 +index 133c90ee13587c441ecd47038d389353940ad3bf..b4e10f82edbbe5301ddcf13f33f2f857eb2858a9 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -101,6 +101,7 @@ import org.bukkit.craftbukkit.util.CraftSpawnCategory; @@ -505,17 +431,8 @@ index 099617d8aefc9b9f1bbcf2810af64b8152822291..ac9647b7232a860b87c0a15aa7971e24 // CraftBukkit end +import org.leavesmc.leaves.util.ArrayConstants; - public abstract class Level implements LevelAccessor, AutoCloseable { + public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel, ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemEntityGetter { // Paper - rewrite chunk system -@@ -1860,7 +1861,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - public org.bukkit.entity.Entity[] getChunkEntities(int chunkX, int chunkZ) { - io.papermc.paper.world.ChunkEntitySlices slices = ((ServerLevel)this).getEntityLookup().getChunk(chunkX, chunkZ); - if (slices == null) { -- return new org.bukkit.entity.Entity[0]; -+ return ArrayConstants.emptyBukkitEntityArray; // Leaves - reduce array allocations - } - return slices.getChunkEntities(); - } diff --git a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java index d3d12f9114173f4971f95d7ef895a4374705bd3f..d9e28a241f7fc9c6828dc3b169f56bad08db5b04 100644 --- a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java @@ -556,7 +473,7 @@ index d3d12f9114173f4971f95d7ef895a4374705bd3f..d9e28a241f7fc9c6828dc3b169f56bad @Override diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -index a99fe191c429bb528209dd0f31b509acf9cccbb5..e544ad7f34005b2aba554a21f3c277bca4f6773d 100644 +index 9ad4600ebee09d81b1785103ad17de47cf1f2ede..6d4264567944f234f6bb3f344c9797a3f73b8df1 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java @@ -60,6 +60,7 @@ import org.bukkit.event.inventory.FurnaceSmeltEvent; diff --git a/patches/server/0090-Optimize-sun-burn-tick.patch b/patches/server/0085-Optimize-sun-burn-tick.patch similarity index 91% rename from patches/server/0090-Optimize-sun-burn-tick.patch rename to patches/server/0085-Optimize-sun-burn-tick.patch index f8518d8d..39e9cfa1 100644 --- a/patches/server/0090-Optimize-sun-burn-tick.patch +++ b/patches/server/0085-Optimize-sun-burn-tick.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Optimize sun burn tick This patch is Powered by Gale(https://github.com/GaleMC/Gale) diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index a13843368d161fd252a95a620463d7040fd98308..2263671fe90d6d26b50de5e211571273ad695c97 100644 +index f9a90bddb0bec8b67da3f9d05a0f3056048c8272..8c89114f34a7b3807efa4f012f378bfa24b5cc6f 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -2090,8 +2090,22 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1975,8 +1975,22 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess /** @deprecated */ @Deprecated public float getLightLevelDependentMagicValue() { @@ -34,12 +34,12 @@ index a13843368d161fd252a95a620463d7040fd98308..2263671fe90d6d26b50de5e211571273 public void absMoveTo(double x, double y, double z, float yaw, float pitch) { this.absMoveTo(x, y, z); diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index 7892c0d43f49d058be25e9c6b62bebfb9aa62229..8a5f5a7b1f0d90014a3c9753e464cace41ca06d9 100644 +index 2634a4cb8a880363829ecffa85cb57ac22f9a632..d1ed94b5e924b39d9d17fd27f0e123316a3b4da2 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java -@@ -1845,15 +1845,41 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti - return flag; - } +@@ -1752,15 +1752,41 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab + + protected void playAttackSound() {} + // Leaves start - optimize sun burn tick + private BlockPos cached_eye_blockpos; diff --git a/patches/server/0091-Reduce-lambda-and-Optional-allocation-in-EntityBased.patch b/patches/server/0086-Reduce-lambda-and-Optional-allocation-in-EntityBased.patch similarity index 100% rename from patches/server/0091-Reduce-lambda-and-Optional-allocation-in-EntityBased.patch rename to patches/server/0086-Reduce-lambda-and-Optional-allocation-in-EntityBased.patch diff --git a/patches/server/0092-Avoid-Class-isAssignableFrom-call-in-ClassInstanceMu.patch b/patches/server/0087-Avoid-Class-isAssignableFrom-call-in-ClassInstanceMu.patch similarity index 100% rename from patches/server/0092-Avoid-Class-isAssignableFrom-call-in-ClassInstanceMu.patch rename to patches/server/0087-Avoid-Class-isAssignableFrom-call-in-ClassInstanceMu.patch diff --git a/patches/server/0093-Optimized-CubePointRange.patch b/patches/server/0088-Optimized-CubePointRange.patch similarity index 93% rename from patches/server/0093-Optimized-CubePointRange.patch rename to patches/server/0088-Optimized-CubePointRange.patch index 0c325b54..d05acc81 100644 --- a/patches/server/0093-Optimized-CubePointRange.patch +++ b/patches/server/0088-Optimized-CubePointRange.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Optimized CubePointRange This patch is Powered by Gale(https://github.com/GaleMC/Gale) diff --git a/src/main/java/net/minecraft/world/phys/shapes/CubePointRange.java b/src/main/java/net/minecraft/world/phys/shapes/CubePointRange.java -index a544db042c8d2ecec8d323770552c4f10ca758a6..d913151417ea72dcb2419d691b869fbf75be8aaa 100644 +index ad02cdb00360165f6405eb3044bd8320f01a7ef1..99ddf5419833244338d349a32e576d21198cef54 100644 --- a/src/main/java/net/minecraft/world/phys/shapes/CubePointRange.java +++ b/src/main/java/net/minecraft/world/phys/shapes/CubePointRange.java @@ -3,21 +3,31 @@ package net.minecraft.world.phys.shapes; @@ -17,7 +17,7 @@ index a544db042c8d2ecec8d323770552c4f10ca758a6..d913151417ea72dcb2419d691b869fbf private final int parts; + private final double scale; // Leaves - replace division by multiplication in CubePointRange - CubePointRange(int sectionCount) { + public CubePointRange(int sectionCount) { if (sectionCount <= 0) { throw new IllegalArgumentException("Need at least 1 part"); } else { diff --git a/patches/server/0094-Check-frozen-ticks-before-landing-block.patch b/patches/server/0089-Check-frozen-ticks-before-landing-block.patch similarity index 89% rename from patches/server/0094-Check-frozen-ticks-before-landing-block.patch rename to patches/server/0089-Check-frozen-ticks-before-landing-block.patch index f74e708d..b6191976 100644 --- a/patches/server/0094-Check-frozen-ticks-before-landing-block.patch +++ b/patches/server/0089-Check-frozen-ticks-before-landing-block.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Check frozen ticks before landing block This patch is Powered by Gale(https://github.com/GaleMC/Gale) diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 8bfbe0b23a1bba49b4c96425dd10eee1153a5697..a92dacce023b4f4c88e70a1f70812e5a4458a0e3 100644 +index eb1ab66ebe14db9a425b65652ef9deace8ea80fa..985f5807bcf9edaa39f74583d7927daabbcd11d9 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -593,11 +593,11 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -564,11 +564,11 @@ public abstract class LivingEntity extends Entity implements Attackable { } protected void tryAddFrost() { diff --git a/patches/server/0095-Skip-entity-move-if-movement-is-zero.patch b/patches/server/0090-Skip-entity-move-if-movement-is-zero.patch similarity index 78% rename from patches/server/0095-Skip-entity-move-if-movement-is-zero.patch rename to patches/server/0090-Skip-entity-move-if-movement-is-zero.patch index 22f50a6e..2eeb98aa 100644 --- a/patches/server/0095-Skip-entity-move-if-movement-is-zero.patch +++ b/patches/server/0090-Skip-entity-move-if-movement-is-zero.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Skip entity move if movement is zero This patch is Powered by Gale(https://github.com/GaleMC/Gale) diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 2263671fe90d6d26b50de5e211571273ad695c97..ed5e9667edad44301366773cfc14bf9b9807e7d5 100644 +index 8c89114f34a7b3807efa4f012f378bfa24b5cc6f..18a1a6211620c2f3f9d6fad022daa2d45d993f60 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -319,6 +319,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -324,6 +324,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess public float yRotO; public float xRotO; private AABB bb; @@ -17,8 +17,8 @@ index 2263671fe90d6d26b50de5e211571273ad695c97..ed5e9667edad44301366773cfc14bf9b public boolean onGround; public boolean horizontalCollision; public boolean verticalCollision; -@@ -1133,6 +1134,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - // Paper end - detailed watchdog information +@@ -1068,6 +1069,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + } public void move(MoverType movementType, Vec3 movement) { + // Leaves start - skip entity move if movement is zero @@ -29,9 +29,9 @@ index 2263671fe90d6d26b50de5e211571273ad695c97..ed5e9667edad44301366773cfc14bf9b + } + // Leaves end - skip entity move if movement is zero final Vec3 originalMovement = movement; // Paper - Expose pre-collision velocity - // Paper start - detailed watchdog information - io.papermc.paper.util.TickThread.ensureTickThread("Cannot move an entity off-main"); -@@ -4183,6 +4191,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + if (this.noPhysics) { + this.setPos(this.getX() + movement.x, this.getY() + movement.y, this.getZ() + movement.z); +@@ -4002,6 +4010,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public final void setBoundingBox(AABB boundingBox) { diff --git a/patches/server/0096-Skip-cloning-advancement-criteria.patch b/patches/server/0091-Skip-cloning-advancement-criteria.patch similarity index 92% rename from patches/server/0096-Skip-cloning-advancement-criteria.patch rename to patches/server/0091-Skip-cloning-advancement-criteria.patch index f60dba6a..532c4560 100644 --- a/patches/server/0096-Skip-cloning-advancement-criteria.patch +++ b/patches/server/0091-Skip-cloning-advancement-criteria.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Skip cloning advancement criteria This patch is Powered by Gale(https://github.com/GaleMC/Gale) diff --git a/src/main/java/net/minecraft/advancements/Advancement.java b/src/main/java/net/minecraft/advancements/Advancement.java -index 6d04be3a75df1f847389b985c9b1c0330c9e2415..23a3575befe8282c5f1be7601645c4c6108776b3 100644 +index fb4b7652c386fa10783d71899615723a958ffd56..eb987b0cb6d2018e648c1488aa2059be18369bd4 100644 --- a/src/main/java/net/minecraft/advancements/Advancement.java +++ b/src/main/java/net/minecraft/advancements/Advancement.java @@ -60,7 +60,7 @@ public record Advancement( diff --git a/patches/server/0097-Skip-negligible-planar-movement-multiplication.patch b/patches/server/0092-Skip-negligible-planar-movement-multiplication.patch similarity index 80% rename from patches/server/0097-Skip-negligible-planar-movement-multiplication.patch rename to patches/server/0092-Skip-negligible-planar-movement-multiplication.patch index e7fac54e..9e88c4a5 100644 --- a/patches/server/0097-Skip-negligible-planar-movement-multiplication.patch +++ b/patches/server/0092-Skip-negligible-planar-movement-multiplication.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Skip negligible planar movement multiplication This patch is Powered by Gale(https://github.com/GaleMC/Gale) diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index ed5e9667edad44301366773cfc14bf9b9807e7d5..2d40a0b3dc849a57abc4346aad2c01f3dc3e5d98 100644 +index 18a1a6211620c2f3f9d6fad022daa2d45d993f60..4f984341827634d7a5eef449657c513bf8a70a0b 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -1305,9 +1305,16 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1230,9 +1230,16 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } this.tryCheckInsideBlocks(); @@ -26,6 +26,6 @@ index ed5e9667edad44301366773cfc14bf9b9807e7d5..2d40a0b3dc849a57abc4346aad2c01f3 + } + } + // Leaves end - skip negligible planar movement multiplication - // Paper start - remove expensive streams from here - boolean noneMatch = true; - AABB fireSearchBox = this.getBoundingBox().deflate(1.0E-6D); + if (this.level().getBlockStatesIfLoaded(this.getBoundingBox().deflate(1.0E-6D)).noneMatch((iblockdata2) -> { + return iblockdata2.is(BlockTags.FIRE) || iblockdata2.is(Blocks.LAVA); + })) { diff --git a/patches/server/0098-Fix-villagers-dont-release-memory.patch b/patches/server/0093-Fix-villagers-dont-release-memory.patch similarity index 80% rename from patches/server/0098-Fix-villagers-dont-release-memory.patch rename to patches/server/0093-Fix-villagers-dont-release-memory.patch index fd6c10e0..b0b38955 100644 --- a/patches/server/0098-Fix-villagers-dont-release-memory.patch +++ b/patches/server/0093-Fix-villagers-dont-release-memory.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix villagers dont release memory 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 a7930f9875aa4aca997caaead46ecdc21e5e11d7..6cac189cf6e0bef2f0ea8c0dbadb0f417171a05e 100644 +index 7e1871401ec5e3e9a85232053490259f132aec0a..18642b4e43d0725690be44b53bbddb6d4486e5f1 100644 --- a/src/main/java/net/minecraft/world/entity/npc/Villager.java +++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java -@@ -1069,4 +1069,20 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -1071,4 +1071,20 @@ public class Villager extends AbstractVillager implements ReputationEventHandler return optional.isPresent() ? worldTime - (Long) optional.get() < 24000L : false; } @@ -16,14 +16,14 @@ index a7930f9875aa4aca997caaead46ecdc21e5e11d7..6cac189cf6e0bef2f0ea8c0dbadb0f41 + // Leaves start - fixes a memory leak when villagers get moved to another world + @Nullable + @Override -+ public Entity changeDimension(ServerLevel destination) { ++ public Entity changeDimension(net.minecraft.world.level.portal.DimensionTransition destination) { + if (org.leavesmc.leaves.LeavesConfig.villagersDontReleaseMemoryFix) { + this.releaseAllPois(); + this.getBrain().eraseMemory(MemoryModuleType.HOME); + this.getBrain().eraseMemory(MemoryModuleType.JOB_SITE); + this.getBrain().eraseMemory(MemoryModuleType.POTENTIAL_JOB_SITE); + this.getBrain().eraseMemory(MemoryModuleType.MEETING_POINT); -+ this.refreshBrain(destination); ++ this.refreshBrain(destination.newLevel()); + } + return super.changeDimension(destination); + } diff --git a/patches/server/0099-Avoid-anvil-too-expensive.patch b/patches/server/0094-Avoid-anvil-too-expensive.patch similarity index 91% rename from patches/server/0099-Avoid-anvil-too-expensive.patch rename to patches/server/0094-Avoid-anvil-too-expensive.patch index 5e7a3657..a5971de2 100644 --- a/patches/server/0099-Avoid-anvil-too-expensive.patch +++ b/patches/server/0094-Avoid-anvil-too-expensive.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Avoid anvil too expensive diff --git a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java -index 2bd91b48eaa06f85a5b9b1ae052c70e966ae8e4c..d49b2539476b2ae2fc09f1bad0e6a7222e35cf45 100644 +index 7198dc9ffc9a37dab3654e12aa497c442a9993c5..f81870bf7fb81d3c409971a35e5782c898ab547b 100644 --- a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java +++ b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java @@ -280,7 +280,7 @@ public class AnvilMenu extends ItemCombinerMenu { diff --git a/patches/server/0100-Bow-infinity-fix.patch b/patches/server/0095-Bow-infinity-fix.patch similarity index 73% rename from patches/server/0100-Bow-infinity-fix.patch rename to patches/server/0095-Bow-infinity-fix.patch index 34b509d0..d1fb8b04 100644 --- a/patches/server/0100-Bow-infinity-fix.patch +++ b/patches/server/0095-Bow-infinity-fix.patch @@ -5,16 +5,16 @@ Subject: [PATCH] Bow infinity fix diff --git a/src/main/java/net/minecraft/world/item/BowItem.java b/src/main/java/net/minecraft/world/item/BowItem.java -index 5ca843df5b4caa668953e5e36a9b20fabeb35046..a1675610ad5114d29f71d385a00330eb0744be5c 100644 +index 6eb5c0f23d9dc61e69ad5ad493c89602a9dcd4b5..7a5073539a451d31a89dc88e38468f141ef452cd 100644 --- a/src/main/java/net/minecraft/world/item/BowItem.java +++ b/src/main/java/net/minecraft/world/item/BowItem.java -@@ -80,7 +80,8 @@ public class BowItem extends ProjectileWeaponItem { +@@ -81,7 +81,8 @@ public class BowItem extends ProjectileWeaponItem { @Override public InteractionResultHolder use(Level world, Player user, InteractionHand hand) { ItemStack itemStack = user.getItemInHand(hand); - boolean bl = !user.getProjectile(itemStack).isEmpty(); + boolean bl = !user.getProjectile(itemStack).isEmpty() -+ || (org.leavesmc.leaves.LeavesConfig.bowInfinityFix && net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.INFINITY, itemStack) > 0); ++ || (org.leavesmc.leaves.LeavesConfig.bowInfinityFix && net.minecraft.world.item.enchantment.EnchantmentHelper.processAmmoUse((ServerLevel) world, itemStack, new ItemStack(Items.ARROW), 1) <= 0); // Leaves - Bow infinity fix if (!user.hasInfiniteMaterials() && !bl) { return InteractionResultHolder.fail(itemStack); } else { diff --git a/patches/server/0101-Zero-tick-plants.patch b/patches/server/0096-Zero-tick-plants.patch similarity index 100% rename from patches/server/0101-Zero-tick-plants.patch rename to patches/server/0096-Zero-tick-plants.patch diff --git a/patches/server/0102-Leaves-update-command.patch b/patches/server/0097-Leaves-Updater.patch similarity index 77% rename from patches/server/0102-Leaves-update-command.patch rename to patches/server/0097-Leaves-Updater.patch index f09f924b..7fb397cb 100644 --- a/patches/server/0102-Leaves-update-command.patch +++ b/patches/server/0097-Leaves-Updater.patch @@ -1,22 +1,17 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: violetc <58360096+s-yh-china@users.noreply.github.com> Date: Mon, 31 Jul 2023 17:42:25 +0800 -Subject: [PATCH] Leaves update command +Subject: [PATCH] Leaves Updater +--------- + +Co-authored-by: MC_XiaoHei diff --git a/src/main/java/org/leavesmc/leaves/command/LeavesCommand.java b/src/main/java/org/leavesmc/leaves/command/LeavesCommand.java -index b9e2bdb034dcd5119680ddea44a1eda11a0189b2..facd180da9b7025cf7ae192cbe91317ff4b70472 100644 +index ebd62b1d3a60d3e22e3849047293e1f62533eae7..e964f05c5c0f2d1d9b4c0a3459076e4b95f0f4e8 100644 --- a/src/main/java/org/leavesmc/leaves/command/LeavesCommand.java +++ b/src/main/java/org/leavesmc/leaves/command/LeavesCommand.java -@@ -13,6 +13,7 @@ import org.bukkit.plugin.PluginManager; - import org.checkerframework.checker.nullness.qual.Nullable; - import org.jetbrains.annotations.NotNull; - import org.leavesmc.leaves.command.subcommands.ConfigCommand; -+import org.leavesmc.leaves.command.subcommands.UpdateCommand; - - import java.util.ArrayList; - import java.util.Arrays; -@@ -33,6 +34,7 @@ public final class LeavesCommand extends Command { +@@ -33,6 +33,7 @@ public final class LeavesCommand extends Command { private static final Map SUBCOMMANDS = Util.make(() -> { final Map, LeavesSubcommand> commands = new HashMap<>(); commands.put(Set.of("config"), new ConfigCommand()); @@ -53,10 +48,10 @@ index 0000000000000000000000000000000000000000..7f94df607e8ffd48ab2cb7c90d520c2b +} diff --git a/src/main/java/org/leavesmc/leaves/util/LeavesUpdateHelper.java b/src/main/java/org/leavesmc/leaves/util/LeavesUpdateHelper.java new file mode 100644 -index 0000000000000000000000000000000000000000..06ca57f0cb319a254ca1511e60f05e5ca151beea +index 0000000000000000000000000000000000000000..8620305f3330a856ad7445259f565bf8e281ea52 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/util/LeavesUpdateHelper.java -@@ -0,0 +1,240 @@ +@@ -0,0 +1,268 @@ +package org.leavesmc.leaves.util; + +import com.google.common.base.Charsets; @@ -68,6 +63,7 @@ index 0000000000000000000000000000000000000000..06ca57f0cb319a254ca1511e60f05e5c +import net.minecraft.Util; +import org.bukkit.Bukkit; +import org.jetbrains.annotations.NotNull; ++import org.leavesmc.leaves.LeavesConfig; +import org.leavesmc.leaves.LeavesLogger; + +import java.io.BufferedReader; @@ -78,6 +74,8 @@ index 0000000000000000000000000000000000000000..06ca57f0cb319a254ca1511e60f05e5c +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; ++import java.net.URI; ++import java.net.URISyntaxException; +import java.net.URL; +import java.nio.channels.Channels; +import java.nio.channels.FileChannel; @@ -85,6 +83,11 @@ index 0000000000000000000000000000000000000000..06ca57f0cb319a254ca1511e60f05e5c +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.MessageDigest; ++import java.time.Duration; ++import java.time.LocalTime; ++import java.util.concurrent.Executors; ++import java.util.concurrent.ScheduledExecutorService; ++import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; + +import static java.nio.file.StandardOpenOption.CREATE; @@ -99,24 +102,50 @@ index 0000000000000000000000000000000000000000..06ca57f0cb319a254ca1511e60f05e5c + private final static ReentrantLock updateLock = new ReentrantLock(); + private static boolean updateTaskStarted = false; + -+ public static void initAutoUpdate() { ++ private static final ScheduledExecutorService autoUpdateExecutor = Executors.newScheduledThreadPool(1); ++ ++ public static void init() { + File workingDirFile = new File(autoUpdateDir); + if (!workingDirFile.exists()) { -+ workingDirFile.mkdir(); ++ if (!workingDirFile.mkdir()) { ++ LeavesLogger.LOGGER.warning("Failed to create working directory: " + autoUpdateDir); ++ } + } + + File corePathFile = new File(corePathFileName); + if (!corePathFile.exists()) { + try { -+ corePathFile.createNewFile(); ++ if (!corePathFile.createNewFile()) { ++ throw new IOException(); ++ } + } catch (IOException e) { -+ e.printStackTrace(); ++ LeavesLogger.LOGGER.severe("Failed to create core path file: " + corePathFileName, e); + } + } + + File leavesUpdateDir = new File(autoUpdateDir + File.separator + "leaves"); + if (!leavesUpdateDir.exists()) { -+ leavesUpdateDir.mkdir(); ++ if (!leavesUpdateDir.mkdir()) { ++ LeavesLogger.LOGGER.warning("Failed to create leaves update directory: " + leavesUpdateDir); ++ } ++ } ++ ++ if (LeavesConfig.autoUpdate) { ++ LocalTime currentTime = LocalTime.now(); ++ long dailyTaskPeriod = 24 * 60 * 60 * 1000; ++ ++ for (String time : LeavesConfig.autoUpdateTime) { ++ try { ++ LocalTime taskTime = LocalTime.of(Integer.parseInt(time.split(":")[0]), Integer.parseInt(time.split(":")[1])); ++ Duration task = Duration.between(currentTime, taskTime); ++ if (task.isNegative()) { ++ task = task.plusDays(1); ++ } ++ autoUpdateExecutor.scheduleAtFixedRate(LeavesUpdateHelper::tryUpdateLeaves, task.toMillis(), dailyTaskPeriod, TimeUnit.MILLISECONDS); ++ } catch (Exception ignored) { ++ LeavesLogger.LOGGER.warning("Illegal auto-update time ignored: " + time); ++ } ++ } + } + } + @@ -125,12 +154,7 @@ index 0000000000000000000000000000000000000000..06ca57f0cb319a254ca1511e60f05e5c + try { + if (!updateTaskStarted) { + updateTaskStarted = true; -+ new Thread(new Runnable() { -+ @Override -+ public void run() { -+ downloadLeaves(); -+ } -+ }).start(); ++ new Thread(LeavesUpdateHelper::downloadLeaves).start(); + } + } finally { + updateLock.unlock(); @@ -142,7 +166,7 @@ index 0000000000000000000000000000000000000000..06ca57f0cb319a254ca1511e60f05e5c + String version = Bukkit.getVersion(); + + if (version.startsWith("null")) { -+ LeavesLogger.LOGGER.info("IDE?"); ++ LeavesLogger.LOGGER.info("IDE? Can not update!"); + updateTaskStarted = false; + return; + } @@ -165,7 +189,7 @@ index 0000000000000000000000000000000000000000..06ca57f0cb319a254ca1511e60f05e5c + Files.deleteIfExists(outFile); + + boolean downloadFlag = false; -+ URL cdnUrl = new URL(buildInfo.cdnUrl); ++ URL cdnUrl = new URI(buildInfo.cdnUrl).toURL(); + try ( + final ReadableByteChannel source = Channels.newChannel(cdnUrl.openStream()); + final FileChannel fileChannel = FileChannel.open(outFile, CREATE, WRITE, TRUNCATE_EXISTING) @@ -177,17 +201,16 @@ index 0000000000000000000000000000000000000000..06ca57f0cb319a254ca1511e60f05e5c + } + + if (!downloadFlag) { -+ URL githubUrl = new URL(buildInfo.githubUrl); ++ URL githubUrl = new URI(buildInfo.githubUrl).toURL(); + try ( + final ReadableByteChannel source = Channels.newChannel(githubUrl.openStream()); + final FileChannel fileChannel = FileChannel.open(outFile, CREATE, WRITE, TRUNCATE_EXISTING) + ) { + fileChannel.transferFrom(source, 0, Long.MAX_VALUE); + } catch (final IOException e) { -+ LeavesLogger.LOGGER.warning("Download " + buildInfo.fileName + " failed."); ++ LeavesLogger.LOGGER.warning("Download " + buildInfo.fileName + " failed.", e); + Files.deleteIfExists(outFile); + updateTaskStarted = false; -+ e.printStackTrace(); + return; + } + } @@ -207,14 +230,14 @@ index 0000000000000000000000000000000000000000..06ca57f0cb319a254ca1511e60f05e5c + try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(corePathFileName))) { + bufferedWriter.write(autoUpdateDir + File.separator + "leaves" + File.separator + buildInfo.fileName); + } catch (IOException e) { -+ e.printStackTrace(); ++ LeavesLogger.LOGGER.warning("Fail to download leaves core", e); + updateTaskStarted = false; + return; + } + + LeavesLogger.LOGGER.info("Leaves update completed, please restart your server."); + } catch (Exception e) { -+ e.printStackTrace(); ++ LeavesLogger.LOGGER.severe("Leaves update failed", e); + } + } else { + LeavesLogger.LOGGER.warning("Can't get build info, stopping update."); @@ -233,7 +256,7 @@ index 0000000000000000000000000000000000000000..06ca57f0cb319a254ca1511e60f05e5c + + return toHexString(md5.digest()).equals(hash); + } catch (Exception e) { -+ e.printStackTrace(); ++ LeavesLogger.LOGGER.warning("Fail to validate file " + file, e); + } + return false; + } @@ -249,14 +272,14 @@ index 0000000000000000000000000000000000000000..06ca57f0cb319a254ca1511e60f05e5c + + private static LeavesBuildInfo getLatestBuildInfo(String mcVersion, String gitHash) { + try { -+ HttpURLConnection connection = (HttpURLConnection) new URL("https://api.leavesmc.org/projects/leaves/versions/" + mcVersion + "/builds/latest").openConnection(); ++ HttpURLConnection connection = (HttpURLConnection) new URI("https://api.leavesmc.org/projects/leaves/versions/" + mcVersion + "/builds/latest").toURL().openConnection(); + connection.connect(); + boolean useApiV2 = false; -+ if (connection.getResponseCode() / 100 != 2){ -+ connection = (HttpURLConnection) new URL("https://api.leavesmc.org/v2/projects/leaves/versions/" + mcVersion + "/builds/latest").openConnection(); ++ if (connection.getResponseCode() / 100 != 2) { ++ connection = (HttpURLConnection) new URI("https://api.leavesmc.org/v2/projects/leaves/versions/" + mcVersion + "/builds/latest").toURL().openConnection(); + connection.connect(); + useApiV2 = true; -+ }; ++ } + if (connection.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) return LeavesBuildInfo.NULL; + try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), Charsets.UTF_8))) { + JsonObject obj = new Gson().fromJson(reader, JsonObject.class); @@ -265,7 +288,7 @@ index 0000000000000000000000000000000000000000..06ca57f0cb319a254ca1511e60f05e5c + if (channel.equals("default")) { + int build = obj.get("build").getAsInt(); + -+ JsonArray changes = obj.get("changes").getAsJsonArray(); ++ JsonArray changes = obj.get("changes").getAsJsonArray(); + boolean needUpdate = true; + for (JsonElement change : changes) { + if (change.getAsJsonObject().get("commit").getAsString().startsWith(gitHash)) { @@ -284,11 +307,11 @@ index 0000000000000000000000000000000000000000..06ca57f0cb319a254ca1511e60f05e5c + return LeavesBuildInfo.NULL; + } + } catch (JsonSyntaxException | NumberFormatException e) { -+ e.printStackTrace(); ++ LeavesLogger.LOGGER.warning("Fail to get latest build info", e); + return LeavesBuildInfo.NULL; + } -+ } catch (IOException e) { -+ e.printStackTrace(); ++ } catch (IOException | URISyntaxException e) { ++ LeavesLogger.LOGGER.warning("Fail to get latest build info", e); + return LeavesBuildInfo.NULL; + } + } diff --git a/patches/server/0103-Force-peaceful-mode-switch.patch b/patches/server/0098-Force-peaceful-mode-switch.patch similarity index 75% rename from patches/server/0103-Force-peaceful-mode-switch.patch rename to patches/server/0098-Force-peaceful-mode-switch.patch index cbac7b9d..7ab4fa3e 100644 --- a/patches/server/0103-Force-peaceful-mode-switch.patch +++ b/patches/server/0098-Force-peaceful-mode-switch.patch @@ -5,12 +5,12 @@ Subject: [PATCH] Force peaceful mode switch diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 6636bdc58be30f89cc52086f6741490fc9cb1653..f4d599bf00a6eaebf2f5edf503c4917df8a6a9cd 100644 +index 48991b885c7cad9c201887b222acad7d700bd03b..86ef1073c47ce430cd94befa8119dcac6a9a72b9 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -75,6 +75,12 @@ public class ServerChunkCache extends ChunkSource { - private final LevelChunk[] lastLoadedChunks = new LevelChunk[4 * 4]; - // Paper end +@@ -129,6 +129,12 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon + } + // Paper end - rewrite chunk system + // Leaves start - peaceful mode switch + public int peacefulModeSwitchTick = org.leavesmc.leaves.LeavesConfig.forcePeacefulMode; @@ -21,12 +21,10 @@ index 6636bdc58be30f89cc52086f6741490fc9cb1653..f4d599bf00a6eaebf2f5edf503c4917d 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) { this.level = world; this.mainThreadProcessor = new ServerChunkCache.MainThreadExecutor(world); -@@ -499,7 +505,21 @@ public class ServerChunkCache extends ChunkSource { - } - // Leaves end - reset ice & snow tick random - gameprofilerfiller.push("filteringLoadedChunks"); -- // Paper - optimise chunk tick iteration -+ +@@ -417,6 +423,21 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon + List list = Lists.newArrayListWithCapacity(this.chunkMap.size()); + Iterator iterator = this.chunkMap.getChunks().iterator(); + + // Leaves start - peaceful mode switch + if (peacefulModeSwitchTick > 0) { + if (this.level.getLevelData().getGameTime() % peacefulModeSwitchTick == 0) { @@ -41,47 +39,40 @@ index 6636bdc58be30f89cc52086f6741490fc9cb1653..f4d599bf00a6eaebf2f5edf503c4917d + peacefulModeSwitchCount = -1; + } + // Leaves end - peaceful mode switch - - // Paper - optimise chunk tick iteration - -@@ -587,10 +607,20 @@ public class ServerChunkCache extends ChunkSource { - } - Util.shuffle(shuffled, this.level.random); - chunkIterator = shuffled.iterator(); -+ } + -+ // Leaves start - peaceful mode switch -+ boolean peacefulModeSwitch = false; -+ if (lastSpawnState != null && peacefulModeSwitchCount != -1) { -+ if (peacefulModeSwitchCount >= NaturalSpawner.globalLimitForCategory(level, net.minecraft.world.entity.MobCategory.MONSTER, lastSpawnState.getSpawnableChunkCount())) { -+ peacefulModeSwitch = true; - } -- try { -- // Paper end - optimise chunk tick iteration -- while (chunkIterator.hasNext()) { -+ } -+ // Leaves end - peaceful mode switch + while (iterator.hasNext()) { + ChunkHolder playerchunk = (ChunkHolder) iterator.next(); + LevelChunk chunk = playerchunk.getTickingChunk(); +@@ -457,6 +478,15 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon + gameprofilerfiller.popPush("spawnAndTick"); + boolean flag = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.players().isEmpty(); // CraftBukkit + ++ // Leaves start - peaceful mode switch ++ boolean peacefulModeSwitch = false; ++ if (lastSpawnState != null && peacefulModeSwitchCount != -1) { ++ if (peacefulModeSwitchCount >= NaturalSpawner.globalLimitForCategory(level, net.minecraft.world.entity.MobCategory.MONSTER, lastSpawnState.getSpawnableChunkCount())) { ++ peacefulModeSwitch = true; ++ } ++ } ++ // Leaves end - peaceful mode switch + -+ try { -+ // Paper end - optimise chunk tick iteration -+ while (chunkIterator.hasNext()) { - LevelChunk chunk1 = chunkIterator.next(); - // Paper end - optimise chunk tick iteration - ChunkPos chunkcoordintpair = chunk1.getPos(); -@@ -621,7 +651,7 @@ public class ServerChunkCache extends ChunkSource { - // Paper end - optimise chunk tick iteration + Util.shuffle(list, this.level.random); + // Paper start - PlayerNaturallySpawnCreaturesEvent + int chunkRange = level.spigotConfig.mobSpawnRange; +@@ -479,7 +509,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon + if (this.level.isNaturalSpawningAllowed(chunkcoordintpair) && this.chunkMap.anyPlayerCloseEnoughForSpawning(chunkcoordintpair)) { chunk1.incrementInhabitedTime(j); - if (spawn && flag && (this.spawnEnemies || this.spawnFriendlies) && this.level.getWorldBorder().isWithinBounds(chunkcoordintpair)) { // Spigot // Paper - optimise chunk tick iteration + if (flag && (this.spawnEnemies || this.spawnFriendlies) && this.level.getWorldBorder().isWithinBounds(chunkcoordintpair) && this.chunkMap.anyPlayerCloseEnoughForSpawning(chunkcoordintpair, true)) { // Spigot - NaturalSpawner.spawnForChunk(this.level, chunk1, spawnercreature_d, this.spawnFriendlies, this.spawnEnemies, flag1); -+ NaturalSpawner.spawnForChunk(this.level, chunk1, spawnercreature_d, this.spawnFriendlies, this.spawnEnemies, flag1, peacefulModeSwitch); // Leaves - peaceful mode switch ++ NaturalSpawner.spawnForChunk(this.level, chunk1, spawnercreature_d, this.spawnFriendlies, this.spawnEnemies, flag1, peacefulModeSwitch); } - if (true || this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) { // Paper - optimise chunk tick iteration + if (this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) { diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index 083a8a7dd99e447904dbac161dd3a1de663d6011..27f064812fd7b8f3feedc9966c9dfc78bfdcc85f 100644 +index a8f792c1ac5740219f014bec5a3875be92b43be9..f4e51c626007252734ac9776c6a5ec3346f6ab09 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -@@ -128,6 +128,12 @@ public final class NaturalSpawner { +@@ -127,6 +127,12 @@ public final class NaturalSpawner { } public static void spawnForChunk(ServerLevel world, LevelChunk chunk, NaturalSpawner.SpawnState info, boolean spawnAnimals, boolean spawnMonsters, boolean rareSpawn) { @@ -94,7 +85,7 @@ index 083a8a7dd99e447904dbac161dd3a1de663d6011..27f064812fd7b8f3feedc9966c9dfc78 world.getProfiler().push("spawner"); MobCategory[] aenumcreaturetype = NaturalSpawner.SPAWNING_CATEGORIES; int i = aenumcreaturetype.length; -@@ -136,6 +142,11 @@ public final class NaturalSpawner { +@@ -135,6 +141,11 @@ public final class NaturalSpawner { for (int j = 0; j < i; ++j) { MobCategory enumcreaturetype = aenumcreaturetype[j]; @@ -107,10 +98,10 @@ index 083a8a7dd99e447904dbac161dd3a1de663d6011..27f064812fd7b8f3feedc9966c9dfc78 boolean spawnThisTick = true; int limit = enumcreaturetype.getMaxInstancesPerChunk(); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 6303760f10af17f1da1d92d6c4dc7dd6f5778f94..105a1fb70a7b869b65617a760b8de1ea86f3571f 100644 +index 8045d6c9398d1c88595da6e41aa1ed27fb6fbad0..2f7de6dc538d147fd80885c1428112b7478b04ca 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -2483,6 +2483,18 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -2372,6 +2372,18 @@ public class CraftWorld extends CraftRegionAccessor implements World { return CraftFeatureFlag.getFromNMS(this.getHandle().enabledFeatures()).stream().map(FeatureFlag.class::cast).collect(Collectors.toUnmodifiableSet()); } @@ -130,18 +121,10 @@ index 6303760f10af17f1da1d92d6c4dc7dd6f5778f94..105a1fb70a7b869b65617a760b8de1ea if (!this.persistentDataContainer.isEmpty()) { c.put("BukkitValues", this.persistentDataContainer.toTagCompound()); diff --git a/src/main/java/org/leavesmc/leaves/command/LeavesCommand.java b/src/main/java/org/leavesmc/leaves/command/LeavesCommand.java -index facd180da9b7025cf7ae192cbe91317ff4b70472..2d871fafff90e2dbc8c4141f92cdb1544ccdce43 100644 +index e964f05c5c0f2d1d9b4c0a3459076e4b95f0f4e8..b28ca267a841f33ba18fff5587a6b0e677dc1ea1 100644 --- a/src/main/java/org/leavesmc/leaves/command/LeavesCommand.java +++ b/src/main/java/org/leavesmc/leaves/command/LeavesCommand.java -@@ -13,6 +13,7 @@ import org.bukkit.plugin.PluginManager; - import org.checkerframework.checker.nullness.qual.Nullable; - import org.jetbrains.annotations.NotNull; - import org.leavesmc.leaves.command.subcommands.ConfigCommand; -+import org.leavesmc.leaves.command.subcommands.PeacefulModeSwitchCommand; - import org.leavesmc.leaves.command.subcommands.UpdateCommand; - - import java.util.ArrayList; -@@ -35,6 +36,7 @@ public final class LeavesCommand extends Command { +@@ -34,6 +34,7 @@ public final class LeavesCommand extends Command { final Map, LeavesSubcommand> commands = new HashMap<>(); commands.put(Set.of("config"), new ConfigCommand()); commands.put(Set.of("update"), new UpdateCommand()); diff --git a/patches/server/0105-Replay-Mod-API.patch b/patches/server/0099-Replay-Mod-API.patch similarity index 92% rename from patches/server/0105-Replay-Mod-API.patch rename to patches/server/0099-Replay-Mod-API.patch index 348014a2..52070ab5 100644 --- a/patches/server/0105-Replay-Mod-API.patch +++ b/patches/server/0099-Replay-Mod-API.patch @@ -5,6 +5,19 @@ Subject: [PATCH] Replay Mod API This patch is Powered by ReplayMod(https://github.com/ReplayMod) +diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java +index 0724bd95143cb5dc69b5f1eb2e67ecd679e09a99..e1d66ac593c6da954ef02def16601dc401421b9f 100644 +--- a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java ++++ b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java +@@ -42,7 +42,7 @@ class PaperEventManager { + } + + // Leaves start - skip bot +- if (event instanceof org.bukkit.event.player.PlayerEvent playerEvent && playerEvent.getPlayer() instanceof org.leavesmc.leaves.entity.Bot) { ++ if (event instanceof org.bukkit.event.player.PlayerEvent playerEvent && (playerEvent.getPlayer() instanceof org.leavesmc.leaves.entity.Bot || playerEvent.getPlayer() instanceof org.leavesmc.leaves.entity.Photographer)) { // Leaves - and photographer + return; + } + // Leaves end - skip bot diff --git a/src/main/java/net/minecraft/commands/arguments/EntityArgument.java b/src/main/java/net/minecraft/commands/arguments/EntityArgument.java index 7976885b902a6ce7d80f31e49448c99452eb9765..6bed90ec5effafbad4aaf82878fe24633891e4e5 100644 --- a/src/main/java/net/minecraft/commands/arguments/EntityArgument.java @@ -18,73 +31,74 @@ index 7976885b902a6ce7d80f31e49448c99452eb9765..6bed90ec5effafbad4aaf82878fe2463 collection.add(player.getGameProfile().getName()); } diff --git a/src/main/java/net/minecraft/commands/arguments/selector/EntitySelector.java b/src/main/java/net/minecraft/commands/arguments/selector/EntitySelector.java -index d78ad5eccd18d89050a486a0c40090a09683bd16..fc7b20df83cd8cb8cdd7d3c2da2bc48a6760858f 100644 +index c8d39e6e1c570c9219f6066da273dc0130920519..96a074281d16a7f64058619da4b102f387c85b28 100644 --- a/src/main/java/net/minecraft/commands/arguments/selector/EntitySelector.java +++ b/src/main/java/net/minecraft/commands/arguments/selector/EntitySelector.java -@@ -122,6 +122,7 @@ public class EntitySelector { +@@ -117,6 +117,7 @@ public class EntitySelector { return this.findPlayers(source); } else if (this.playerName != null) { ServerPlayer entityplayer = source.getServer().getPlayerList().getPlayerByName(this.playerName); + entityplayer = entityplayer instanceof org.leavesmc.leaves.replay.ServerPhotographer ? null : entityplayer; // Leaves - skip photographer - return (List) (entityplayer == null ? Collections.emptyList() : Lists.newArrayList(new ServerPlayer[]{entityplayer})); + return entityplayer == null ? List.of() : List.of(entityplayer); } else if (this.entityUUID != null) { -@@ -137,6 +138,7 @@ public class EntitySelector { +@@ -126,7 +127,7 @@ public class EntitySelector { ServerLevel worldserver = (ServerLevel) iterator.next(); + Entity entity = worldserver.getEntity(this.entityUUID); - entity = worldserver.getEntity(this.entityUUID); -+ entity = entity instanceof org.leavesmc.leaves.replay.ServerPhotographer ? null : entity; // Leaves - skip photographer - } while (entity == null); - - return Lists.newArrayList(new Entity[]{entity}); -@@ -145,7 +147,7 @@ public class EntitySelector { - Predicate predicate = this.getPredicate(vec3d); +- if (entity != null) { ++ if (entity != null && !(entity instanceof org.leavesmc.leaves.replay.ServerPhotographer)) { + if (entity.getType().isEnabled(source.enabledFeatures())) { + return List.of(entity); + } +@@ -142,7 +143,7 @@ public class EntitySelector { if (this.currentEntity) { -- return (List) (source.getEntity() != null && predicate.test(source.getEntity()) ? Lists.newArrayList(new Entity[]{source.getEntity()}) : Collections.emptyList()); -+ return (List) (source.getEntity() != null && !(source.getEntity() instanceof org.leavesmc.leaves.replay.ServerPhotographer) && predicate.test(source.getEntity()) ? Lists.newArrayList(new Entity[]{source.getEntity()}) : Collections.emptyList()); // Leaves - skip photographer + predicate = this.getPredicate(vec3d, axisalignedbb, (FeatureFlagSet) null); +- return source.getEntity() != null && predicate.test(source.getEntity()) ? List.of(source.getEntity()) : List.of(); ++ return source.getEntity() != null && !(source.getEntity() instanceof org.leavesmc.leaves.replay.ServerPhotographer) && predicate.test(source.getEntity()) ? List.of(source.getEntity()) : List.of(); // Leaves - skip photographer } else { - List list = Lists.newArrayList(); - -@@ -160,6 +162,7 @@ public class EntitySelector { - this.addEntities(list, worldserver1, vec3d, predicate); + predicate = this.getPredicate(vec3d, axisalignedbb, source.enabledFeatures()); + List list = new ObjectArrayList(); +@@ -158,6 +159,7 @@ public class EntitySelector { + this.addEntities(list, worldserver1, axisalignedbb, predicate); } } + list.removeIf(entity -> entity instanceof org.leavesmc.leaves.replay.ServerPhotographer); // Leaves - skip photographer return this.sortAndLimit(vec3d, list); } -@@ -200,9 +203,11 @@ public class EntitySelector { +@@ -198,9 +200,11 @@ public class EntitySelector { if (this.playerName != null) { entityplayer = source.getServer().getPlayerList().getPlayerByName(this.playerName); + entityplayer = entityplayer instanceof org.leavesmc.leaves.replay.ServerPhotographer ? null : entityplayer; // Leaves - skip photographer - return (List) (entityplayer == null ? Collections.emptyList() : Lists.newArrayList(new ServerPlayer[]{entityplayer})); + return entityplayer == null ? List.of() : List.of(entityplayer); } else if (this.entityUUID != null) { entityplayer = source.getServer().getPlayerList().getPlayer(this.entityUUID); + entityplayer = entityplayer instanceof org.leavesmc.leaves.replay.ServerPhotographer ? null : entityplayer; // Leaves - skip photographer - return (List) (entityplayer == null ? Collections.emptyList() : Lists.newArrayList(new ServerPlayer[]{entityplayer})); + return entityplayer == null ? List.of() : List.of(entityplayer); } else { Vec3 vec3d = (Vec3) this.position.apply(source.getPosition()); -@@ -214,7 +219,7 @@ public class EntitySelector { +@@ -213,7 +217,7 @@ public class EntitySelector { if (entity instanceof ServerPlayer) { ServerPlayer entityplayer1 = (ServerPlayer) entity; - if (predicate.test(entityplayer1)) { + if (predicate.test(entityplayer1) && !(entityplayer1 instanceof org.leavesmc.leaves.replay.ServerPhotographer)) { // Leaves - skip photographer - return Lists.newArrayList(new ServerPlayer[]{entityplayer1}); + return List.of(entityplayer1); } } -@@ -225,7 +230,7 @@ public class EntitySelector { +@@ -224,7 +228,7 @@ public class EntitySelector { Object object; if (this.isWorldLimited()) { - object = source.getLevel().getPlayers(predicate, i); + object = source.getLevel().getPlayers((entityplayer3 -> !(entityplayer3 instanceof org.leavesmc.leaves.replay.ServerPhotographer) && predicate.test(entityplayer3)), i); // Leaves - skip photographer } else { - object = Lists.newArrayList(); + object = new ObjectArrayList(); Iterator iterator = source.getServer().getPlayerList().getPlayers().iterator(); -@@ -233,7 +238,7 @@ public class EntitySelector { +@@ -232,7 +236,7 @@ public class EntitySelector { while (iterator.hasNext()) { ServerPlayer entityplayer2 = (ServerPlayer) iterator.next(); @@ -94,10 +108,10 @@ index d78ad5eccd18d89050a486a0c40090a09683bd16..fc7b20df83cd8cb8cdd7d3c2da2bc48a if (((List) object).size() >= i) { return (List) object; diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 658ac73c319683cf8d74d4af8e2a3fca418bd71c..8bb6f9d26c8a24638ed64e8726b3b11dcccde9c8 100644 +index 1a5c7e8473c8d183080f6995c2c76487d7ff5a68..ebbb18d2e741e535dbfeca364d0f2d0d27a96c7d 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1659,7 +1659,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop !playerList.isOp(player.getGameProfile())) .map(player -> player.getGameProfile().getName()), diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index c4aac957906ff3bf28b29e58e30decc608562e6a..975062e67278614220eab0c301019a235c7953b7 100644 +index fedeaf43f7b61a7ca6dc2a99bb76a47f4c640a1d..34b0a606a0bb2073b3ce151a2fdeeb3c7c9f2acb 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -126,6 +126,7 @@ import org.bukkit.event.player.PlayerSpawnChangeEvent; +@@ -124,6 +124,7 @@ import org.bukkit.event.player.PlayerSpawnChangeEvent; // CraftBukkit end import org.leavesmc.leaves.bot.ServerBot; @@ -144,7 +158,7 @@ index c4aac957906ff3bf28b29e58e30decc608562e6a..975062e67278614220eab0c301019a23 public abstract class PlayerList { -@@ -158,6 +159,7 @@ public abstract class PlayerList { +@@ -156,6 +157,7 @@ public abstract class PlayerList { private boolean allowCommandsForAllPlayers; private static final boolean ALLOW_LOGOUTIVATOR = false; private int sendAllPlayerInfoIn; @@ -152,7 +166,7 @@ index c4aac957906ff3bf28b29e58e30decc608562e6a..975062e67278614220eab0c301019a23 // CraftBukkit start private CraftServer cserver; -@@ -184,6 +186,120 @@ public abstract class PlayerList { +@@ -182,6 +184,120 @@ public abstract class PlayerList { } abstract public void loadAndSaveFiles(); // Paper - fix converting txt to json file; moved from DedicatedPlayerList constructor @@ -273,7 +287,7 @@ index c4aac957906ff3bf28b29e58e30decc608562e6a..975062e67278614220eab0c301019a23 public void placeNewPlayer(Connection connection, ServerPlayer player, CommonListenerCookie clientData) { player.isRealPlayer = true; // Paper player.loginTime = System.currentTimeMillis(); // Paper - Replace OfflinePlayer#getLastPlayed -@@ -330,6 +446,7 @@ public abstract class PlayerList { +@@ -328,6 +444,7 @@ public abstract class PlayerList { // entityplayer.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(this.players)); // CraftBukkit - replaced with loop below this.players.add(player); @@ -281,7 +295,7 @@ index c4aac957906ff3bf28b29e58e30decc608562e6a..975062e67278614220eab0c301019a23 this.playersByName.put(player.getScoreboardName().toLowerCase(java.util.Locale.ROOT), player); // Spigot this.playersByUUID.put(player.getUUID(), player); // this.broadcastAll(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(entityplayer))); // CraftBukkit - replaced with loop below -@@ -401,6 +518,12 @@ public abstract class PlayerList { +@@ -399,6 +516,12 @@ public abstract class PlayerList { continue; } @@ -294,7 +308,7 @@ index c4aac957906ff3bf28b29e58e30decc608562e6a..975062e67278614220eab0c301019a23 onlinePlayers.add(entityplayer1); // Paper - Use single player info update packet on join } // Paper start - Use single player info update packet on join -@@ -611,6 +734,43 @@ public abstract class PlayerList { +@@ -602,6 +725,43 @@ public abstract class PlayerList { } @@ -338,7 +352,7 @@ index c4aac957906ff3bf28b29e58e30decc608562e6a..975062e67278614220eab0c301019a23 public net.kyori.adventure.text.Component remove(ServerPlayer entityplayer) { // CraftBukkit - return string // Paper - return Component // Paper start - Fix kick event leave message not being sent return this.remove(entityplayer, net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, io.papermc.paper.configuration.GlobalConfiguration.get().messages.useDisplayNameInQuitMessage ? entityplayer.getBukkitEntity().displayName() : io.papermc.paper.adventure.PaperAdventure.asAdventure(entityplayer.getDisplayName()))); -@@ -679,6 +839,7 @@ public abstract class PlayerList { +@@ -670,6 +830,7 @@ public abstract class PlayerList { entityplayer.retireScheduler(); // Paper - Folia schedulers entityplayer.getAdvancements().stopListening(); this.players.remove(entityplayer); @@ -346,7 +360,7 @@ index c4aac957906ff3bf28b29e58e30decc608562e6a..975062e67278614220eab0c301019a23 this.playersByName.remove(entityplayer.getScoreboardName().toLowerCase(java.util.Locale.ROOT)); // Spigot this.server.getCustomBossEvents().onPlayerDisconnect(entityplayer); UUID uuid = entityplayer.getUUID(); -@@ -773,7 +934,7 @@ public abstract class PlayerList { +@@ -764,7 +925,7 @@ public abstract class PlayerList { event.disallow(PlayerLoginEvent.Result.KICK_BANNED, io.papermc.paper.adventure.PaperAdventure.asAdventure(ichatmutablecomponent)); // Paper - Adventure } else { // return this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameprofile) ? IChatBaseComponent.translatable("multiplayer.disconnect.server_full") : null; @@ -356,10 +370,10 @@ index c4aac957906ff3bf28b29e58e30decc608562e6a..975062e67278614220eab0c301019a23 } } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index a75f5cf9dc6044a3778106adf0c325c1a563e302..98f10278b14d540e81703ee1330ddd7c6ed5f194 100644 +index d7f373bae76e14ce20515ec22bf48c40a2054f92..a58a495d35c5963df7947b42c4000a0f6ba28534 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -308,6 +308,7 @@ public final class CraftServer implements Server { +@@ -310,6 +310,7 @@ public final class CraftServer implements Server { private final io.papermc.paper.logging.SysoutCatcher sysoutCatcher = new io.papermc.paper.logging.SysoutCatcher(); // Paper private final io.papermc.paper.potion.PaperPotionBrewer potionBrewer; // Paper - Custom Potion Mixes private final org.leavesmc.leaves.entity.CraftBotManager botManager = new org.leavesmc.leaves.entity.CraftBotManager(); // Leaves @@ -367,7 +381,7 @@ index a75f5cf9dc6044a3778106adf0c325c1a563e302..98f10278b14d540e81703ee1330ddd7c // Paper start - Folia region threading API private final io.papermc.paper.threadedregions.scheduler.FallbackRegionScheduler regionizedScheduler = new io.papermc.paper.threadedregions.scheduler.FallbackRegionScheduler(); -@@ -390,7 +391,7 @@ public final class CraftServer implements Server { +@@ -392,7 +393,7 @@ public final class CraftServer implements Server { public CraftServer(DedicatedServer console, PlayerList playerList) { this.console = console; this.playerList = (DedicatedPlayerList) playerList; @@ -376,7 +390,7 @@ index a75f5cf9dc6044a3778106adf0c325c1a563e302..98f10278b14d540e81703ee1330ddd7c @Override public CraftPlayer apply(ServerPlayer player) { return player.getBukkitEntity(); -@@ -3299,4 +3300,11 @@ public final class CraftServer implements Server { +@@ -3224,4 +3225,11 @@ public final class CraftServer implements Server { return botManager; } // Leaves end - Bot API @@ -389,31 +403,22 @@ index a75f5cf9dc6044a3778106adf0c325c1a563e302..98f10278b14d540e81703ee1330ddd7c + // Leaves end - replay mod api } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index ff4563be301d237bb2f431e424687891e95b2b4f..22f29b760bc569f4ca38617e147c699689a1ddf1 100644 +index a007beca6c00bce4514889935b1762a37826c75a..02881fdb1a3c96466618149c288094b755eafb4d 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -59,6 +59,8 @@ import org.leavesmc.leaves.bot.ServerBot; - import org.leavesmc.leaves.entity.CraftBot; - - import net.md_5.bungee.api.chat.BaseComponent; // Spigot -+import org.leavesmc.leaves.entity.CraftPhotographer; -+import org.leavesmc.leaves.replay.ServerPhotographer; - - public abstract class CraftEntity implements org.bukkit.entity.Entity { - private static PermissibleBase perm; -@@ -95,6 +97,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -95,6 +95,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { } - if (entity instanceof ServerBot) { return new CraftBot(server, (ServerBot) entity); } -+ if (entity instanceof ServerPhotographer) { return new CraftPhotographer(server, (ServerPhotographer) entity); } + if (entity instanceof org.leavesmc.leaves.bot.ServerBot bot) { return new org.leavesmc.leaves.entity.CraftBot(server, bot); } ++ if (entity instanceof org.leavesmc.leaves.replay.ServerPhotographer photographer) { return new org.leavesmc.leaves.entity.CraftPhotographer(server, photographer); } // Special case complex part, since there is no extra entity type for them if (entity instanceof EnderDragonPart complexPart) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 40155cc70ba959eea8011626a30e26f44298c99d..a265dd6af9a58d1f71ea464a88c787749c79a111 100644 +index 7eea190ce8a62960ecc42ff56a4ef71b754184fb..386d9d342cd63ab2bbbb218d1f4a10308e1ea032 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2223,7 +2223,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2242,7 +2242,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public boolean canSee(Player player) { @@ -1031,7 +1036,7 @@ index 0000000000000000000000000000000000000000..8978fe0c7ed092334618e27892f940ee +} diff --git a/src/main/java/org/leavesmc/leaves/replay/ReplayFile.java b/src/main/java/org/leavesmc/leaves/replay/ReplayFile.java new file mode 100644 -index 0000000000000000000000000000000000000000..5076b552816d7eae3a1c89fff488de63414eb5ee +index 0000000000000000000000000000000000000000..331ced8677b28827c277c64ae0b31d4d9ecd1d9b --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/replay/ReplayFile.java @@ -0,0 +1,199 @@ @@ -1118,7 +1123,7 @@ index 0000000000000000000000000000000000000000..5076b552816d7eae3a1c89fff488de63 + ConnectionProtocol.STATUS, StatusProtocols.CLIENTBOUND, + ConnectionProtocol.LOGIN, LoginProtocols.CLIENTBOUND, + ConnectionProtocol.CONFIGURATION, ConfigurationProtocols.CLIENTBOUND, -+ ConnectionProtocol.PLAY, GameProtocols.CLIENTBOUND.bind(RegistryFriendlyByteBuf.decorator(MinecraftServer.getServer().registryAccess())) ++ ConnectionProtocol.PLAY, GameProtocols.CLIENTBOUND_TEMPLATE.bind(RegistryFriendlyByteBuf.decorator(MinecraftServer.getServer().registryAccess())) + ); + } + diff --git a/patches/server/0107-Leaves-I18n.patch b/patches/server/0100-Leaves-I18n.patch similarity index 99% rename from patches/server/0107-Leaves-I18n.patch rename to patches/server/0100-Leaves-I18n.patch index ed0ef16a..c253920d 100644 --- a/patches/server/0107-Leaves-I18n.patch +++ b/patches/server/0100-Leaves-I18n.patch @@ -51,10 +51,10 @@ index a9bca1d10553f1406f7dbce3f7c40378b6abdc10..aa7f4f738c637ffc3d50f2bdb5ee61ff Builder builder = ImmutableMap.builder(); BiConsumer biConsumer = builder::put; diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index f240a9d90ec469a99d3d8b82cfa3fcb5d0e78057..7148b5c8f4b63649ef8f89963b6bd591fd1a97bf 100644 +index 2068081a072a0298e95fe40d67e020bf2331f093..59df97cf46923d3b84179a9407e210de9a2f3658 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -@@ -234,6 +234,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -238,6 +238,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface org.leavesmc.leaves.LeavesConfig.init((java.io.File) options.valueOf("leaves-settings")); // Leaves - Server Config System.setProperty("spark.serverconfigs.extra", "leaves.yml"); // Leaves - spark config diff --git a/patches/server/0108-Fix-minecraft-hopper-not-work-without-player.patch b/patches/server/0101-Fix-minecraft-hopper-not-work-without-player.patch similarity index 100% rename from patches/server/0108-Fix-minecraft-hopper-not-work-without-player.patch rename to patches/server/0101-Fix-minecraft-hopper-not-work-without-player.patch diff --git a/patches/server/0102-RNG-Fishing.patch b/patches/server/0102-RNG-Fishing.patch new file mode 100644 index 00000000..2d4155d5 --- /dev/null +++ b/patches/server/0102-RNG-Fishing.patch @@ -0,0 +1,19 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: violetc <58360096+s-yh-china@users.noreply.github.com> +Date: Mon, 4 Sep 2023 22:09:10 +0800 +Subject: [PATCH] RNG Fishing + + +diff --git a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java +index 0e00f59a8962dd6356d483ef5be3209a3a410008..1c556f9cca2d21c3bdb49cb22263a597c6a8680f 100644 +--- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java ++++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java +@@ -523,7 +523,7 @@ public class FishingHook extends Projectile { + } else if (this.nibble > 0) { + LootParams lootparams = (new LootParams.Builder((ServerLevel) this.level())).withParameter(LootContextParams.ORIGIN, this.position()).withParameter(LootContextParams.TOOL, usedItem).withParameter(LootContextParams.THIS_ENTITY, this).withLuck((float) this.luck + entityhuman.getLuck()).create(LootContextParamSets.FISHING); + LootTable loottable = this.level().getServer().reloadableRegistries().getLootTable(BuiltInLootTables.FISHING); +- List list = loottable.getRandomItems(lootparams); ++ List list = org.leavesmc.leaves.LeavesConfig.rngFishing ? loottable.getRandomItems(lootparams, this.random) : loottable.getRandomItems(lootparams); // Leaves - world random + + CriteriaTriggers.FISHING_ROD_HOOKED.trigger((ServerPlayer) entityhuman, usedItem, this, list); + Iterator iterator = list.iterator(); diff --git a/patches/server/0109-Wool-Hopper-Counter.patch b/patches/server/0103-Wool-Hopper-Counter.patch similarity index 88% rename from patches/server/0109-Wool-Hopper-Counter.patch rename to patches/server/0103-Wool-Hopper-Counter.patch index 12134781..368e9fdc 100644 --- a/patches/server/0109-Wool-Hopper-Counter.patch +++ b/patches/server/0103-Wool-Hopper-Counter.patch @@ -18,33 +18,11 @@ index e314f36951e9ac15c57137e24fce8c410373130a..dd232d9e86c5bf03cfb4597d3291a172 @Nullable public ItemStack[] itemStacks; @Nullable -diff --git a/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java b/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java -index a31326e24cb68472c81cd781c5e3041772712862..f0422a70ef79c837405284fd42a74af6c57959de 100644 ---- a/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java -+++ b/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java -@@ -45,7 +45,7 @@ public class RecipeManager extends SimpleJsonResourceReloadListener { - private static final Logger LOGGER = LogUtils.getLogger(); - private final HolderLookup.Provider registries; - public Multimap, RecipeHolder> byType = ImmutableMultimap.of(); -- private Map> byName = ImmutableMap.of(); -+ public Map> byName = ImmutableMap.of(); // Leaves - hopper counter - private boolean hasErrors; - - public RecipeManager(HolderLookup.Provider registryLookup) { diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java -index b08b7ffbcfbc6a12d74cadf878fd069f7a1345cb..741ab2ffc8e4f40f43e24fed3b6d55580a3fdaca 100644 +index 82e8b560ee24ad262df4ad073e66cd129ccb7bb8..76b3e6622aae61c058af2a0e84fa03082e968c79 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java -@@ -202,7 +202,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen - - final int fullState = getFullState(blockEntity); // Paper - Perf: Optimize Hoppers - if (fullState != HOPPER_EMPTY) { // Paper - Perf: Optimize Hoppers -- flag = HopperBlockEntity.ejectItems(world, pos, blockEntity); -+ flag = HopperBlockEntity.ejectItems(world, pos, blockEntity); // Leaves - hopper counter - } - - if (fullState != HOPPER_IS_FULL || flag) { // Paper - Perf: Optimize Hoppers -@@ -432,7 +432,14 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen +@@ -447,7 +447,14 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen private static final java.util.function.BiPredicate IS_EMPTY_TEST = (itemstack, i) -> itemstack.isEmpty(); // Paper end - Perf: Optimize Hoppers @@ -59,7 +37,7 @@ index b08b7ffbcfbc6a12d74cadf878fd069f7a1345cb..741ab2ffc8e4f40f43e24fed3b6d5558 Container iinventory = HopperBlockEntity.getAttachedContainer(world, pos, blockEntity); if (iinventory == null) { -@@ -491,6 +498,23 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen +@@ -506,6 +513,23 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen } } @@ -84,18 +62,10 @@ index b08b7ffbcfbc6a12d74cadf878fd069f7a1345cb..741ab2ffc8e4f40f43e24fed3b6d5558 if (inventory instanceof WorldlyContainer iworldinventory) { return iworldinventory.getSlotsForFace(side); diff --git a/src/main/java/org/leavesmc/leaves/command/LeavesCommand.java b/src/main/java/org/leavesmc/leaves/command/LeavesCommand.java -index 2d871fafff90e2dbc8c4141f92cdb1544ccdce43..31473e5a257276d1feb37e98cf52477cd9523712 100644 +index b28ca267a841f33ba18fff5587a6b0e677dc1ea1..f9a1f2d7f319c22178c2254347bcdc15f19badd9 100644 --- a/src/main/java/org/leavesmc/leaves/command/LeavesCommand.java +++ b/src/main/java/org/leavesmc/leaves/command/LeavesCommand.java -@@ -13,6 +13,7 @@ import org.bukkit.plugin.PluginManager; - import org.checkerframework.checker.nullness.qual.Nullable; - import org.jetbrains.annotations.NotNull; - import org.leavesmc.leaves.command.subcommands.ConfigCommand; -+import org.leavesmc.leaves.command.subcommands.CounterCommand; - import org.leavesmc.leaves.command.subcommands.PeacefulModeSwitchCommand; - import org.leavesmc.leaves.command.subcommands.UpdateCommand; - -@@ -37,6 +38,7 @@ public final class LeavesCommand extends Command { +@@ -35,6 +35,7 @@ public final class LeavesCommand extends Command { commands.put(Set.of("config"), new ConfigCommand()); commands.put(Set.of("update"), new UpdateCommand()); commands.put(Set.of("peaceful"), new PeacefulModeSwitchCommand()); @@ -232,10 +202,10 @@ index 0000000000000000000000000000000000000000..358780d37600220d132ae8e2e6c594fc +} diff --git a/src/main/java/org/leavesmc/leaves/util/HopperCounter.java b/src/main/java/org/leavesmc/leaves/util/HopperCounter.java new file mode 100644 -index 0000000000000000000000000000000000000000..1551feb2e2787ccf15dbe6a027e7fff21f762c7a +index 0000000000000000000000000000000000000000..1a83b3918bc040ab32e648b54b498e9a556c17a3 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/util/HopperCounter.java -@@ -0,0 +1,334 @@ +@@ -0,0 +1,338 @@ +package org.leavesmc.leaves.util; + +import it.unimi.dsi.fastutil.objects.Object2LongLinkedOpenHashMap; @@ -269,6 +239,7 @@ index 0000000000000000000000000000000000000000..1551feb2e2787ccf15dbe6a027e7fff2 +import net.minecraft.world.level.material.MapColor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; ++import org.leavesmc.leaves.LeavesConfig; + +import java.util.ArrayList; +import java.util.Arrays; @@ -277,8 +248,6 @@ index 0000000000000000000000000000000000000000..1551feb2e2787ccf15dbe6a027e7fff2 +import java.util.EnumMap; +import java.util.List; +import java.util.Map; -+import java.util.Objects; -+import java.util.stream.Collectors; + +import static java.util.Map.entry; + @@ -418,6 +387,7 @@ index 0000000000000000000000000000000000000000..1551feb2e2787ccf15dbe6a027e7fff2 + entry(Items.SPIDER_EYE, Blocks.NETHERRACK), + entry(Items.GUNPOWDER, Blocks.GRAY_WOOL), + entry(Items.TURTLE_SCUTE, Blocks.LIME_WOOL), ++ entry(Items.ARMADILLO_SCUTE, Blocks.ANCIENT_DEBRIS), + entry(Items.FEATHER, Blocks.WHITE_WOOL), + entry(Items.FLINT, Blocks.BLACK_WOOL), + entry(Items.LEATHER, Blocks.SPRUCE_PLANKS), @@ -515,17 +485,21 @@ index 0000000000000000000000000000000000000000..1551feb2e2787ccf15dbe6a027e7fff2 + } + + public static List> getAllMatching(@NotNull RecipeManager manager, RecipeType type, ResourceLocation output, final RegistryAccess registryAccess) { -+ Map> typeRecipes = manager.byName; // Leaves - hopper counter -+ if (typeRecipes == null) { -+ return Collections.emptyList(); ++ RecipeHolder recipe = manager.byName.get(output); ++ if (recipe != null && recipe.value().getType().equals(type)) { ++ return List.of(recipe.value()); + } -+ if (typeRecipes.containsKey(output)) { -+ return Collections.singletonList(typeRecipes.get(output).value()); ++ if (!manager.byType.containsKey(type)) { ++ return List.of(); + } -+ final Registry regs = registryAccess.registryOrThrow(Registries.ITEM); -+ return typeRecipes.values().stream() -+ .filter(r -> Objects.equals(regs.getKey(r.value().getResultItem(registryAccess).getItem()), output)) -+ .map(RecipeHolder::value).collect(Collectors.toList()); ++ ++ Collection> typeRecipes = manager.byType.get(type); ++ Registry regs = registryAccess.registryOrThrow(Registries.ITEM); ++ Item item = regs.get(output); ++ return typeRecipes.stream() ++ .>map(RecipeHolder::value) ++ .filter(r -> r.getResultItem(registryAccess).getItem() == item) ++ .toList(); + } + + public static List> getRecipeStacks(@NotNull Ingredient ingredient) { @@ -567,7 +541,7 @@ index 0000000000000000000000000000000000000000..1551feb2e2787ccf15dbe6a027e7fff2 + } + + public static boolean isEnabled() { -+ return enabled; ++ return LeavesConfig.hopperCounter && enabled; + } +} diff --git a/src/main/java/org/leavesmc/leaves/util/WoolUtils.java b/src/main/java/org/leavesmc/leaves/util/WoolUtils.java diff --git a/patches/server/0104-Add-Leaves-Auto-Update.patch b/patches/server/0104-Add-Leaves-Auto-Update.patch deleted file mode 100644 index 47f0dadf..00000000 --- a/patches/server/0104-Add-Leaves-Auto-Update.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: MC_XiaoHei -Date: Sun, 6 Aug 2023 09:57:53 +0800 -Subject: [PATCH] Add Leaves Auto Update - - -diff --git a/src/main/java/org/leavesmc/leaves/util/LeavesUpdateHelper.java b/src/main/java/org/leavesmc/leaves/util/LeavesUpdateHelper.java -index 06ca57f0cb319a254ca1511e60f05e5ca151beea..061869a93704e9605378468af8343c64fa009580 100644 ---- a/src/main/java/org/leavesmc/leaves/util/LeavesUpdateHelper.java -+++ b/src/main/java/org/leavesmc/leaves/util/LeavesUpdateHelper.java -@@ -7,8 +7,11 @@ import com.google.gson.JsonElement; - import com.google.gson.JsonObject; - import com.google.gson.JsonSyntaxException; - import net.minecraft.Util; -+import net.minecraft.world.level.gameevent.vibrations.VibrationSystem; - import org.bukkit.Bukkit; -+import org.checkerframework.checker.units.qual.C; - import org.jetbrains.annotations.NotNull; -+import org.leavesmc.leaves.LeavesConfig; - import org.leavesmc.leaves.LeavesLogger; - - import java.io.BufferedReader; -@@ -26,6 +29,12 @@ import java.nio.channels.ReadableByteChannel; - import java.nio.file.Files; - import java.nio.file.Path; - import java.security.MessageDigest; -+import java.time.Duration; -+import java.time.LocalTime; -+import java.util.*; -+import java.util.concurrent.Executors; -+import java.util.concurrent.ScheduledExecutorService; -+import java.util.concurrent.TimeUnit; - import java.util.concurrent.locks.ReentrantLock; - - import static java.nio.file.StandardOpenOption.CREATE; -@@ -40,7 +49,9 @@ public class LeavesUpdateHelper { - private final static ReentrantLock updateLock = new ReentrantLock(); - private static boolean updateTaskStarted = false; - -- public static void initAutoUpdate() { -+ private static final ScheduledExecutorService autoUpdateExecutor = Executors.newScheduledThreadPool(1); -+ -+ public static void init() { - File workingDirFile = new File(autoUpdateDir); - if (!workingDirFile.exists()) { - workingDirFile.mkdir(); -@@ -59,6 +70,24 @@ public class LeavesUpdateHelper { - if (!leavesUpdateDir.exists()) { - leavesUpdateDir.mkdir(); - } -+ -+ if (LeavesConfig.autoUpdate) { -+ LocalTime currentTime = LocalTime.now(); -+ long dailyTaskPeriod = 24 * 60 * 60 * 1000; -+ -+ for (String time : LeavesConfig.autoUpdateTime) { -+ try { -+ LocalTime taskTime = LocalTime.of(Integer.parseInt(time.split(":")[0]), Integer.parseInt(time.split(":")[1])); -+ Duration task = Duration.between(currentTime, taskTime); -+ if (task.isNegative()) { -+ task = task.plusDays(1); -+ } -+ autoUpdateExecutor.scheduleAtFixedRate(LeavesUpdateHelper::tryUpdateLeaves, task.toMillis(), dailyTaskPeriod, TimeUnit.MILLISECONDS); -+ } catch (Exception ignored){ -+ LeavesLogger.LOGGER.warning("Illegal auto-update time ignored: " + time); -+ } -+ } -+ } - } - - public static void tryUpdateLeaves() { -@@ -66,12 +95,7 @@ public class LeavesUpdateHelper { - try { - if (!updateTaskStarted) { - updateTaskStarted = true; -- new Thread(new Runnable() { -- @Override -- public void run() { -- downloadLeaves(); -- } -- }).start(); -+ new Thread(LeavesUpdateHelper::downloadLeaves).start(); - } - } finally { - updateLock.unlock(); -@@ -83,7 +107,7 @@ public class LeavesUpdateHelper { - String version = Bukkit.getVersion(); - - if (version.startsWith("null")) { -- LeavesLogger.LOGGER.info("IDE?"); -+ LeavesLogger.LOGGER.info("IDE? Can not update!"); - updateTaskStarted = false; - return; - } diff --git a/patches/server/0111-Leaves-Reload-Command.patch b/patches/server/0104-Leaves-Reload-Command.patch similarity index 78% rename from patches/server/0111-Leaves-Reload-Command.patch rename to patches/server/0104-Leaves-Reload-Command.patch index 61d441a5..6c383b40 100644 --- a/patches/server/0111-Leaves-Reload-Command.patch +++ b/patches/server/0104-Leaves-Reload-Command.patch @@ -5,18 +5,10 @@ Subject: [PATCH] Leaves Reload Command diff --git a/src/main/java/org/leavesmc/leaves/command/LeavesCommand.java b/src/main/java/org/leavesmc/leaves/command/LeavesCommand.java -index 31473e5a257276d1feb37e98cf52477cd9523712..0f958ccafda1490f1acfc8089c47f6b7de7d4722 100644 +index f9a1f2d7f319c22178c2254347bcdc15f19badd9..139c807916ec1be7bf993b34f52343f12eea888a 100644 --- a/src/main/java/org/leavesmc/leaves/command/LeavesCommand.java +++ b/src/main/java/org/leavesmc/leaves/command/LeavesCommand.java -@@ -15,6 +15,7 @@ import org.jetbrains.annotations.NotNull; - import org.leavesmc.leaves.command.subcommands.ConfigCommand; - import org.leavesmc.leaves.command.subcommands.CounterCommand; - import org.leavesmc.leaves.command.subcommands.PeacefulModeSwitchCommand; -+import org.leavesmc.leaves.command.subcommands.ReloadCommand; - import org.leavesmc.leaves.command.subcommands.UpdateCommand; - - import java.util.ArrayList; -@@ -39,6 +40,7 @@ public final class LeavesCommand extends Command { +@@ -36,6 +36,7 @@ public final class LeavesCommand extends Command { commands.put(Set.of("update"), new UpdateCommand()); commands.put(Set.of("peaceful"), new PeacefulModeSwitchCommand()); commands.put(Set.of("counter"), new CounterCommand()); diff --git a/patches/server/0112-Spider-jockeys-drop-gapples.patch b/patches/server/0105-Spider-jockeys-drop-gapples.patch similarity index 93% rename from patches/server/0112-Spider-jockeys-drop-gapples.patch rename to patches/server/0105-Spider-jockeys-drop-gapples.patch index cf9c7dda..fa5be2fe 100644 --- a/patches/server/0112-Spider-jockeys-drop-gapples.patch +++ b/patches/server/0105-Spider-jockeys-drop-gapples.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Spider jockeys drop gapples diff --git a/src/main/java/net/minecraft/world/entity/monster/Spider.java b/src/main/java/net/minecraft/world/entity/monster/Spider.java -index fa0316e9d2a4cf213982994dc8bf310299cca984..27c37f3152fe2317ae5dcee154267274c82aaa7c 100644 +index e675f1e3e5b6f9e1aa0d928ebb9abe76458edb38..902119c7501e98b2a4a67504216ad2cded138f87 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Spider.java +++ b/src/main/java/net/minecraft/world/entity/monster/Spider.java @@ -145,6 +145,18 @@ public class Spider extends Monster { diff --git a/patches/server/0106-Fix-vehicle-teleport-by-end-gateway.patch b/patches/server/0106-Fix-vehicle-teleport-by-end-gateway.patch deleted file mode 100644 index fa42cfb7..00000000 --- a/patches/server/0106-Fix-vehicle-teleport-by-end-gateway.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: violetc <58360096+s-yh-china@users.noreply.github.com> -Date: Tue, 15 Aug 2023 22:40:42 +0800 -Subject: [PATCH] Fix vehicle teleport by end gateway - - -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 4af071ff2d0a29ad9315e1076436f70f848c89b8..8809755d0e3e6199e2db6c061e53375d17753b70 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 -@@ -215,7 +215,7 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity { - - entity1.setPortalCooldown(); - ((ServerPlayer) entity1).connection.teleport(teleEvent.getTo()); -- entity1.teleportPassengers(); // Paper - teleport passengers as well, preventing invisible passengers post teleport. -+ // entity1.teleportPassengers(); // Paper - teleport passengers as well, preventing invisible passengers post teleport. // Leaves - vanilla - TheEndGatewayBlockEntity.triggerCooldown(world, pos, state, blockEntity); // CraftBukkit - call at end of method - return; - diff --git a/patches/server/0113-Force-Void-Trade.patch b/patches/server/0106-Force-Void-Trade.patch similarity index 73% rename from patches/server/0113-Force-Void-Trade.patch rename to patches/server/0106-Force-Void-Trade.patch index 047fb96d..a82dd48e 100644 --- a/patches/server/0113-Force-Void-Trade.patch +++ b/patches/server/0106-Force-Void-Trade.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Force Void Trade diff --git a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java -index d323cf157f2a910916baa9ce3f7e5bc81648c47d..308638bb5dc12ac11eb7a44d05647403184f38d6 100644 +index 915b44434eebdd200bef38b4e5e8fcdf5cdcf5ad..04ffe95c123bc595d06f1055d4da4a91844334ae 100644 --- a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java +++ b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java @@ -66,6 +66,7 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa @@ -16,7 +16,7 @@ index d323cf157f2a910916baa9ce3f7e5bc81648c47d..308638bb5dc12ac11eb7a44d05647403 public AbstractVillager(EntityType type, Level world) { super(type, world); -@@ -143,7 +144,13 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa +@@ -156,7 +157,13 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa @Override public void processTrade(MerchantOffer recipe, @Nullable io.papermc.paper.event.player.PlayerPurchaseEvent event) { // The MerchantRecipe passed in here is the one set by the PlayerPurchaseEvent if (event == null || event.willIncreaseTradeUses()) { @@ -31,7 +31,7 @@ index d323cf157f2a910916baa9ce3f7e5bc81648c47d..308638bb5dc12ac11eb7a44d05647403 } if (event == null || event.isRewardingExp()) { this.rewardTradeXp(recipe); -@@ -155,7 +162,7 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa +@@ -168,7 +175,7 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa @Override public void notifyTrade(MerchantOffer offer) { // offer.increaseUses(); // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent @@ -40,7 +40,7 @@ index d323cf157f2a910916baa9ce3f7e5bc81648c47d..308638bb5dc12ac11eb7a44d05647403 // this.rewardTradeXp(offer); // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent if (this.tradingPlayer instanceof ServerPlayer) { CriteriaTriggers.TRADE.trigger((ServerPlayer) this.tradingPlayer, this, offer.getResult()); -@@ -173,7 +180,7 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa +@@ -186,7 +193,7 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa @Override public void notifyTradeUpdated(ItemStack stack) { if (!this.level().isClientSide && this.ambientSoundTime > -this.getAmbientSoundInterval() + 20) { @@ -49,7 +49,7 @@ index d323cf157f2a910916baa9ce3f7e5bc81648c47d..308638bb5dc12ac11eb7a44d05647403 this.makeSound(this.getTradeUpdatedSound(!stack.isEmpty())); } -@@ -228,6 +235,12 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa +@@ -243,6 +250,12 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa } protected void stopTrading() { @@ -62,7 +62,7 @@ index d323cf157f2a910916baa9ce3f7e5bc81648c47d..308638bb5dc12ac11eb7a44d05647403 this.setTradingPlayer((Player) null); } -@@ -307,4 +320,10 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa +@@ -322,4 +335,10 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa public boolean isClientSide() { return this.level().isClientSide; } @@ -74,7 +74,7 @@ index d323cf157f2a910916baa9ce3f7e5bc81648c47d..308638bb5dc12ac11eb7a44d05647403 + // Leaves end - force void trade } 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 6cac189cf6e0bef2f0ea8c0dbadb0f417171a05e..45be97d79377f028264e7828e929d37893ebdfb5 100644 +index 18642b4e43d0725690be44b53bbddb6d4486e5f1..8a21e03c012b047eef3948e10bdb23766194b670 100644 --- a/src/main/java/net/minecraft/world/entity/npc/Villager.java +++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java @@ -348,6 +348,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler @@ -85,7 +85,7 @@ index 6cac189cf6e0bef2f0ea8c0dbadb0f417171a05e..45be97d79377f028264e7828e929d378 this.updateSpecialPrices(customer); this.setTradingPlayer(customer); this.openTradingScreen(customer, this.getDisplayName(), this.getVillagerData().getLevel()); -@@ -643,8 +644,12 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -645,8 +646,12 @@ public class Villager extends AbstractVillager implements ReputationEventHandler protected void rewardTradeXp(MerchantOffer offer) { int i = 3 + this.random.nextInt(4); @@ -101,17 +101,23 @@ index 6cac189cf6e0bef2f0ea8c0dbadb0f417171a05e..45be97d79377f028264e7828e929d378 this.updateMerchantTimer = 40; this.increaseProfessionLevelOnUpdate = true; diff --git a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java -index 0854e9b7ee2e6b23b6c1ee6a324a5a253c9d4679..43d2785ee82467f0ce6c60b29d8f6f33fe65acc4 100644 +index 0af34e0f9c9696fbcb11b12fb27472ef17ad532a..422d537014520383503f06e834ef6fb31813beb8 100644 --- a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java +++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java -@@ -121,6 +121,7 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill - return InteractionResult.sidedSuccess(this.level().isClientSide); - } else { - if (!this.level().isClientSide) { -+ this.voidTrade = false; // Leaves - force void trade - this.setTradingPlayer(player); - this.openTradingScreen(player, this.getDisplayName(), 1); +@@ -122,9 +122,10 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill + return InteractionResult.CONSUME; } + +- this.setTradingPlayer(player); +- this.openTradingScreen(player, this.getDisplayName(), 1); +- } ++ this.voidTrade = false; // Leaves - force void trade ++ this.setTradingPlayer(player); ++ this.openTradingScreen(player, this.getDisplayName(), 1); ++ } + + return InteractionResult.sidedSuccess(this.level().isClientSide); + } else { diff --git a/src/main/java/net/minecraft/world/inventory/MerchantMenu.java b/src/main/java/net/minecraft/world/inventory/MerchantMenu.java index 2992e86f5f83431e230162380b33721df785ba91..7ec2ef906433d7e0164ce0e5ec62fef602ba6b37 100644 --- a/src/main/java/net/minecraft/world/inventory/MerchantMenu.java @@ -171,24 +177,24 @@ index 0efc8d997b34302c3e0a5d7ec73a11a940dbeefe..d246c9932f3f98972124089306d6ed74 } public void setToOutOfStock() { -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 8809755d0e3e6199e2db6c061e53375d17753b70..bd748c1b6d174b14aa4b5cba14578cc5c118b912 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 -@@ -213,6 +213,16 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity { - return; - } +diff --git a/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java b/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java +index 3f5bb5c9ceb5b31fcc9ef0a7a6157e1e1cb2a09f..3087c60589de8fc38e12d322e58886ba76749507 100644 +--- a/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java ++++ b/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java +@@ -118,6 +118,16 @@ public class EndGatewayBlock extends BaseEntityBlock implements Portal { + if (tileentity instanceof TheEndGatewayBlockEntity tileentityendgateway) { + Vec3 vec3d = tileentityendgateway.getPortalPosition(world, pos); -+ // Leaves start - force void trade -+ if (org.leavesmc.leaves.LeavesConfig.forceVoidTrade) { -+ if (((ServerPlayer) entity1).containerMenu instanceof net.minecraft.world.inventory.MerchantMenu merchantMenu) { -+ if (merchantMenu.trader instanceof net.minecraft.world.entity.npc.AbstractVillager villager) { -+ villager.setVoidTrade(); -+ } -+ } ++ // Leaves start - force void trade ++ if (org.leavesmc.leaves.LeavesConfig.forceVoidTrade && vec3d != null && entity instanceof net.minecraft.server.level.ServerPlayer player) { ++ if (player.containerMenu instanceof net.minecraft.world.inventory.MerchantMenu merchantMenu) { ++ if (merchantMenu.trader instanceof net.minecraft.world.entity.npc.AbstractVillager villager) { ++ villager.setVoidTrade(); + } -+ // Leaves end - force void trade ++ } ++ } ++ // Leaves end - force void trade + - entity1.setPortalCooldown(); - ((ServerPlayer) entity1).connection.teleport(teleEvent.getTo()); - // entity1.teleportPassengers(); // Paper - teleport passengers as well, preventing invisible passengers post teleport. // Leaves - vanilla + return vec3d != null ? new DimensionTransition(world, vec3d, EndGatewayBlock.calculateExitMovement(entity), entity.getYRot(), entity.getXRot(), DimensionTransition.PLACE_PORTAL_TICKET, PlayerTeleportEvent.TeleportCause.END_GATEWAY) : null; // CraftBukkit + } else { + return null; diff --git a/patches/server/0115-Villager-infinite-discounts.patch b/patches/server/0107-Villager-infinite-discounts.patch similarity index 100% rename from patches/server/0115-Villager-infinite-discounts.patch rename to patches/server/0107-Villager-infinite-discounts.patch diff --git a/patches/server/0116-CCE-update-suppression.patch b/patches/server/0108-CCE-update-suppression.patch similarity index 95% rename from patches/server/0116-CCE-update-suppression.patch rename to patches/server/0108-CCE-update-suppression.patch index 4e147755..ae97bb98 100644 --- a/patches/server/0116-CCE-update-suppression.patch +++ b/patches/server/0108-CCE-update-suppression.patch @@ -5,7 +5,7 @@ Subject: [PATCH] CCE update suppression diff --git a/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java b/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java -index aeb0577abcc0790edaece34939a6756424610dbc..254ae2f75ab25b3b1c2349b593122c3e09c9b981 100644 +index 4a0617f7b5f528421620ad504467212b7042716f..bb82b7aadb03ffba652948a660773035f5ee735d 100644 --- a/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java @@ -231,17 +231,21 @@ public class ShulkerBoxBlock extends BaseEntityBlock { diff --git a/patches/server/0117-Disable-offline-warn-if-use-proxy.patch b/patches/server/0109-Disable-offline-warn-if-use-proxy.patch similarity index 89% rename from patches/server/0117-Disable-offline-warn-if-use-proxy.patch rename to patches/server/0109-Disable-offline-warn-if-use-proxy.patch index 4896d509..fd9e1d8d 100644 --- a/patches/server/0117-Disable-offline-warn-if-use-proxy.patch +++ b/patches/server/0109-Disable-offline-warn-if-use-proxy.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Disable offline warn if use proxy diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index 7148b5c8f4b63649ef8f89963b6bd591fd1a97bf..5a2bd2543dee0c307d2702395fc676c4f44bf59d 100644 +index 59df97cf46923d3b84179a9407e210de9a2f3658..ecf6bad6e19a67ac122555bba7a8f9a42eed4e52 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -@@ -296,7 +296,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -300,7 +300,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface String proxyFlavor = (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) ? "Velocity" : "BungeeCord"; String proxyLink = (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) ? "https://docs.papermc.io/velocity/security" : "http://www.spigotmc.org/wiki/firewall-guide/"; // Paper end - Add Velocity IP Forwarding Support diff --git a/patches/server/0118-Disable-moved-wrongly-threshold.patch b/patches/server/0110-Disable-moved-wrongly-threshold.patch similarity index 90% rename from patches/server/0118-Disable-moved-wrongly-threshold.patch rename to patches/server/0110-Disable-moved-wrongly-threshold.patch index 06f4c857..251afb19 100644 --- a/patches/server/0118-Disable-moved-wrongly-threshold.patch +++ b/patches/server/0110-Disable-moved-wrongly-threshold.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Disable moved wrongly threshold diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 27aecb9282460b7744638d282f4504fb9e8ce897..48a706bc90e409a8e520ff04e8cb68c5cc8cef23 100644 +index 7ba4f9926a8945651e55aeca99e3badaf258546e..b65ef0e04836b85b31e3681b4b25f94c84f9692b 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -566,7 +566,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -569,7 +569,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } // Paper end - Prevent moving into unloaded chunks @@ -17,16 +17,16 @@ index 27aecb9282460b7744638d282f4504fb9e8ce897..48a706bc90e409a8e520ff04e8cb68c5 // CraftBukkit end ServerGamePacketListenerImpl.LOGGER.warn("{} (vehicle of {}) moved too quickly! {},{},{}", new Object[]{entity.getName().getString(), this.player.getName().getString(), d6, d7, d8}); this.send(new ClientboundMoveVehiclePacket(entity)); -@@ -602,7 +602,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -604,7 +604,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl d10 = d6 * d6 + d7 * d7 + d8 * d8; boolean flag2 = false; - if (d10 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot + if (!org.leavesmc.leaves.LeavesConfig.disableMovedWronglyThreshold && d10 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot // Leaves - disable can - flag2 = true; // Paper - diff on change, this should be moved wrongly + flag2 = true; ServerGamePacketListenerImpl.LOGGER.warn("{} (vehicle of {}) moved wrongly! {}", new Object[]{entity.getName().getString(), this.player.getName().getString(), Math.sqrt(d10)}); } -@@ -1417,7 +1417,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1381,7 +1381,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.MOVED_TOO_QUICKLY, toX, toY, toZ, toYaw, toPitch, true); if (!event.isAllowed()) { @@ -35,7 +35,7 @@ index 27aecb9282460b7744638d282f4504fb9e8ce897..48a706bc90e409a8e520ff04e8cb68c5 ServerGamePacketListenerImpl.LOGGER.warn("{} moved too quickly! {},{},{}", new Object[]{this.player.getName().getString(), d6, d7, d8}); this.teleport(this.player.getX(), this.player.getY(), this.player.getZ(), this.player.getYRot(), this.player.getXRot()); return; -@@ -1487,7 +1487,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1450,7 +1450,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl d10 = d6 * d6 + d7 * d7 + d8 * d8; boolean movedWrongly = false; // Paper - Add fail move event; rename diff --git a/patches/server/0110-RNG-Fishing.patch b/patches/server/0110-RNG-Fishing.patch deleted file mode 100644 index bd8e7682..00000000 --- a/patches/server/0110-RNG-Fishing.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: violetc <58360096+s-yh-china@users.noreply.github.com> -Date: Mon, 4 Sep 2023 22:09:10 +0800 -Subject: [PATCH] RNG Fishing - - -diff --git a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java -index 79ed9104efd9695aee9f9f45d342900d88a7ef02..b16f8f6cae5ad27b5889e2349d95359902b60bd8 100644 ---- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java -+++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java -@@ -522,7 +522,7 @@ public class FishingHook extends Projectile { - } else if (this.nibble > 0) { - LootParams lootparams = (new LootParams.Builder((ServerLevel) this.level())).withParameter(LootContextParams.ORIGIN, this.position()).withParameter(LootContextParams.TOOL, usedItem).withParameter(LootContextParams.THIS_ENTITY, this).withLuck((float) this.luck + entityhuman.getLuck()).create(LootContextParamSets.FISHING); - LootTable loottable = this.level().getServer().reloadableRegistries().getLootTable(BuiltInLootTables.FISHING); -- List list = loottable.getRandomItems(lootparams); -+ List list = org.leavesmc.leaves.LeavesConfig.rngFishing ? loottable.getRandomItems(lootparams, this.random) : loottable.getRandomItems(lootparams); // Leaves - world random - - CriteriaTriggers.FISHING_ROD_HOOKED.trigger((ServerPlayer) entityhuman, usedItem, this, list); - Iterator iterator = list.iterator(); -diff --git a/src/main/java/net/minecraft/world/level/storage/loot/LootContext.java b/src/main/java/net/minecraft/world/level/storage/loot/LootContext.java -index 4a1a37040a328281ce748486b7f4150b7b0a3b01..849bde24d9a0f64ea9a64d9cd94de979befd1261 100644 ---- a/src/main/java/net/minecraft/world/level/storage/loot/LootContext.java -+++ b/src/main/java/net/minecraft/world/level/storage/loot/LootContext.java -@@ -96,6 +96,13 @@ public class LootContext { - this.params = parameters; - } - -+ // Leaves start - world random -+ public LootContext.Builder withRandom(RandomSource random) { -+ this.random = random; -+ return this; -+ } -+ // Leaves end - world random -+ - public LootContext.Builder withOptionalRandomSeed(long seed) { - if (seed != 0L) { - this.random = RandomSource.create(seed); -diff --git a/src/main/java/net/minecraft/world/level/storage/loot/LootTable.java b/src/main/java/net/minecraft/world/level/storage/loot/LootTable.java -index 6db7a023dd802706935c384df0b0aa430a6e29aa..1199c741a14eaa9f002ee756a3ffb35d22ec26df 100644 ---- a/src/main/java/net/minecraft/world/level/storage/loot/LootTable.java -+++ b/src/main/java/net/minecraft/world/level/storage/loot/LootTable.java -@@ -136,6 +136,12 @@ public class LootTable { - return this.getRandomItems((new LootContext.Builder(parameters)).create(this.randomSequence)); - } - -+ // Leaves start - world random -+ public ObjectArrayList getRandomItems(LootParams parameters, RandomSource randomSource) { -+ return this.getRandomItems((new LootContext.Builder(parameters)).withRandom(randomSource).create(this.randomSequence)); -+ } -+ // Leaves end - world random -+ - private ObjectArrayList getRandomItems(LootContext context) { - ObjectArrayList objectarraylist = new ObjectArrayList(); - diff --git a/patches/server/0119-Armor-stand-cant-kill-by-mob-projectile.patch b/patches/server/0111-Armor-stand-cant-kill-by-mob-projectile.patch similarity index 68% rename from patches/server/0119-Armor-stand-cant-kill-by-mob-projectile.patch rename to patches/server/0111-Armor-stand-cant-kill-by-mob-projectile.patch index 718d3dc0..24900ad9 100644 --- a/patches/server/0119-Armor-stand-cant-kill-by-mob-projectile.patch +++ b/patches/server/0111-Armor-stand-cant-kill-by-mob-projectile.patch @@ -5,12 +5,12 @@ Subject: [PATCH] Armor stand cant kill by mob projectile diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -index 32fd9c3d79bb9e9e75b03750696425089e503dcb..4b04753093dd6c9140f68966120f80e52608936f 100644 +index df29a54063ee957c2b88a12ef228c7d8541a2f2c..93d4345695f69c94325edda17fb9aee65bf61ce5 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -@@ -525,6 +525,14 @@ public class ArmorStand extends LivingEntity { - boolean flag = source.is(DamageTypeTags.CAN_BREAK_ARMOR_STAND); - boolean flag1 = source.is(DamageTypeTags.ALWAYS_KILLS_ARMOR_STANDS); +@@ -531,6 +531,14 @@ public class ArmorStand extends LivingEntity { + boolean flag = source.is(DamageTypeTags.CAN_BREAK_ARMOR_STAND); + boolean flag1 = source.is(DamageTypeTags.ALWAYS_KILLS_ARMOR_STANDS); + // Leaves start - Armor stand cant kill by mob projectile + if (org.leavesmc.leaves.LeavesConfig.armorStandCantKillByMobProjectile) { @@ -20,6 +20,6 @@ index 32fd9c3d79bb9e9e75b03750696425089e503dcb..4b04753093dd6c9140f68966120f80e5 + } + // Leaves end - Armor stand cant kill by mob projectile + - if (!flag && !flag1) { - return false; - } else { + if (!flag && !flag1) { + return false; + } else { diff --git a/patches/server/0120-Make-Item-tick-vanilla.patch b/patches/server/0112-Make-Item-tick-vanilla.patch similarity index 83% rename from patches/server/0120-Make-Item-tick-vanilla.patch rename to patches/server/0112-Make-Item-tick-vanilla.patch index 29e79049..343ec4b4 100644 --- a/patches/server/0120-Make-Item-tick-vanilla.patch +++ b/patches/server/0112-Make-Item-tick-vanilla.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Make Item tick vanilla 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 1bb762349c868e6a68b46366710dbbee60466eaf..7ebe3c96254ea94855a80b9ffab6bffdc0dac808 100644 +index a1d4d8b6fe488a7056c6613acbd35d3be71ae039..ab277eee0ab86b6c5896d4e5179fcfc4f1a34375 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -@@ -258,6 +258,9 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -259,6 +259,9 @@ public class ItemEntity extends Entity implements TraceableEntity { // Spigot start - copied from above @Override public void inactiveTick() { @@ -18,7 +18,7 @@ index 1bb762349c868e6a68b46366710dbbee60466eaf..7ebe3c96254ea94855a80b9ffab6bffd // CraftBukkit start - Use wall time for pickup and despawn timers int elapsedTicks = MinecraftServer.currentTick - this.lastTick; if (this.pickupDelay != 32767) this.pickupDelay -= elapsedTicks; -@@ -275,6 +278,8 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -276,6 +279,8 @@ public class ItemEntity extends Entity implements TraceableEntity { // CraftBukkit end this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause } diff --git a/patches/server/0121-Copper-Bulb-1-gt-delay.patch b/patches/server/0113-Copper-Bulb-1-gt-delay.patch similarity index 100% rename from patches/server/0121-Copper-Bulb-1-gt-delay.patch rename to patches/server/0113-Copper-Bulb-1-gt-delay.patch diff --git a/patches/server/0122-Crafter-1-gt-delay.patch b/patches/server/0114-Crafter-1-gt-delay.patch similarity index 93% rename from patches/server/0122-Crafter-1-gt-delay.patch rename to patches/server/0114-Crafter-1-gt-delay.patch index 555b48c2..0f663be7 100644 --- a/patches/server/0122-Crafter-1-gt-delay.patch +++ b/patches/server/0114-Crafter-1-gt-delay.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Crafter 1 gt delay diff --git a/src/main/java/net/minecraft/world/level/block/CrafterBlock.java b/src/main/java/net/minecraft/world/level/block/CrafterBlock.java -index 4d315bd1df9f4647814500135195375166c578b3..69f7c2e4a41c73c99f3c9bf7a2923339d77e7f37 100644 +index 6c24b25a7c8ce6e34aceb5702f1a0a6732ebca44..d9caca74221e7173096671caae83ba171f4732df 100644 --- a/src/main/java/net/minecraft/world/level/block/CrafterBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CrafterBlock.java @@ -80,7 +80,7 @@ public class CrafterBlock extends BaseEntityBlock { diff --git a/patches/server/0114-Placeholder-for-Servux-Protocol.patch b/patches/server/0114-Placeholder-for-Servux-Protocol.patch deleted file mode 100644 index 1ffcc17d..00000000 --- a/patches/server/0114-Placeholder-for-Servux-Protocol.patch +++ /dev/null @@ -1,15 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: MC_XiaoHei -Date: Thu, 9 May 2024 22:46:34 +0800 -Subject: [PATCH] Placeholder for Servux-Protocol - - -diff --git a/.gitignore b/.gitignore -index 1ad93453221244f880855b510e888e759275b640..3811c0d849a3eb028ed1a6b7a2d4747f7f570448 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -46,4 +46,3 @@ dependency-reduced-pom.xml - # vs code - /.vscode - /.factorypath -- diff --git a/patches/server/0123-Linear-region-file-format.patch b/patches/server/0115-Linear-region-file-format.patch similarity index 56% rename from patches/server/0123-Linear-region-file-format.patch rename to patches/server/0115-Linear-region-file-format.patch index 07d91788..fc992e33 100644 --- a/patches/server/0123-Linear-region-file-format.patch +++ b/patches/server/0115-Linear-region-file-format.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Linear region file format This patch is Powered by LinearPurpur(https://github.com/StupidCraft/LinearPurpur) diff --git a/build.gradle.kts b/build.gradle.kts -index 28baa9a192a6fd83563b57a411e9bc905ba6b7e1..de18503a98afca9a271f81bb24cb489d902cfe39 100644 +index b35bc56ca35e7ada015e011ab4c3136b4803e48c..ce53dd3066bf8cf8812dbdcb660397ba7e9764d0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -30,6 +30,10 @@ dependencies { @@ -14,18 +14,33 @@ index 28baa9a192a6fd83563b57a411e9bc905ba6b7e1..de18503a98afca9a271f81bb24cb489d implementation("io.netty:netty-codec-haproxy:4.1.97.Final") // Paper - Add support for proxy protocol // Paper end + // Leaves start - Linear format -+ implementation("com.github.luben:zstd-jni:1.5.5-11") ++ implementation("com.github.luben:zstd-jni:1.5.6-3") + implementation("org.lz4:lz4-java:1.8.0") + // Leaves end - Linear format implementation("org.apache.logging.log4j:log4j-iostreams:2.22.1") // Paper - remove exclusion implementation("org.ow2.asm:asm-commons:9.7") implementation("org.spongepowered:configurate-yaml:4.2.0-SNAPSHOT") // Paper - config files -diff --git a/src/main/java/io/papermc/paper/chunk/system/io/RegionFileIOThread.java b/src/main/java/io/papermc/paper/chunk/system/io/RegionFileIOThread.java -index 2096e57c025858519e7c46788993b9aac1ec60e8..d4fa12ce7d2482bf00229e2ea9e25a2d7f59e0ea 100644 ---- a/src/main/java/io/papermc/paper/chunk/system/io/RegionFileIOThread.java -+++ b/src/main/java/io/papermc/paper/chunk/system/io/RegionFileIOThread.java -@@ -1077,9 +1077,9 @@ public final class RegionFileIOThread extends PrioritisedQueueExecutorThread { - return this.getCache().doesRegionFileNotExistNoIO(new ChunkPos(chunkX, chunkZ)); +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java +index 73df26b27146bbad2106d57b22dd3c792ed3dd1d..f3bd1488da34ea796c8205088e83d4c5dbd9f6bc 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java +@@ -7,8 +7,8 @@ public interface ChunkSystemRegionFileStorage { + + public boolean moonrise$doesRegionFileNotExistNoIO(final int chunkX, final int chunkZ); + +- public RegionFile moonrise$getRegionFileIfLoaded(final int chunkX, final int chunkZ); ++ public org.leavesmc.leaves.region.AbstractRegionFile moonrise$getRegionFileIfLoaded(final int chunkX, final int chunkZ); + +- public RegionFile moonrise$getRegionFileIfExists(final int chunkX, final int chunkZ) throws IOException; ++ public org.leavesmc.leaves.region.AbstractRegionFile moonrise$getRegionFileIfExists(final int chunkX, final int chunkZ) throws IOException; + + } +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/RegionFileIOThread.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/RegionFileIOThread.java +index c833f78d083b8f661087471c35bc90f65af1b525..8a00fd8c05df53ac99f214254e4dd9bd71858162 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/RegionFileIOThread.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/RegionFileIOThread.java +@@ -1042,9 +1042,9 @@ public final class RegionFileIOThread extends PrioritisedQueueExecutorThread { + return ((ChunkSystemRegionFileStorage)(Object)this.getCache()).moonrise$doesRegionFileNotExistNoIO(chunkX, chunkZ); } - public T computeForRegionFile(final int chunkX, final int chunkZ, final boolean existingOnly, final Function function) { @@ -35,14 +50,8 @@ index 2096e57c025858519e7c46788993b9aac1ec60e8..d4fa12ce7d2482bf00229e2ea9e25a2d + final org.leavesmc.leaves.region.AbstractRegionFile regionFile; // Leaves synchronized (cache) { try { - regionFile = cache.getRegionFile(new ChunkPos(chunkX, chunkZ), existingOnly, true); -@@ -1092,19 +1092,19 @@ public final class RegionFileIOThread extends PrioritisedQueueExecutorThread { - return function.apply(regionFile); - } finally { - if (regionFile != null) { -- regionFile.fileLock.unlock(); -+ regionFile.getFileLock().unlock(); // Leaves - } + if (existingOnly) { +@@ -1060,9 +1060,9 @@ public final class RegionFileIOThread extends PrioritisedQueueExecutorThread { } } @@ -53,53 +62,9 @@ index 2096e57c025858519e7c46788993b9aac1ec60e8..d4fa12ce7d2482bf00229e2ea9e25a2d + final org.leavesmc.leaves.region.AbstractRegionFile regionFile; // Leaves synchronized (cache) { - regionFile = cache.getRegionFileIfLoaded(new ChunkPos(chunkX, chunkZ)); - if (regionFile != null) { -- regionFile.fileLock.lock(); -+ regionFile.getFileLock().lock(); // Leaves - } - } - -@@ -1112,7 +1112,7 @@ public final class RegionFileIOThread extends PrioritisedQueueExecutorThread { - return function.apply(regionFile); - } finally { - if (regionFile != null) { -- regionFile.fileLock.unlock(); -+ regionFile.getFileLock().unlock(); // Leaves - } - } - } -diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 7dcdc9b40c594234d87bef3e75a68ddaa58506a3..6bbccbc2e114bf31a0ca3341437b7d5f466f858e 100644 ---- a/src/main/java/net/minecraft/server/level/ChunkMap.java -+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -885,13 +885,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - } - - public ChunkStatus getChunkStatusOnDiskIfCached(ChunkPos chunkPos) { -- net.minecraft.world.level.chunk.storage.RegionFile regionFile = regionFileCache.getRegionFileIfLoaded(chunkPos); -+ org.leavesmc.leaves.region.AbstractRegionFile regionFile = regionFileCache.getRegionFileIfLoaded(chunkPos); // Leaves - - return regionFile == null ? null : regionFile.getStatusIfCached(chunkPos.x, chunkPos.z); - } - - public ChunkStatus getChunkStatusOnDisk(ChunkPos chunkPos) throws IOException { -- net.minecraft.world.level.chunk.storage.RegionFile regionFile = regionFileCache.getRegionFile(chunkPos, true); -+ org.leavesmc.leaves.region.AbstractRegionFile regionFile = regionFileCache.getRegionFile(chunkPos, true); // Leaves - - if (regionFile == null || !regionFileCache.chunkExists(chunkPos)) { - return null; -@@ -909,7 +909,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - } - - public void updateChunkStatusOnDisk(ChunkPos chunkPos, @Nullable CompoundTag compound) throws IOException { -- net.minecraft.world.level.chunk.storage.RegionFile regionFile = regionFileCache.getRegionFile(chunkPos, false); -+ org.leavesmc.leaves.region.AbstractRegionFile regionFile = regionFileCache.getRegionFile(chunkPos, false); // Leaves - - regionFile.setStatus(chunkPos.x, chunkPos.z, ChunkSerializer.getStatus(compound)); - } + regionFile = ((ChunkSystemRegionFileStorage)(Object)cache).moonrise$getRegionFileIfLoaded(chunkX, chunkZ); diff --git a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java -index 954d468459fe167ede0e7fca5b9f99da565d59e1..12055c5e16ddb58d9e3c6c6d13f85facb2b7ac5d 100644 +index 0382b6597a130d746f8954a93a756a9d1ac81d50..256d0541394e24a039f1f670e3d894ac039e212d 100644 --- a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java +++ b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java @@ -76,7 +76,7 @@ public class WorldUpgrader { @@ -111,7 +76,7 @@ index 954d468459fe167ede0e7fca5b9f99da565d59e1..12055c5e16ddb58d9e3c6c6d13f85fac final DimensionDataStorage overworldDataStorage; public WorldUpgrader(LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, RegistryAccess dynamicRegistryManager, boolean eraseCache, boolean recreateRegionFiles) { -@@ -406,7 +406,7 @@ public class WorldUpgrader { +@@ -394,7 +394,7 @@ public class WorldUpgrader { private static List getAllChunkPositions(RegionStorageInfo key, Path regionDirectory) { File[] afile = regionDirectory.toFile().listFiles((file, s) -> { @@ -120,8 +85,35 @@ index 954d468459fe167ede0e7fca5b9f99da565d59e1..12055c5e16ddb58d9e3c6c6d13f85fac }); if (afile == null) { +@@ -414,7 +414,7 @@ public class WorldUpgrader { + List list1 = Lists.newArrayList(); + + try { +- RegionFile regionfile = new RegionFile(key, file.toPath(), regionDirectory, true); ++ org.leavesmc.leaves.region.AbstractRegionFile regionfile = org.leavesmc.leaves.region.AbstractRegionFileFactory.getAbstractRegionFile(key, file.toPath(), regionDirectory, true); // Leaves + + try { + for (int i1 = 0; i1 < 32; ++i1) { +@@ -477,7 +477,7 @@ public class WorldUpgrader { + + protected abstract boolean tryProcessOnePosition(T storage, ChunkPos chunkPos, ResourceKey worldKey); + +- private void onFileFinished(RegionFile regionFile) { ++ private void onFileFinished(org.leavesmc.leaves.region.AbstractRegionFile regionFile) { // Leaves + if (WorldUpgrader.this.recreateRegionFiles) { + if (this.previousWriteFuture != null) { + this.previousWriteFuture.join(); +@@ -502,7 +502,7 @@ public class WorldUpgrader { + } + } + +- static record FileToUpgrade(RegionFile file, List chunksToUpgrade) { ++ static record FileToUpgrade(org.leavesmc.leaves.region.AbstractRegionFile file, List chunksToUpgrade) { // Leaves + + } + diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java -index 1362a47943cf1a51a185a15094b1f74c94bf40ef..5dc0631ee8122f1a8473b6b1cf890cb567400e09 100644 +index e761b63eebc1e76b2bb1cb887d83d0b63ad6ec90..2fefc69cc1df01a5ede2e5f2642adec6238e6368 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java @@ -28,7 +28,7 @@ import net.minecraft.nbt.NbtIo; // Paper @@ -133,33 +125,7 @@ index 1362a47943cf1a51a185a15094b1f74c94bf40ef..5dc0631ee8122f1a8473b6b1cf890cb5 private static final Logger LOGGER = LogUtils.getLogger(); private static final int SECTOR_BYTES = 4096; -@@ -60,6 +60,16 @@ public class RegionFile implements AutoCloseable { - return sectors + (sign >>> 63); - } - -+ // Leaves start - Abstract getters -+ public Path getRegionFile() { -+ return this.path; -+ } -+ -+ public java.util.concurrent.locks.ReentrantLock getFileLock() { -+ return this.fileLock; -+ } -+ // Leaves end -+ - private static final CompoundTag OVERSIZED_COMPOUND = new CompoundTag(); - - private CompoundTag attemptRead(long sector, int chunkDataLength, long fileLength) throws IOException { -@@ -130,7 +140,7 @@ public class RegionFile implements AutoCloseable { - } - - // note: only call for CHUNK regionfiles -- boolean recalculateHeader() throws IOException { -+ public boolean recalculateHeader() throws IOException { // Leaves - if (!this.canRecalcHeader) { - return false; - } -@@ -972,10 +982,10 @@ public class RegionFile implements AutoCloseable { +@@ -465,10 +465,10 @@ public class RegionFile implements AutoCloseable { private static int getChunkIndex(int x, int z) { return (x & 31) + (z & 31) * 32; } @@ -172,7 +138,7 @@ index 1362a47943cf1a51a185a15094b1f74c94bf40ef..5dc0631ee8122f1a8473b6b1cf890cb5 final int offset = getChunkIndex(x, z); boolean previous = this.oversized[offset] == 1; this.oversized[offset] = (byte) (oversized ? 1 : 0); -@@ -1014,7 +1024,7 @@ public class RegionFile implements AutoCloseable { +@@ -507,7 +507,7 @@ public class RegionFile implements AutoCloseable { return this.path.getParent().resolve(this.path.getFileName().toString().replaceAll("\\.mca$", "") + "_oversized_" + x + "_" + z + ".nbt"); } @@ -182,10 +148,10 @@ index 1362a47943cf1a51a185a15094b1f74c94bf40ef..5dc0631ee8122f1a8473b6b1cf890cb5 try (DataInputStream out = new DataInputStream(new java.io.BufferedInputStream(new InflaterInputStream(Files.newInputStream(file))))) { return NbtIo.read((java.io.DataInput) out); diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java -index 1090b7e36e3c1c105bc36135b82751c651f237d4..d24ec065c76f6852586328dd56fba311cf8ac8a8 100644 +index 0615fd82b71efb9a397de01615050e6d906c2844..f400a188b70ea74f986f05861c35671d82e59b32 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java -@@ -21,11 +21,15 @@ public class RegionFileStorage implements AutoCloseable { +@@ -21,7 +21,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise public static final String ANVIL_EXTENSION = ".mca"; private static final int MAX_CACHE_SIZE = 256; @@ -194,118 +160,99 @@ index 1090b7e36e3c1c105bc36135b82751c651f237d4..d24ec065c76f6852586328dd56fba311 private final RegionStorageInfo info; private final Path folder; private final boolean sync; - private final boolean isChunkData; // Paper -+ // Leaves start - region format -+ public final org.leavesmc.leaves.region.RegionFileFormat format; -+ public final int linearCompression; +@@ -31,9 +31,15 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise + private static final int MAX_NON_EXISTING_CACHE = 1024 * 64; + private final it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet nonExistingRegionFiles = new it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet(MAX_NON_EXISTING_CACHE+1); + private static String getRegionFileName(final int chunkX, final int chunkZ) { +- return "r." + (chunkX >> REGION_SHIFT) + "." + (chunkZ >> REGION_SHIFT) + ".mca"; ++ return "r." + (chunkX >> REGION_SHIFT) + "." + (chunkZ >> REGION_SHIFT) + (org.leavesmc.leaves.LeavesConfig.regionFormatName != org.leavesmc.leaves.region.RegionFileFormat.LINEAR ? ".mca" : ".linear"); // Leaves + } + ++ // Leaves start ++ private static String getOtherRegionFileName(final int chunkX, final int chunkZ) { ++ return "r." + (chunkX >> REGION_SHIFT) + "." + (chunkZ >> REGION_SHIFT) + (org.leavesmc.leaves.LeavesConfig.regionFormatName == org.leavesmc.leaves.region.RegionFileFormat.LINEAR ? ".mca" : ".linear"); ++ } + // Leaves end - - // Paper start - cache regionfile does not exist state - static final int MAX_NON_EXISTING_CACHE = 1024 * 64; -@@ -66,13 +70,17 @@ public class RegionFileStorage implements AutoCloseable { - this.folder = directory; - this.sync = dsync; - this.info = storageKey; -+ // Leaves start -+ this.format = org.leavesmc.leaves.LeavesConfig.regionFormatName; -+ this.linearCompression = org.leavesmc.leaves.LeavesConfig.linearCompressionLevel; -+ // Leaves end ++ + private boolean doesRegionFilePossiblyExist(final long position) { + synchronized (this.nonExistingRegionFiles) { + if (this.nonExistingRegionFiles.contains(position)) { +@@ -66,15 +72,15 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise } - // Paper start - @Nullable - public static ChunkPos getRegionFileCoordinates(Path file) { - String fileName = file.getFileName().toString(); -- if (!fileName.startsWith("r.") || !fileName.endsWith(".mca")) { -+ if (!fileName.startsWith("r.") || !fileName.endsWith(".mca") || !fileName.endsWith(".linear")) { // Leaves - return null; + @Override +- public synchronized final RegionFile moonrise$getRegionFileIfLoaded(final int chunkX, final int chunkZ) { ++ public synchronized final org.leavesmc.leaves.region.AbstractRegionFile moonrise$getRegionFileIfLoaded(final int chunkX, final int chunkZ) { // Leaves + return this.regionCache.getAndMoveToFirst(ChunkPos.asLong(chunkX >> REGION_SHIFT, chunkZ >> REGION_SHIFT)); + } + + @Override +- public synchronized final RegionFile moonrise$getRegionFileIfExists(final int chunkX, final int chunkZ) throws IOException { ++ public synchronized final org.leavesmc.leaves.region.AbstractRegionFile moonrise$getRegionFileIfExists(final int chunkX, final int chunkZ) throws IOException { // Leaves + final long key = ChunkPos.asLong(chunkX >> REGION_SHIFT, chunkZ >> REGION_SHIFT); + +- RegionFile ret = this.regionCache.getAndMoveToFirst(key); ++ org.leavesmc.leaves.region.AbstractRegionFile ret = this.regionCache.getAndMoveToFirst(key); // Leaves + if (ret != null) { + return ret; } +@@ -86,19 +92,23 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise + if (this.regionCache.size() >= io.papermc.paper.configuration.GlobalConfiguration.get().misc.regionFileCacheSize) { // Paper + this.regionCache.removeLast().close(); + } +- +- final Path regionPath = this.folder.resolve(getRegionFileName(chunkX, chunkZ)); ++ // Leaves start ++ Path regionPath = this.folder.resolve(getRegionFileName(chunkX, chunkZ)); -@@ -94,29 +102,29 @@ public class RegionFileStorage implements AutoCloseable { - // Paper end + if (!java.nio.file.Files.exists(regionPath)) { +- this.markNonExisting(key); +- return null; ++ regionPath = this.folder.resolve(getOtherRegionFileName(chunkX, chunkZ)); ++ if (!java.nio.file.Files.exists(regionPath)) { ++ this.markNonExisting(key); ++ return null; ++ } + } ++ // Leaves end - // Paper start -- public synchronized RegionFile getRegionFileIfLoaded(ChunkPos chunkcoordintpair) { -+ public synchronized org.leavesmc.leaves.region.AbstractRegionFile getRegionFileIfLoaded(ChunkPos chunkcoordintpair) { // Leaves - return this.regionCache.getAndMoveToFirst(ChunkPos.asLong(chunkcoordintpair.getRegionX(), chunkcoordintpair.getRegionZ())); + this.createRegionFile(key); + + FileUtil.createDirectoriesSafe(this.folder); + +- ret = new RegionFile(this.info, regionPath, this.folder, this.sync); ++ ret = org.leavesmc.leaves.region.AbstractRegionFileFactory.getAbstractRegionFile(this.info, regionPath, this.folder, this.sync); // Leaves + + this.regionCache.putAndMoveToFirst(key, ret); + +@@ -112,7 +122,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise + this.info = storageKey; } - public synchronized boolean chunkExists(ChunkPos pos) throws IOException { -- RegionFile regionfile = getRegionFile(pos, true); -+ org.leavesmc.leaves.region.AbstractRegionFile regionfile = getRegionFile(pos, true); // Leaves +- public RegionFile getRegionFile(ChunkPos chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit // Paper - public ++ public org.leavesmc.leaves.region.AbstractRegionFile getRegionFile(ChunkPos chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit // Paper - public // Leaves + // Paper start - rewrite chunk system + if (existingOnly) { + return this.moonrise$getRegionFileIfExists(chunkcoordintpair.x, chunkcoordintpair.z); +@@ -120,7 +130,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise + synchronized (this) { + final long key = ChunkPos.asLong(chunkcoordintpair.x >> REGION_SHIFT, chunkcoordintpair.z >> REGION_SHIFT); - return regionfile != null ? regionfile.hasChunk(pos) : false; - } +- RegionFile ret = this.regionCache.getAndMoveToFirst(key); ++ org.leavesmc.leaves.region.AbstractRegionFile ret = this.regionCache.getAndMoveToFirst(key); // Leaves + if (ret != null) { + return ret; + } +@@ -135,7 +145,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise -- public synchronized RegionFile getRegionFile(ChunkPos chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit -+ public synchronized org.leavesmc.leaves.region.AbstractRegionFile getRegionFile(ChunkPos chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit // Leaves - return this.getRegionFile(chunkcoordintpair, existingOnly, false); - } -- public synchronized RegionFile getRegionFile(ChunkPos chunkcoordintpair, boolean existingOnly, boolean lock) throws IOException { -+ public synchronized org.leavesmc.leaves.region.AbstractRegionFile getRegionFile(ChunkPos chunkcoordintpair, boolean existingOnly, boolean lock) throws IOException { // Leaves - // Paper end - long i = ChunkPos.asLong(chunkcoordintpair.getRegionX(), chunkcoordintpair.getRegionZ()); final long regionPos = i; // Paper - OBFHELPER -- RegionFile regionfile = (RegionFile) this.regionCache.getAndMoveToFirst(i); -+ org.leavesmc.leaves.region.AbstractRegionFile regionfile = this.regionCache.getAndMoveToFirst(i); // Leaves + FileUtil.createDirectoriesSafe(this.folder); - if (regionfile != null) { - // Paper start - if (lock) { - // must be in this synchronized block -- regionfile.fileLock.lock(); -+ regionfile.getFileLock().lock(); // Leaves - } - // Paper end - return regionfile; -@@ -127,28 +135,40 @@ public class RegionFileStorage implements AutoCloseable { - } - // Paper end - cache regionfile does not exist state - if (this.regionCache.size() >= io.papermc.paper.configuration.GlobalConfiguration.get().misc.regionFileCacheSize) { // Paper - Sanitise RegionFileCache and make configurable -- ((RegionFile) this.regionCache.removeLast()).close(); -+ this.regionCache.removeLast().close(); // Leaves - } +- ret = new RegionFile(this.info, regionPath, this.folder, this.sync); ++ ret = org.leavesmc.leaves.region.AbstractRegionFileFactory.getAbstractRegionFile(this.info, regionPath, this.folder, this.sync); // Leaves - // Paper - only create directory if not existing only - moved down - Path path = this.folder; - int j = chunkcoordintpair.getRegionX(); -- Path path1 = path.resolve("r." + j + "." + chunkcoordintpair.getRegionZ() + ".mca"); // Paper - diff on change -- if (existingOnly && !java.nio.file.Files.exists(path1)) { // Paper start - cache regionfile does not exist state -- this.markNonExisting(regionPos); -- return null; // CraftBukkit -+ // Leaves start - Polyglot -+ Path path1; -+ if (existingOnly) { -+ Path anvil = path.resolve("r." + j + "." + chunkcoordintpair.getRegionZ() + ".mca"); -+ Path linear = path.resolve("r." + j + "." + chunkcoordintpair.getRegionZ() + ".linear"); -+ path1 = java.nio.file.Files.exists(linear) ? linear : java.nio.file.Files.exists(anvil) ? anvil : null; -+ if (path1 == null) { -+ markNonExisting(regionPos); -+ return null; // CraftBukkit -+ } - } else { -+ String extension = switch (this.format) { -+ case LINEAR -> "linear"; -+ default -> "mca"; -+ }; -+ path1 = path.resolve("r." + j + "." + chunkcoordintpair.getRegionZ() + "." + extension); -+ // Leaves end - Polyglot - this.createRegionFile(regionPos); - } - // Paper end - cache regionfile does not exist state - FileUtil.createDirectoriesSafe(this.folder); // Paper - only create directory if not existing only - moved from above -- RegionFile regionfile1 = new RegionFile(this.info, path1, this.folder, this.sync, this.isChunkData); // Paper - allow for chunk regionfiles to regen header -+ org.leavesmc.leaves.region.AbstractRegionFile regionfile1 = org.leavesmc.leaves.region.AbstractRegionFileFactory.getAbstractRegionFile(this.linearCompression, this.info, path1, this.folder, this.sync, this.isChunkData); // Paper - allow for chunk regionfiles to regen header // Leaves + this.regionCache.putAndMoveToFirst(key, ret); - this.regionCache.putAndMoveToFirst(i, regionfile1); - // Paper start - if (lock) { - // must be in this synchronized block -- regionfile1.fileLock.lock(); -+ regionfile1.getFileLock().lock(); // Leaves - } - // Paper end - return regionfile1; -@@ -160,7 +180,7 @@ public class RegionFileStorage implements AutoCloseable { +@@ -149,7 +159,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise org.apache.logging.log4j.LogManager.getLogger().fatal(msg + " (" + file.toString().replaceAll(".+[\\\\/]", "") + " - " + x + "," + z + ") Go clean it up to remove this message. /minecraft:tp " + (x<<4)+" 128 "+(z<<4) + " - DO NOT REPORT THIS TO PAPER - You may ask for help on Discord, but do not file an issue. These error messages can not be removed."); } @@ -314,56 +261,16 @@ index 1090b7e36e3c1c105bc36135b82751c651f237d4..d24ec065c76f6852586328dd56fba311 synchronized (regionfile) { try (DataInputStream datainputstream = regionfile.getChunkDataInputStream(chunkCoordinate)) { CompoundTag oversizedData = regionfile.getOversizedData(chunkCoordinate.x, chunkCoordinate.z); -@@ -195,14 +215,14 @@ public class RegionFileStorage implements AutoCloseable { +@@ -184,7 +194,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise @Nullable public CompoundTag read(ChunkPos pos) throws IOException { // CraftBukkit start - SPIGOT-5680: There's no good reason to preemptively create files on read, save that for writing -- RegionFile regionfile = this.getRegionFile(pos, true, true); // Paper -+ org.leavesmc.leaves.region.AbstractRegionFile regionfile = this.getRegionFile(pos, true, true); // Paper // Leaves +- RegionFile regionfile = this.getRegionFile(pos, true); ++ org.leavesmc.leaves.region.AbstractRegionFile regionfile = this.getRegionFile(pos, true); // Paper // Leaves if (regionfile == null) { return null; } - // Paper start - Add regionfile parameter - return this.read(pos, regionfile); - } -- public CompoundTag read(ChunkPos pos, RegionFile regionfile) throws IOException { -+ public CompoundTag read(ChunkPos pos, org.leavesmc.leaves.region.AbstractRegionFile regionfile) throws IOException { // Leaves - // We add the regionfile parameter to avoid the potential deadlock (on fileLock) if we went back to obtain a regionfile - // if we decide to re-read - // Paper end -@@ -212,7 +232,7 @@ public class RegionFileStorage implements AutoCloseable { - - // Paper start - if (regionfile.isOversized(pos.x, pos.z)) { -- printOversizedLog("Loading Oversized Chunk!", regionfile.getPath(), pos.x, pos.z); -+ printOversizedLog("Loading Oversized Chunk!", regionfile.getRegionFile(), pos.x, pos.z); // Leaves - return readOversizedChunk(regionfile, pos); - } - // Paper end -@@ -226,12 +246,12 @@ public class RegionFileStorage implements AutoCloseable { - if (this.isChunkData) { - ChunkPos chunkPos = ChunkSerializer.getChunkCoordinate(nbttagcompound); - if (!chunkPos.equals(pos)) { -- net.minecraft.server.MinecraftServer.LOGGER.error("Attempting to read chunk data at " + pos + " but got chunk data for " + chunkPos + " instead! Attempting regionfile recalculation for regionfile " + regionfile.getPath().toAbsolutePath()); -+ net.minecraft.server.MinecraftServer.LOGGER.error("Attempting to read chunk data at " + pos + " but got chunk data for " + chunkPos + " instead! Attempting regionfile recalculation for regionfile " + regionfile.getRegionFile().toAbsolutePath()); // Leaves - if (regionfile.recalculateHeader()) { -- regionfile.fileLock.lock(); // otherwise we will unlock twice and only lock once. -+ regionfile.getFileLock().lock(); // otherwise we will unlock twice and only lock once. // Leaves - return this.read(pos, regionfile); - } -- net.minecraft.server.MinecraftServer.LOGGER.error("Can't recalculate regionfile header, regenerating chunk " + pos + " for " + regionfile.getPath().toAbsolutePath()); -+ net.minecraft.server.MinecraftServer.LOGGER.error("Can't recalculate regionfile header, regenerating chunk " + pos + " for " + regionfile.getRegionFile().toAbsolutePath()); // Leaves - return null; - } - } -@@ -265,13 +285,13 @@ public class RegionFileStorage implements AutoCloseable { - - return nbttagcompound; - } finally { // Paper start -- regionfile.fileLock.unlock(); -+ regionfile.getFileLock().unlock(); // Leaves - } // Paper end - } +@@ -235,7 +245,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise public void scanChunk(ChunkPos chunkPos, StreamTagVisitor scanner) throws IOException { // CraftBukkit start - SPIGOT-5680: There's no good reason to preemptively create files on read, save that for writing @@ -372,16 +279,16 @@ index 1090b7e36e3c1c105bc36135b82751c651f237d4..d24ec065c76f6852586328dd56fba311 if (regionfile == null) { return; } -@@ -302,7 +322,7 @@ public class RegionFileStorage implements AutoCloseable { +@@ -265,7 +275,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise + } - protected void write(ChunkPos pos, @Nullable CompoundTag nbt) throws IOException { + public void write(ChunkPos pos, @Nullable CompoundTag nbt) throws IOException { // Paper - public +- RegionFile regionfile = this.getRegionFile(pos, nbt == null); // CraftBukkit // Paper - rewrite chunk system ++ org.leavesmc.leaves.region.AbstractRegionFile regionfile = this.getRegionFile(pos, nbt == null); // CraftBukkit // Paper - rewrite chunk system // Leaves // Paper start - rewrite chunk system -- RegionFile regionfile = this.getRegionFile(pos, nbt == null, true); // CraftBukkit -+ org.leavesmc.leaves.region.AbstractRegionFile regionfile = this.getRegionFile(pos, nbt == null, true); // CraftBukkit // Paper // Paper start - rewrite chunk system // Leaves - if (nbt == null && regionfile == null) { - return; - } -@@ -317,8 +337,33 @@ public class RegionFileStorage implements AutoCloseable { + if (regionfile == null) { + // if the RegionFile doesn't exist, no point in deleting from it +@@ -281,8 +291,33 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise if (nbt == null) { regionfile.clear(pos); } else { @@ -389,8 +296,8 @@ index 1090b7e36e3c1c105bc36135b82751c651f237d4..d24ec065c76f6852586328dd56fba311 + // Leaves start - auto convert anvil to linear + DataOutputStream dataoutputstream; + -+ if(regionfile instanceof RegionFile && org.leavesmc.leaves.LeavesConfig.regionFormatName == org.leavesmc.leaves.region.RegionFileFormat.LINEAR && org.leavesmc.leaves.LeavesConfig.autoConvertAnvilToLinear) { -+ Path linearFilePath = Path.of(regionfile.getRegionFile().toString().replaceAll(".mca", ".linear")); ++ if (regionfile instanceof RegionFile && org.leavesmc.leaves.LeavesConfig.regionFormatName == org.leavesmc.leaves.region.RegionFileFormat.LINEAR && org.leavesmc.leaves.LeavesConfig.autoConvertAnvilToLinear) { ++ Path linearFilePath = Path.of(regionfile.getPath().toString().replaceAll(".mca", ".linear")); + try (org.leavesmc.leaves.region.LinearRegionFile linearRegionFile = new org.leavesmc.leaves.region.LinearRegionFile(linearFilePath, org.leavesmc.leaves.LeavesConfig.linearCompressionLevel)) { + DataInputStream regionDataInputStream = regionfile.getChunkDataInputStream(pos); + if (regionDataInputStream == null) { @@ -403,8 +310,8 @@ index 1090b7e36e3c1c105bc36135b82751c651f237d4..d24ec065c76f6852586328dd56fba311 + } + + linearRegionFile.flush(); -+ if(java.nio.file.Files.isRegularFile(regionfile.getRegionFile())) { -+ java.nio.file.Files.delete(regionfile.getRegionFile()); ++ if(java.nio.file.Files.isRegularFile(regionfile.getPath())) { ++ java.nio.file.Files.delete(regionfile.getPath()); + } + + dataoutputstream = linearRegionFile.getChunkDataOutputStream(pos); @@ -415,53 +322,31 @@ index 1090b7e36e3c1c105bc36135b82751c651f237d4..d24ec065c76f6852586328dd56fba311 + // leaves end - auto convert anvil to linear try { NbtIo.write(nbt, (DataOutput) dataoutputstream); - regionfile.setStatus(pos.x, pos.z, ChunkSerializer.getStatus(nbt)); // Paper - Cache chunk status -@@ -357,7 +402,7 @@ public class RegionFileStorage implements AutoCloseable { - // Paper end - Chunk save reattempt + regionfile.setOversized(pos.x, pos.z, false); // Paper - We don't do this anymore, mojang stores differently, but clear old meta flag if it exists to get rid of our own meta file once last oversized is gone +@@ -324,7 +359,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise // Paper start - rewrite chunk system - } finally { -- regionfile.fileLock.unlock(); -+ regionfile.getFileLock().unlock(); // Leaves - } - // Paper end - rewrite chunk system - } -@@ -367,7 +412,7 @@ public class RegionFileStorage implements AutoCloseable { - ObjectIterator objectiterator = this.regionCache.values().iterator(); - - while (objectiterator.hasNext()) { -- RegionFile regionfile = (RegionFile) objectiterator.next(); -+ org.leavesmc.leaves.region.AbstractRegionFile regionfile = (org.leavesmc.leaves.region.AbstractRegionFile) objectiterator.next(); // Leaves - - try { - regionfile.close(); -@@ -383,7 +428,7 @@ public class RegionFileStorage implements AutoCloseable { - ObjectIterator objectiterator = this.regionCache.values().iterator(); - - while (objectiterator.hasNext()) { -- RegionFile regionfile = (RegionFile) objectiterator.next(); -+ org.leavesmc.leaves.region.AbstractRegionFile regionfile = (org.leavesmc.leaves.region.AbstractRegionFile) objectiterator.next(); // Leaves - - regionfile.flush(); - } -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 105a1fb70a7b869b65617a760b8de1ea86f3571f..1288be2fa570ff304c70c8da6af8a6d862c5bdb7 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -609,7 +609,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { - world.getChunk(x, z); // make sure we're at ticket level 32 or lower - return true; - } -- net.minecraft.world.level.chunk.storage.RegionFile file; -+ org.leavesmc.leaves.region.AbstractRegionFile file; // Leaves - try { - file = world.getChunkSource().chunkMap.regionFileCache.getRegionFile(chunkPos, false); - } catch (java.io.IOException ex) { + synchronized (this) { + final ExceptionCollector exceptionCollector = new ExceptionCollector<>(); +- for (final RegionFile regionFile : this.regionCache.values()) { ++ for (final org.leavesmc.leaves.region.AbstractRegionFile regionFile : this.regionCache.values()) { // Leaves + try { + regionFile.close(); + } catch (final IOException ex) { +@@ -341,7 +376,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise + // Paper start - rewrite chunk system + synchronized (this) { + final ExceptionCollector exceptionCollector = new ExceptionCollector<>(); +- for (final RegionFile regionFile : this.regionCache.values()) { ++ for (final org.leavesmc.leaves.region.AbstractRegionFile regionFile : this.regionCache.values()) { // Leaves + try { + regionFile.flush(); + } catch (final IOException ex) { diff --git a/src/main/java/org/leavesmc/leaves/region/AbstractRegionFile.java b/src/main/java/org/leavesmc/leaves/region/AbstractRegionFile.java new file mode 100644 -index 0000000000000000000000000000000000000000..2116a2e7e10e64aad1373171c6efde65de6ca198 +index 0000000000000000000000000000000000000000..e5439ece2a33a8d88df6423eca22a895129fdbf4 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/region/AbstractRegionFile.java -@@ -0,0 +1,45 @@ +@@ -0,0 +1,37 @@ +package org.leavesmc.leaves.region; + +import net.minecraft.nbt.CompoundTag; @@ -476,95 +361,81 @@ index 0000000000000000000000000000000000000000..2116a2e7e10e64aad1373171c6efde65 + +public interface AbstractRegionFile { + -+ void flush() throws IOException; -+ -+ void clear(ChunkPos pos) throws IOException; -+ -+ void close() throws IOException; -+ -+ void setStatus(int x, int z, ChunkStatus status); -+ -+ void setOversized(int x, int z, boolean b) throws IOException; -+ -+ boolean hasChunk(ChunkPos pos); -+ -+ boolean doesChunkExist(ChunkPos pos) throws Exception; -+ -+ boolean isOversized(int x, int z); -+ -+ boolean recalculateHeader() throws IOException; -+ -+ DataOutputStream getChunkDataOutputStream(ChunkPos pos) throws IOException; ++ Path getPath(); + + DataInputStream getChunkDataInputStream(ChunkPos pos) throws IOException; + ++ DataOutputStream getChunkDataOutputStream(ChunkPos pos) throws IOException; ++ + CompoundTag getOversizedData(int x, int z) throws IOException; + -+ ChunkStatus getStatusIfCached(int x, int z); ++ boolean hasChunk(ChunkPos pos); + -+ ReentrantLock getFileLock(); ++ boolean doesChunkExist(ChunkPos pos); + -+ Path getRegionFile(); ++ boolean isOversized(int x, int z); ++ ++ void flush() throws IOException; ++ ++ void close() throws IOException; ++ ++ void clear(ChunkPos pos) throws IOException; ++ ++ void setOversized(int x, int z, boolean oversized) throws IOException; +} + diff --git a/src/main/java/org/leavesmc/leaves/region/AbstractRegionFileFactory.java b/src/main/java/org/leavesmc/leaves/region/AbstractRegionFileFactory.java new file mode 100644 -index 0000000000000000000000000000000000000000..8050b23fd624d2462200b621a6d711b144b2b46b +index 0000000000000000000000000000000000000000..72f4507aa10f2ecad545199ccb88038fd49dbe35 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/region/AbstractRegionFileFactory.java -@@ -0,0 +1,31 @@ +@@ -0,0 +1,24 @@ +package org.leavesmc.leaves.region; + +import net.minecraft.world.level.chunk.storage.RegionFile; +import net.minecraft.world.level.chunk.storage.RegionFileVersion; +import net.minecraft.world.level.chunk.storage.RegionStorageInfo; ++import org.leavesmc.leaves.LeavesConfig; + +import java.io.IOException; +import java.nio.file.Path; + +public class AbstractRegionFileFactory { + -+ public static AbstractRegionFile getAbstractRegionFile(int linearCompression, RegionStorageInfo storageKey, Path file, Path directory, boolean dsync) throws IOException { -+ return getAbstractRegionFile(linearCompression, storageKey, file, directory, RegionFileVersion.VERSION_DEFLATE, dsync); ++ public static AbstractRegionFile getAbstractRegionFile(RegionStorageInfo storageKey, Path directory, Path path, boolean dsync) throws IOException { ++ return getAbstractRegionFile(storageKey, directory, path, RegionFileVersion.getCompressionFormat(), dsync); + } + -+ public static AbstractRegionFile getAbstractRegionFile(int linearCompression, RegionStorageInfo storageKey, Path file, Path directory, boolean dsync, boolean canRecalcHeader) throws IOException { -+ return getAbstractRegionFile(linearCompression, storageKey, file, directory, RegionFileVersion.VERSION_DEFLATE, dsync, canRecalcHeader); -+ } -+ -+ public static AbstractRegionFile getAbstractRegionFile(int linearCompression, RegionStorageInfo storageKey, Path file, Path directory, RegionFileVersion outputChunkStreamVersion, boolean dsync) throws IOException { -+ return getAbstractRegionFile(linearCompression, storageKey, file, directory, outputChunkStreamVersion, dsync, false); -+ } -+ -+ public static AbstractRegionFile getAbstractRegionFile(int linearCompression, RegionStorageInfo storageKey, Path file, Path directory, RegionFileVersion outputChunkStreamVersion, boolean dsync, boolean canRecalcHeader) throws IOException { -+ if (file.toString().endsWith(".linear")) { -+ return new LinearRegionFile(file, linearCompression); ++ public static AbstractRegionFile getAbstractRegionFile(RegionStorageInfo storageKey, Path path, Path directory, RegionFileVersion compressionFormat, boolean dsync) throws IOException { ++ if (path.toString().endsWith(".linear")) { ++ return new LinearRegionFile(path, LeavesConfig.linearCompressionLevel); + } else { -+ return new RegionFile(storageKey, file, directory, outputChunkStreamVersion, dsync, canRecalcHeader); ++ return new RegionFile(storageKey, path, directory, compressionFormat, dsync); + } + } +} diff --git a/src/main/java/org/leavesmc/leaves/region/LinearRegionFile.java b/src/main/java/org/leavesmc/leaves/region/LinearRegionFile.java new file mode 100644 -index 0000000000000000000000000000000000000000..dd57eea25d8a52b298c49e47f06108cbf8150160 +index 0000000000000000000000000000000000000000..0c0ccc4d1848ee3c440fbe4b924aead09c9947dc --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/region/LinearRegionFile.java -@@ -0,0 +1,330 @@ +@@ -0,0 +1,314 @@ +package org.leavesmc.leaves.region; + +import com.github.luben.zstd.ZstdInputStream; +import com.github.luben.zstd.ZstdOutputStream; +import com.mojang.logging.LogUtils; -+import net.jpountz.lz4.LZ4Compressor; -+import net.jpountz.lz4.LZ4Factory; -+import net.jpountz.lz4.LZ4FastDecompressor; -+import net.minecraft.nbt.CompoundTag; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.chunk.status.ChunkStatus; -+import org.slf4j.Logger; + -+import javax.annotation.Nullable; -+import java.io.*; ++import java.io.BufferedOutputStream; ++import java.io.ByteArrayInputStream; ++import java.io.ByteArrayOutputStream; ++import java.io.DataInputStream; ++import java.io.DataOutputStream; ++import java.io.File; ++import java.io.FileInputStream; ++import java.io.FileOutputStream; ++import java.io.IOException; ++import java.io.InputStream; +import java.nio.ByteBuffer; +import java.nio.file.Files; +import java.nio.file.Path; @@ -573,7 +444,14 @@ index 0000000000000000000000000000000000000000..dd57eea25d8a52b298c49e47f06108cb +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; -+import java.util.concurrent.locks.ReentrantLock; ++import javax.annotation.Nullable; ++ ++import net.jpountz.lz4.LZ4Compressor; ++import net.jpountz.lz4.LZ4Factory; ++import net.jpountz.lz4.LZ4FastDecompressor; ++import net.minecraft.nbt.CompoundTag; ++import net.minecraft.world.level.ChunkPos; ++import org.slf4j.Logger; + +// Powered by LinearPurpur(https://github.com/StupidCraft/LinearPurpur) +public class LinearRegionFile implements AbstractRegionFile, AutoCloseable { @@ -585,19 +463,12 @@ index 0000000000000000000000000000000000000000..dd57eea25d8a52b298c49e47f06108cb + private static final Logger LOGGER = LogUtils.getLogger(); + private static final List SUPPORTED_VERSIONS = Arrays.asList((byte) 1, (byte) 2); + private static final LinearRegionFileFlusher linearRegionFileFlusher = new LinearRegionFileFlusher(); -+ + private final byte[][] buffer = new byte[1024][]; + private final int[] bufferUncompressedSize = new int[1024]; -+ + private final int[] chunkTimestamps = new int[1024]; -+ private final ChunkStatus[] statuses = new ChunkStatus[1024]; -+ + private final LZ4Compressor compressor; + private final LZ4FastDecompressor decompressor; -+ -+ public final ReentrantLock fileLock = new ReentrantLock(true); + private final int compressionLevel; -+ + private final AtomicBoolean markedToSave = new AtomicBoolean(false); + public boolean closed = false; + public Path path; @@ -676,12 +547,16 @@ index 0000000000000000000000000000000000000000..dd57eea25d8a52b298c49e47f06108cb + } + } + -+ public Path getRegionFile() { -+ return this.path; ++ private static int getChunkIndex(int x, int z) { ++ return (x & 31) + ((z & 31) << 5); + } + -+ public ReentrantLock getFileLock() { -+ return this.fileLock; ++ private static int getTimestamp() { ++ return (int) (System.currentTimeMillis() / 1000L); ++ } ++ ++ public Path getPath() { ++ return this.path; + } + + public void flush() throws IOException { @@ -701,12 +576,12 @@ index 0000000000000000000000000000000000000000..dd57eea25d8a52b298c49e47f06108cb + try { + save(); + } catch (IOException e) { -+ LOGGER.error("Failed to flush region file " + path.toAbsolutePath(), e); ++ LOGGER.error("Failed to flush region file {}", path.toAbsolutePath(), e); + } + } + -+ public boolean doesChunkExist(ChunkPos pos) throws Exception { -+ throw new Exception("doesChunkExist is a stub"); ++ public boolean doesChunkExist(ChunkPos pos) { ++ return false; + } + + private synchronized void save() throws IOException { @@ -766,11 +641,6 @@ index 0000000000000000000000000000000000000000..dd57eea25d8a52b298c49e47f06108cb + Files.move(tempFile.toPath(), this.path, StandardCopyOption.REPLACE_EXISTING); + } + -+ -+ public void setStatus(int x, int z, ChunkStatus status) { -+ this.statuses[getChunkIndex(x, z)] = status; -+ } -+ + public synchronized void write(ChunkPos pos, ByteBuffer buffer) { + try { + byte[] b = toByteArray(new ByteArrayInputStream(buffer.array())); @@ -787,7 +657,7 @@ index 0000000000000000000000000000000000000000..dd57eea25d8a52b298c49e47f06108cb + this.chunkTimestamps[index] = getTimestamp(); + this.bufferUncompressedSize[getChunkIndex(pos.x, pos.z)] = uncompressedSize; + } catch (IOException e) { -+ LOGGER.error("Chunk write IOException " + e + " " + this.path); ++ LOGGER.error("Chunk write IOException {} {}", e, this.path); + } + markToSave(); + } @@ -796,21 +666,6 @@ index 0000000000000000000000000000000000000000..dd57eea25d8a52b298c49e47f06108cb + return new DataOutputStream(new BufferedOutputStream(new ChunkBuffer(pos))); + } + -+ private class ChunkBuffer extends ByteArrayOutputStream { -+ -+ private final ChunkPos pos; -+ -+ public ChunkBuffer(ChunkPos chunkcoordintpair) { -+ super(); -+ this.pos = chunkcoordintpair; -+ } -+ -+ public void close() { -+ ByteBuffer bytebuffer = ByteBuffer.wrap(this.buf, 0, this.count); -+ LinearRegionFile.this.write(this.pos, bytebuffer); -+ } -+ } -+ + private byte[] toByteArray(InputStream in) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + byte[] tempBuffer = new byte[4096]; @@ -833,10 +688,6 @@ index 0000000000000000000000000000000000000000..dd57eea25d8a52b298c49e47f06108cb + return null; + } + -+ public ChunkStatus getStatusIfCached(int x, int z) { -+ return this.statuses[getChunkIndex(x, z)]; -+ } -+ + public void clear(ChunkPos pos) { + int i = getChunkIndex(pos.x, pos.z); + this.buffer[i] = null; @@ -853,22 +704,11 @@ index 0000000000000000000000000000000000000000..dd57eea25d8a52b298c49e47f06108cb + if (closed) { + return; + } ++ + closed = true; + flush(); // sync + } + -+ private static int getChunkIndex(int x, int z) { -+ return (x & 31) + ((z & 31) << 5); -+ } -+ -+ private static int getTimestamp() { -+ return (int) (System.currentTimeMillis() / 1000L); -+ } -+ -+ public boolean recalculateHeader() { -+ return false; -+ } -+ + public void setOversized(int x, int z, boolean something) { + } + @@ -879,26 +719,44 @@ index 0000000000000000000000000000000000000000..dd57eea25d8a52b298c49e47f06108cb + public boolean isOversized(int x, int z) { + return false; + } ++ ++ private class ChunkBuffer extends ByteArrayOutputStream { ++ private final ChunkPos pos; ++ ++ public ChunkBuffer(ChunkPos chunkcoordintpair) { ++ super(); ++ this.pos = chunkcoordintpair; ++ } ++ ++ public void close() { ++ ByteBuffer bytebuffer = ByteBuffer.wrap(this.buf, 0, this.count); ++ LinearRegionFile.this.write(this.pos, bytebuffer); ++ } ++ } +} diff --git a/src/main/java/org/leavesmc/leaves/region/LinearRegionFileFlusher.java b/src/main/java/org/leavesmc/leaves/region/LinearRegionFileFlusher.java new file mode 100644 -index 0000000000000000000000000000000000000000..d452d704c54b211be6becd41d12862ba33553c1f +index 0000000000000000000000000000000000000000..7793c1b870bfc223adc121e6bd98361a2e5d7117 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/region/LinearRegionFileFlusher.java -@@ -0,0 +1,53 @@ +@@ -0,0 +1,56 @@ +package org.leavesmc.leaves.region; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; + +import java.util.Queue; -+import java.util.concurrent.*; ++import java.util.concurrent.ExecutorService; ++import java.util.concurrent.Executors; ++import java.util.concurrent.LinkedBlockingQueue; ++import java.util.concurrent.ScheduledExecutorService; ++import java.util.concurrent.TimeUnit; + -+import org.bukkit.Bukkit; +import org.leavesmc.leaves.LeavesConfig; +import org.leavesmc.leaves.LeavesLogger; + +// Powered by LinearPurpur(https://github.com/StupidCraft/LinearPurpur) +public class LinearRegionFileFlusher { ++ + private final Queue savingQueue = new LinkedBlockingQueue<>(); + private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor( + new ThreadFactoryBuilder() @@ -938,7 +796,6 @@ index 0000000000000000000000000000000000000000..d452d704c54b211be6becd41d12862ba + scheduler.shutdown(); + } +} -+ diff --git a/src/main/java/org/leavesmc/leaves/region/RegionFileFormat.java b/src/main/java/org/leavesmc/leaves/region/RegionFileFormat.java new file mode 100644 index 0000000000000000000000000000000000000000..3651246acf3dd786eb6a85c7a846a248962cdd7f diff --git a/patches/server/0125-No-TNT-place-update.patch b/patches/server/0116-No-TNT-place-update.patch similarity index 93% rename from patches/server/0125-No-TNT-place-update.patch rename to patches/server/0116-No-TNT-place-update.patch index 5bd1a44e..3a8db65a 100644 --- a/patches/server/0125-No-TNT-place-update.patch +++ b/patches/server/0116-No-TNT-place-update.patch @@ -5,7 +5,7 @@ Subject: [PATCH] No TNT place update diff --git a/src/main/java/net/minecraft/world/level/block/TntBlock.java b/src/main/java/net/minecraft/world/level/block/TntBlock.java -index a5e1813ba4fee55f469d5c4884124fccecd908d2..52af38f35b47e43fa328f66d969b7b5f6c2cc915 100644 +index a3525ae6d83591664e1456f20d9732a8de0ec326..48412de89948175bab7f7060432afef92cdaa27c 100644 --- a/src/main/java/net/minecraft/world/level/block/TntBlock.java +++ b/src/main/java/net/minecraft/world/level/block/TntBlock.java @@ -49,7 +49,7 @@ public class TntBlock extends Block { diff --git a/patches/server/0117-Servux-Protocol.patch b/patches/server/0117-Servux-Protocol.patch new file mode 100644 index 00000000..69cfec86 --- /dev/null +++ b/patches/server/0117-Servux-Protocol.patch @@ -0,0 +1,583 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: violetc <58360096+s-yh-china@users.noreply.github.com> +Date: Wed, 13 Sep 2023 19:31:20 +0800 +Subject: [PATCH] Servux Protocol + + +diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java +index c97a9096e6b0fcb8f336a745b812b5cf0ea682ed..463c60ab0a5cc697315cbc23651e63cb96b7d90c 100644 +--- a/src/main/java/net/minecraft/server/level/ServerLevel.java ++++ b/src/main/java/net/minecraft/server/level/ServerLevel.java +@@ -1958,6 +1958,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. + } + + this.lastSpawnChunkRadius = i; ++ org.leavesmc.leaves.protocol.servux.ServuxStructuresProtocol.refreshSpawnMetadata = true; // Leaves - servux + } + + public LongSet getForcedChunks() { +diff --git a/src/main/java/org/leavesmc/leaves/protocol/servux/PacketSplitter.java b/src/main/java/org/leavesmc/leaves/protocol/servux/PacketSplitter.java +new file mode 100644 +index 0000000000000000000000000000000000000000..3a0e790f0d8e6866950601f9936984a83a4cdf2c +--- /dev/null ++++ b/src/main/java/org/leavesmc/leaves/protocol/servux/PacketSplitter.java +@@ -0,0 +1,117 @@ ++package org.leavesmc.leaves.protocol.servux; ++ ++import io.netty.buffer.Unpooled; ++import net.minecraft.network.FriendlyByteBuf; ++import net.minecraft.server.level.ServerPlayer; ++ ++import javax.annotation.Nullable; ++import java.util.HashMap; ++import java.util.Map; ++ ++// Powered by Servux(https://github.com/sakura-ryoko/servux) ++ ++/** ++ * Network packet splitter code from QuickCarpet by skyrising ++ * ++ * @author skyrising ++ *

++ * Updated by Sakura to work with newer versions by changing the Reading Session keys, ++ * and using the HANDLER interface to send packets via the Payload system ++ *

++ * Move to Leaves by violetc ++ */ ++public class PacketSplitter { ++ public static final int MAX_TOTAL_PER_PACKET_S2C = 1048576; ++ public static final int MAX_PAYLOAD_PER_PACKET_S2C = MAX_TOTAL_PER_PACKET_S2C - 5; ++ public static final int MAX_TOTAL_PER_PACKET_C2S = 32767; ++ public static final int MAX_PAYLOAD_PER_PACKET_C2S = MAX_TOTAL_PER_PACKET_C2S - 5; ++ public static final int DEFAULT_MAX_RECEIVE_SIZE_C2S = 1048576; ++ public static final int DEFAULT_MAX_RECEIVE_SIZE_S2C = 67108864; ++ ++ private static final Map READING_SESSIONS = new HashMap<>(); ++ ++ public static boolean send(IPacketSplitterHandler handler, FriendlyByteBuf packet, ServerPlayer player) { ++ return send(handler, packet, player, MAX_PAYLOAD_PER_PACKET_S2C); ++ } ++ ++ private static boolean send(IPacketSplitterHandler handler, FriendlyByteBuf packet, ServerPlayer player, int payloadLimit) { ++ int len = packet.writerIndex(); ++ ++ packet.resetReaderIndex(); ++ ++ for (int offset = 0; offset < len; offset += payloadLimit) { ++ int thisLen = Math.min(len - offset, payloadLimit); ++ FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer(thisLen)); ++ ++ buf.resetWriterIndex(); ++ ++ if (offset == 0) { ++ buf.writeVarInt(len); ++ } ++ ++ buf.writeBytes(packet, thisLen); ++ handler.encode(player, buf); ++ } ++ ++ packet.release(); ++ ++ return true; ++ } ++ ++ public static FriendlyByteBuf receive(long key, FriendlyByteBuf buf) { ++ return receive(key, buf, DEFAULT_MAX_RECEIVE_SIZE_S2C); ++ } ++ ++ @Nullable ++ private static FriendlyByteBuf receive(long key, FriendlyByteBuf buf, int maxLength) { ++ return READING_SESSIONS.computeIfAbsent(key, ReadingSession::new).receive(buf, maxLength); ++ } ++ ++ /** ++ * I had to fix the `Pair.of` key mappings, because they were removed from MC; ++ * So I made it into a pre-shared random session 'key' between client and server. ++ * Generated using 'long key = Random.create(Util.getMeasuringTimeMs()).nextLong();' ++ * - ++ * It can be shared to the receiving end via a separate packet; or it can just be ++ * generated randomly on the receiving end per an expected Reading Session. ++ * It needs to be stored and changed for every unique session. ++ */ ++ private static class ReadingSession { ++ private final long key; ++ private int expectedSize = -1; ++ private FriendlyByteBuf received; ++ ++ private ReadingSession(long key) { ++ this.key = key; ++ } ++ ++ @Nullable ++ private FriendlyByteBuf receive(FriendlyByteBuf data, int maxLength) { ++ data.readerIndex(0); ++ // data = PacketUtils.slice(data); ++ ++ if (this.expectedSize < 0) { ++ this.expectedSize = data.readVarInt(); ++ ++ if (this.expectedSize > maxLength) { ++ throw new IllegalArgumentException("Payload too large"); ++ } ++ ++ this.received = new FriendlyByteBuf(Unpooled.buffer(this.expectedSize)); ++ } ++ ++ this.received.writeBytes(data.readBytes(data.readableBytes())); ++ ++ if (this.received.writerIndex() >= this.expectedSize) { ++ READING_SESSIONS.remove(this.key); ++ return this.received; ++ } ++ ++ return null; ++ } ++ } ++ ++ public interface IPacketSplitterHandler { ++ void encode(ServerPlayer player, FriendlyByteBuf buf); ++ } ++} +diff --git a/src/main/java/org/leavesmc/leaves/protocol/servux/ServuxProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/servux/ServuxProtocol.java +new file mode 100644 +index 0000000000000000000000000000000000000000..f80678c0abc38c72b63a32450bd726268d208d6a +--- /dev/null ++++ b/src/main/java/org/leavesmc/leaves/protocol/servux/ServuxProtocol.java +@@ -0,0 +1,17 @@ ++package org.leavesmc.leaves.protocol.servux; ++ ++import io.papermc.paper.ServerBuildInfo; ++import net.minecraft.resources.ResourceLocation; ++import org.jetbrains.annotations.Contract; ++import org.jetbrains.annotations.NotNull; ++ ++public class ServuxProtocol { ++ ++ public static final String PROTOCOL_ID = "servux"; ++ public static final String SERVUX_STRING = "servux-leaves-" + ServerBuildInfo.buildInfo().asString(ServerBuildInfo.StringRepresentation.VERSION_SIMPLE); ++ ++ @Contract("_ -> new") ++ public static @NotNull ResourceLocation id(String path) { ++ return new ResourceLocation(PROTOCOL_ID, path); ++ } ++} +diff --git a/src/main/java/org/leavesmc/leaves/protocol/servux/ServuxStructuresProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/servux/ServuxStructuresProtocol.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b7839e1e8cdd68f5db3e6fe237a767a664659daa +--- /dev/null ++++ b/src/main/java/org/leavesmc/leaves/protocol/servux/ServuxStructuresProtocol.java +@@ -0,0 +1,413 @@ ++package org.leavesmc.leaves.protocol.servux; ++ ++import io.netty.buffer.Unpooled; ++import it.unimi.dsi.fastutil.longs.LongIterator; ++import it.unimi.dsi.fastutil.longs.LongOpenHashSet; ++import it.unimi.dsi.fastutil.longs.LongSet; ++import net.minecraft.core.BlockPos; ++import net.minecraft.nbt.CompoundTag; ++import net.minecraft.nbt.ListTag; ++import net.minecraft.network.FriendlyByteBuf; ++import net.minecraft.resources.ResourceLocation; ++import net.minecraft.server.MinecraftServer; ++import net.minecraft.server.level.ServerLevel; ++import net.minecraft.server.level.ServerPlayer; ++import net.minecraft.world.level.ChunkPos; ++import net.minecraft.world.level.GameRules; ++import net.minecraft.world.level.Level; ++import net.minecraft.world.level.chunk.ChunkAccess; ++import net.minecraft.world.level.chunk.status.ChunkStatus; ++import net.minecraft.world.level.levelgen.structure.Structure; ++import net.minecraft.world.level.levelgen.structure.StructureStart; ++import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext; ++import org.jetbrains.annotations.NotNull; ++import org.leavesmc.leaves.LeavesConfig; ++import org.leavesmc.leaves.LeavesLogger; ++import org.leavesmc.leaves.protocol.core.LeavesCustomPayload; ++import org.leavesmc.leaves.protocol.core.LeavesProtocol; ++import org.leavesmc.leaves.protocol.core.ProtocolHandler; ++import org.leavesmc.leaves.protocol.core.ProtocolUtils; ++ ++import java.util.HashMap; ++import java.util.HashSet; ++import java.util.Map; ++import java.util.Set; ++import java.util.UUID; ++import java.util.concurrent.ConcurrentHashMap; ++ ++// Powered by Servux(https://github.com/sakura-ryoko/servux) ++ ++@LeavesProtocol(namespace = "servux") ++public class ServuxStructuresProtocol { ++ ++ public static final int PROTOCOL_VERSION = 2; ++ ++ private static final int updateInterval = 40; ++ private static final int timeout = 30 * 20; ++ ++ public static boolean refreshSpawnMetadata = false; ++ private static int retainDistance; ++ ++ public static final ResourceLocation CHANNEL = ServuxProtocol.id("structures"); ++ ++ private static final Map players = new ConcurrentHashMap<>(); ++ private static final Map> timeouts = new HashMap<>(); ++ ++ @ProtocolHandler.PayloadReceiver(payload = StructuresPayload.class, payloadId = "structures") ++ public static void onPacketReceive(ServerPlayer player, StructuresPayload payload) { ++ if (!LeavesConfig.servuxProtocol) { ++ return; ++ } ++ ++ switch (payload.packetType()) { ++ case PACKET_C2S_STRUCTURES_REGISTER -> onPlayerSubscribed(player); ++ case PACKET_C2S_REQUEST_SPAWN_METADATA -> refreshSpawnMetadata(player); ++ case PACKET_C2S_STRUCTURES_UNREGISTER -> { ++ onPlayerLoggedOut(player); ++ refreshSpawnMetadata(player); ++ } ++ } ++ } ++ ++ @ProtocolHandler.PlayerLeave ++ public static void onPlayerLoggedOut(@NotNull ServerPlayer player) { ++ if (!LeavesConfig.servuxProtocol) { ++ return; ++ } ++ ++ players.remove(player.getId()); ++ } ++ ++ @ProtocolHandler.Ticker ++ public static void tick() { ++ if (LeavesConfig.servuxProtocol) { ++ return; ++ } ++ ++ MinecraftServer server = MinecraftServer.getServer(); ++ int tickCounter = server.getTickCount(); ++ if ((tickCounter % updateInterval) == 0) { ++ retainDistance = server.getPlayerList().getViewDistance() + 2; ++ for (ServerPlayer player : players.values()) { ++ if (refreshSpawnMetadata) { ++ refreshSpawnMetadata(player); ++ } ++ ++ // TODO DimensionChange ++ refreshTrackedChunks(player, tickCounter); ++ } ++ ++ if (refreshSpawnMetadata) { ++ refreshSpawnMetadata = false; ++ } ++ } ++ } ++ ++ public static void onPlayerSubscribed(@NotNull ServerPlayer player) { ++ if (!players.containsKey(player.getId())) { ++ players.put(player.getId(), player); ++ } else { ++ LeavesLogger.LOGGER.warning(player.getScoreboardName() + " re-register servux:structures"); ++ } ++ ++ CompoundTag tag = new CompoundTag(); ++ tag.putString("name", "structure_bounding_boxes"); ++ tag.putString("id", CHANNEL.toString()); ++ tag.putInt("version", PROTOCOL_VERSION); ++ tag.putString("servux", ServuxProtocol.SERVUX_STRING); ++ tag.putInt("timeout", timeout); ++ ++ MinecraftServer server = MinecraftServer.getServer(); ++ BlockPos spawnPos = server.overworld().levelData.getSpawnPos(); ++ tag.putInt("spawnPosX", spawnPos.getX()); ++ tag.putInt("spawnPosY", spawnPos.getY()); ++ tag.putInt("spawnPosZ", spawnPos.getZ()); ++ tag.putInt("spawnChunkRadius", server.getGameRules().getInt(GameRules.RULE_SPAWN_CHUNK_RADIUS)); ++ ++ sendPacket(player, new StructuresPayload(StructuresPayloadType.PACKET_S2C_METADATA, tag)); ++ initialSyncStructures(player, player.moonrise$getViewDistanceHolder().getViewDistances().sendViewDistance() + 2, server.getTickCount()); ++ } ++ ++ public static void refreshSpawnMetadata(ServerPlayer player) { ++ CompoundTag tag = new CompoundTag(); ++ tag.putString("id", CHANNEL.toString()); ++ tag.putString("servux", ServuxProtocol.SERVUX_STRING); ++ ++ MinecraftServer server = MinecraftServer.getServer(); ++ BlockPos spawnPos = server.overworld().levelData.getSpawnPos(); ++ tag.putInt("spawnPosX", spawnPos.getX()); ++ tag.putInt("spawnPosY", spawnPos.getY()); ++ tag.putInt("spawnPosZ", spawnPos.getZ()); ++ tag.putInt("spawnChunkRadius", server.getGameRules().getInt(GameRules.RULE_SPAWN_CHUNK_RADIUS)); ++ ++ sendPacket(player, new StructuresPayload(StructuresPayloadType.PACKET_S2C_SPAWN_METADATA, tag)); ++ } ++ ++ public static void initialSyncStructures(ServerPlayer player, int chunkRadius, int tickCounter) { ++ UUID uuid = player.getUUID(); ++ ChunkPos center = player.getLastSectionPos().chunk(); ++ Map references = getStructureReferences(player.serverLevel(), center, chunkRadius); ++ ++ timeouts.remove(uuid); ++ ++ sendStructures(player, references, tickCounter); ++ } ++ ++ public static Map getStructureReferences(ServerLevel world, ChunkPos center, int chunkRadius) { ++ Map references = new HashMap<>(); ++ ++ for (int cx = center.x - chunkRadius; cx <= center.x + chunkRadius; ++cx) { ++ for (int cz = center.z - chunkRadius; cz <= center.z + chunkRadius; ++cz) { ++ getReferencesFromChunk(cx, cz, world, references); ++ } ++ } ++ ++ return references; ++ } ++ ++ public static void getReferencesFromChunk(int chunkX, int chunkZ, Level world, Map references) { ++ if (!world.hasChunk(chunkX, chunkZ)) { ++ return; ++ } ++ ++ ChunkAccess chunk = world.getChunk(chunkX, chunkZ, ChunkStatus.STRUCTURE_STARTS, false); ++ ++ if (chunk == null) { ++ return; ++ } ++ ++ for (Map.Entry entry : chunk.getAllReferences().entrySet()) { ++ Structure feature = entry.getKey(); ++ LongSet startChunks = entry.getValue(); ++ ++ // TODO add an option && feature != StructureFeature.MINESHAFT (?) ++ if (!startChunks.isEmpty()) { ++ references.merge(feature, startChunks, (oldSet, entrySet) -> { ++ LongOpenHashSet newSet = new LongOpenHashSet(oldSet); ++ newSet.addAll(entrySet); ++ return newSet; ++ }); ++ } ++ } ++ } ++ ++ public static void sendStructures(ServerPlayer player, Map references, int tickCounter) { ++ ServerLevel world = player.serverLevel(); ++ Map starts = getStructureStarts(world, references); ++ ++ if (!starts.isEmpty()) { ++ addOrRefreshTimeouts(player.getUUID(), references, tickCounter); ++ ++ ListTag structureList = getStructureList(starts, world); ++ ++ if (players.containsKey(player.getId())) { ++ CompoundTag test = new CompoundTag(); ++ test.put("Structures", structureList.copy()); ++ sendPacket(player, new StructuresPayload(StructuresPayloadType.PACKET_S2C_STRUCTURE_DATA_START, test)); ++ } ++ } ++ } ++ ++ public static ListTag getStructureList(Map structures, ServerLevel world) { ++ ListTag list = new ListTag(); ++ StructurePieceSerializationContext ctx = StructurePieceSerializationContext.fromLevel(world); ++ ++ for (Map.Entry entry : structures.entrySet()) { ++ ChunkPos pos = entry.getKey(); ++ list.add(entry.getValue().createTag(ctx, pos)); ++ } ++ ++ return list; ++ } ++ ++ public static Map getStructureStarts(ServerLevel world, Map references) { ++ Map starts = new HashMap<>(); ++ ++ for (Map.Entry entry : references.entrySet()) { ++ Structure structure = entry.getKey(); ++ LongSet startChunks = entry.getValue(); ++ LongIterator iter = startChunks.iterator(); ++ ++ while (iter.hasNext()) { ++ ChunkPos pos = new ChunkPos(iter.nextLong()); ++ ++ if (!world.hasChunk(pos.x, pos.z)) { ++ continue; ++ } ++ ++ ChunkAccess chunk = world.getChunk(pos.x, pos.z, ChunkStatus.STRUCTURE_STARTS, false); ++ ++ if (chunk == null) { ++ continue; ++ } ++ ++ StructureStart start = chunk.getStartForStructure(structure); ++ ++ if (start != null) { ++ starts.put(pos, start); ++ } ++ } ++ } ++ ++ return starts; ++ } ++ ++ public static void refreshTrackedChunks(ServerPlayer player, int tickCounter) { ++ UUID uuid = player.getUUID(); ++ Map map = timeouts.get(uuid); ++ ++ if (map != null) { ++ sendAndRefreshExpiredStructures(player, map, tickCounter); ++ } ++ } ++ ++ public static void sendAndRefreshExpiredStructures(ServerPlayer player, Map map, int tickCounter) { ++ Set positionsToUpdate = new HashSet<>(); ++ ++ for (Map.Entry entry : map.entrySet()) { ++ Timeout out = entry.getValue(); ++ ++ if (out.needsUpdate(tickCounter, timeout)) { ++ positionsToUpdate.add(entry.getKey()); ++ } ++ } ++ ++ if (!positionsToUpdate.isEmpty()) { ++ ServerLevel world = player.serverLevel(); ++ ChunkPos center = player.getLastSectionPos().chunk(); ++ Map references = new HashMap<>(); ++ ++ for (ChunkPos pos : positionsToUpdate) { ++ if (isOutOfRange(pos, center)) { ++ map.remove(pos); ++ } else { ++ getReferencesFromChunk(pos.x, pos.z, world, references); ++ ++ Timeout timeout = map.get(pos); ++ ++ if (timeout != null) { ++ timeout.setLastSync(tickCounter); ++ } ++ } ++ } ++ ++ if (!references.isEmpty()) { ++ sendStructures(player, references, tickCounter); ++ } ++ } ++ } ++ ++ protected static boolean isOutOfRange(ChunkPos pos, ChunkPos center) { ++ return Math.abs(pos.x - center.x) > retainDistance || Math.abs(pos.z - center.z) > retainDistance; ++ } ++ ++ public static void addOrRefreshTimeouts(final UUID uuid, final Map references, final int tickCounter) { ++ Map map = timeouts.computeIfAbsent(uuid, (u) -> new HashMap<>()); ++ ++ for (LongSet chunks : references.values()) { ++ for (Long chunkPosLong : chunks) { ++ final ChunkPos pos = new ChunkPos(chunkPosLong); ++ map.computeIfAbsent(pos, (p) -> new Timeout(tickCounter)).setLastSync(tickCounter); ++ } ++ } ++ } ++ ++ public enum StructuresPayloadType { ++ PACKET_S2C_METADATA(1), ++ PACKET_S2C_STRUCTURE_DATA(2), ++ PACKET_C2S_STRUCTURES_REGISTER(3), ++ PACKET_C2S_STRUCTURES_UNREGISTER(4), ++ PACKET_S2C_STRUCTURE_DATA_START(5), ++ PACKET_S2C_SPAWN_METADATA(10), ++ PACKET_C2S_REQUEST_SPAWN_METADATA(11); ++ ++ private static final class Helper { ++ static Map ID_TO_TYPE = new HashMap<>(); ++ } ++ ++ public final int type; ++ ++ StructuresPayloadType(int type) { ++ this.type = type; ++ Helper.ID_TO_TYPE.put(type, this); ++ } ++ ++ public static StructuresPayloadType fromId(int id) { ++ return Helper.ID_TO_TYPE.get(id); ++ } ++ } ++ ++ public record StructuresPayload(StructuresPayloadType packetType, CompoundTag nbt, FriendlyByteBuf buffer) implements LeavesCustomPayload { ++ ++ public StructuresPayload(StructuresPayloadType packetType, CompoundTag nbt) { ++ this(packetType, nbt, null); ++ } ++ ++ public StructuresPayload(StructuresPayloadType packetType, FriendlyByteBuf buffer) { ++ this(packetType, new CompoundTag(), buffer); ++ } ++ ++ @New ++ private static StructuresPayload decode(ResourceLocation id, FriendlyByteBuf buf) { ++ int i = buf.readVarInt(); ++ StructuresPayloadType type = StructuresPayloadType.fromId(i); ++ ++ if (type == null) { ++ throw new IllegalStateException("invalid packet type received"); ++ } else if (type.equals(StructuresPayloadType.PACKET_S2C_STRUCTURE_DATA)) { ++ return new StructuresPayload(type, new FriendlyByteBuf(buf.readBytes(buf.readableBytes()))); ++ } else { ++ return new StructuresPayload(type, buf.readNbt()); ++ } ++ } ++ ++ @Override ++ public void write(FriendlyByteBuf buf) { ++ buf.writeVarInt(this.packetType.type); ++ if (this.packetType.equals(StructuresPayloadType.PACKET_S2C_STRUCTURE_DATA)) { ++ buf.writeBytes(this.buffer.readBytes(this.buffer.readableBytes())); ++ } else { ++ buf.writeNbt(this.nbt); ++ } ++ } ++ ++ @Override ++ public ResourceLocation id() { ++ return CHANNEL; ++ } ++ } ++ ++ public static class Timeout { ++ private int lastSync; ++ ++ public Timeout(int currentTick) { ++ this.lastSync = currentTick; ++ } ++ ++ public boolean needsUpdate(int currentTick, int timeout) { ++ return currentTick - this.lastSync >= timeout; ++ } ++ ++ public void setLastSync(int tickCounter) { ++ this.lastSync = tickCounter; ++ } ++ } ++ ++ public static void sendPacket(ServerPlayer player, StructuresPayload payload) { ++ if (!LeavesConfig.servuxProtocol) { ++ return; ++ } ++ ++ if (payload.packetType() == StructuresPayloadType.PACKET_S2C_STRUCTURE_DATA_START) { ++ FriendlyByteBuf buffer = new FriendlyByteBuf(Unpooled.buffer()); ++ buffer.writeNbt(payload.nbt()); ++ PacketSplitter.send(ServuxStructuresProtocol::sendWithSplitter, buffer, player); ++ } else { ++ ProtocolUtils.sendPayloadPacket(player, payload); ++ } ++ } ++ ++ private static void sendWithSplitter(ServerPlayer player, FriendlyByteBuf buf) { ++ sendPacket(player, new StructuresPayload(StructuresPayloadType.PACKET_S2C_STRUCTURE_DATA, buf)); ++ } ++} diff --git a/patches/server/0118-Placing-locked-hopper-no-longer-send-NC-updates.patch b/patches/server/0118-Placing-locked-hopper-no-longer-send-NC-updates.patch new file mode 100644 index 00000000..caa4d66c --- /dev/null +++ b/patches/server/0118-Placing-locked-hopper-no-longer-send-NC-updates.patch @@ -0,0 +1,23 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Fortern +Date: Sat, 20 Jan 2024 02:50:56 +0800 +Subject: [PATCH] Placing locked hopper no longer send NC updates + + +diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java +index b4e10f82edbbe5301ddcf13f33f2f857eb2858a9..4a11b870da00d4802a29a174c7554d23931019da 100644 +--- a/src/main/java/net/minecraft/world/level/Level.java ++++ b/src/main/java/net/minecraft/world/level/Level.java +@@ -710,7 +710,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl + } + + if ((i & 1) != 0) { +- this.blockUpdated(blockposition, iblockdata1.getBlock()); ++ // Leaves start - Placing locked hopper doesn't send NC updates. ++ if (!(iblockdata.getBlock() instanceof net.minecraft.world.level.block.HopperBlock) || iblockdata.getValue(net.minecraft.world.level.block.HopperBlock.ENABLED)) { ++ this.blockUpdated(blockposition, iblockdata1.getBlock()); ++ } ++ // Leaves end - Placing locked hopper doesn't send NC updates. + if (!this.isClientSide && iblockdata.hasAnalogOutputSignal()) { + this.updateNeighbourForOutputSignal(blockposition, newBlock.getBlock()); + } diff --git a/patches/server/0127-Renewable-deepslate.patch b/patches/server/0119-Renewable-deepslate.patch similarity index 100% rename from patches/server/0127-Renewable-deepslate.patch rename to patches/server/0119-Renewable-deepslate.patch diff --git a/patches/server/0128-Renewable-sponges.patch b/patches/server/0120-Renewable-sponges.patch similarity index 91% rename from patches/server/0128-Renewable-sponges.patch rename to patches/server/0120-Renewable-sponges.patch index 5d1094d2..3a54b7bf 100644 --- a/patches/server/0128-Renewable-sponges.patch +++ b/patches/server/0120-Renewable-sponges.patch @@ -5,15 +5,14 @@ Subject: [PATCH] Renewable sponges diff --git a/src/main/java/net/minecraft/world/entity/monster/Guardian.java b/src/main/java/net/minecraft/world/entity/monster/Guardian.java -index 6c2e2fd5826a5f8070502e20d1d140c3d70bd0d3..661a589b8b2e624a24ae8b1405d1b116a9220844 100644 +index 5df07b59ff6e39687e361d89d7764381ca3ce9ca..465a46f497d726303859ca31688a848699441234 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Guardian.java +++ b/src/main/java/net/minecraft/world/entity/monster/Guardian.java -@@ -345,6 +345,30 @@ public class Guardian extends Monster { +@@ -345,6 +345,28 @@ public class Guardian extends Monster { } + // Leaves start - renewable sponges -+ + @Override + public void thunderHit(net.minecraft.server.level.ServerLevel world, net.minecraft.world.entity.LightningBolt lightning) { + if (org.leavesmc.leaves.LeavesConfig.renewableSponges && !this.isRemoved() && !(this instanceof ElderGuardian)) { @@ -33,7 +32,6 @@ index 6c2e2fd5826a5f8070502e20d1d140c3d70bd0d3..661a589b8b2e624a24ae8b1405d1b116 + super.thunderHit(world, lightning); + } + } -+ + // Leaves end - renewable sponges + private static class GuardianMoveControl extends MoveControl { diff --git a/patches/server/0129-Renewable-coral.patch b/patches/server/0121-Renewable-coral.patch similarity index 91% rename from patches/server/0129-Renewable-coral.patch rename to patches/server/0121-Renewable-coral.patch index be0351d9..2e8940a3 100644 --- a/patches/server/0129-Renewable-coral.patch +++ b/patches/server/0121-Renewable-coral.patch @@ -56,25 +56,21 @@ index 4c4aa2a63be84ff614a3dc0db2864266755545a2..208685f28509f92483f1efc89302e7a9 + // Leaves end - renewable coral } diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/CoralFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/CoralFeature.java -index 7bc5ff8eb1174834dcc27363af4a5cef19017b3d..e2fc5f9c5cc4ce6b5c1a0d0c43b753c1ca87bf72 100644 +index 7bc5ff8eb1174834dcc27363af4a5cef19017b3d..790686428b01127d0f94e044f0ec4bff4127f79e 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/feature/CoralFeature.java +++ b/src/main/java/net/minecraft/world/level/levelgen/feature/CoralFeature.java -@@ -31,6 +31,12 @@ public abstract class CoralFeature extends Feature { +@@ -31,7 +31,7 @@ public abstract class CoralFeature extends Feature { return !optional.isEmpty() && this.placeFeature(worldGenLevel, randomSource, blockPos, optional.get().defaultBlockState()); } -+ // Leaves start - renewable coral -+ public boolean growSpecific(LevelAccessor world, RandomSource random, BlockPos pos, BlockState state) { -+ return placeFeature(world, random, pos, state); -+ } -+ // Leaves end - renewable coral -+ - protected abstract boolean placeFeature(LevelAccessor world, RandomSource random, BlockPos pos, BlockState state); +- protected abstract boolean placeFeature(LevelAccessor world, RandomSource random, BlockPos pos, BlockState state); ++ public abstract boolean placeFeature(LevelAccessor world, RandomSource random, BlockPos pos, BlockState state); // Leaves - protected -> public protected boolean placeCoralBlock(LevelAccessor world, RandomSource random, BlockPos pos, BlockState state) { + BlockPos blockPos = pos.above(); diff --git a/src/main/java/org/leavesmc/leaves/util/FertilizableCoral.java b/src/main/java/org/leavesmc/leaves/util/FertilizableCoral.java new file mode 100644 -index 0000000000000000000000000000000000000000..d7110e2def699626939f6fdeb0e8c614e51346d2 +index 0000000000000000000000000000000000000000..f1cad30bd4c937b137305e790e1d372a123170a6 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/util/FertilizableCoral.java @@ -0,0 +1,72 @@ @@ -138,7 +134,7 @@ index 0000000000000000000000000000000000000000..d7110e2def699626939f6fdeb0e8c614 + } + worldIn.setBlock(pos, Blocks.WATER.defaultBlockState(), Block.UPDATE_NONE); + -+ if (!coral.growSpecific(worldIn, random, pos, properBlock)) { ++ if (!coral.placeFeature(worldIn, random, pos, properBlock)) { + worldIn.setBlock(pos, blockUnder, 3); + } else { + if (worldIn.random.nextInt(10) == 0) { diff --git a/patches/server/0130-Fast-resume.patch b/patches/server/0122-Fast-resume.patch similarity index 77% rename from patches/server/0130-Fast-resume.patch rename to patches/server/0122-Fast-resume.patch index 2f411731..8e558873 100644 --- a/patches/server/0130-Fast-resume.patch +++ b/patches/server/0122-Fast-resume.patch @@ -4,37 +4,31 @@ Date: Thu, 25 Jan 2024 01:16:49 +0800 Subject: [PATCH] Fast resume -diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java -index b133b977bc7d452b5032809f84f8ac2ff96ae5bb..be8280d421a483b354f88d60117002181abe570b 100644 ---- a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java -+++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java -@@ -566,6 +566,56 @@ public final class ChunkHolderManager { +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java +index 3d902f382977a194e09986419391c3ca1568885c..37201582d1bb3ed109f0efc6830a76173fc066a9 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java +@@ -581,6 +581,49 @@ public final class ChunkHolderManager { } } + // Leaves start - add custom ticket -+ public boolean addTicketAtLevelCustom(final Ticket ticket, final long chunk, final boolean lock) { -+ final long removeDelay = ticket.removeDelay; -+ if (ticket.getTicketLevel() > MAX_TICKET_LEVEL) { -+ return false; -+ } ++ public void addTicketAtLevelCustom(final Ticket ticket, final long chunk, final boolean lock) { ++ final long removeDelay = ticket.moonrise$getRemoveDelay(); + + final int chunkX = CoordinateUtils.getChunkX(chunk); + final int chunkZ = CoordinateUtils.getChunkZ(chunk); -+ final RegionFileIOThread.ChunkCoordinate chunkCoord = new RegionFileIOThread.ChunkCoordinate(chunk); + + final ReentrantAreaLock.Node ticketLock = lock ? this.ticketLockArea.lock(chunkX, chunkZ) : null; + try { -+ final SortedArraySet> ticketsAtChunk = this.tickets.computeIfAbsent(chunkCoord, (final RegionFileIOThread.ChunkCoordinate keyInMap) -> { -+ return SortedArraySet.create(4); -+ }); ++ final SortedArraySet> ticketsAtChunk = this.tickets.computeIfAbsent(chunk, (final long keyInMap) -> SortedArraySet.create(4)); + + final int levelBefore = getTicketLevelAt(ticketsAtChunk); -+ final Ticket current = (Ticket)ticketsAtChunk.replace(ticket); ++ final Ticket current = (Ticket)((ChunkSystemSortedArraySet>)ticketsAtChunk).moonrise$replace(ticket); + final int levelAfter = getTicketLevelAt(ticketsAtChunk); + + if (current != ticket) { -+ final long oldRemoveDelay = current.removeDelay; ++ final long oldRemoveDelay = ((ChunkSystemTicket) current).moonrise$getRemoveDelay(); + if (removeDelay != oldRemoveDelay) { + if (oldRemoveDelay != NO_TIMEOUT_MARKER && removeDelay == NO_TIMEOUT_MARKER) { + this.removeExpireCount(chunkX, chunkZ); @@ -53,7 +47,6 @@ index b133b977bc7d452b5032809f84f8ac2ff96ae5bb..be8280d421a483b354f88d6011700218 + this.updateTicketLevel(chunk, levelAfter); + } + -+ return current == ticket; + } finally { + if (ticketLock != null) { + this.ticketLockArea.unlock(ticketLock); @@ -66,10 +59,10 @@ index b133b977bc7d452b5032809f84f8ac2ff96ae5bb..be8280d421a483b354f88d6011700218 return this.removeTicketAtLevel(type, CoordinateUtils.getChunkKey(chunkPos), level, identifier); } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 8bb6f9d26c8a24638ed64e8726b3b11dcccde9c8..0e2ebd43304a54a0367c89037bf842d22afe13a5 100644 +index ebbb18d2e741e535dbfeca364d0f2d0d27a96c7d..b35455b6499c5f31137673922f45ad1f941ecf08 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -669,6 +669,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop> NEED_SAVED = Set.of(TicketType.PLAYER, TicketType.PORTAL, TicketType.ENTITY_LOAD, TicketType.POI_LOAD); ++ private static final Set> NEED_SAVED = Set.of(TicketType.PLAYER, TicketType.PORTAL, RegionizedPlayerChunkLoader.PLAYER_TICKET); + + public static void tryToLoadTickets() { + if (!LeavesConfig.fastResume) { @@ -135,9 +129,11 @@ index 0000000000000000000000000000000000000000..47154500a4375ee8bfd45d5dbe372425 + try (BufferedReader bfr = Files.newBufferedReader(file.toPath(), StandardCharsets.UTF_8)) { + JsonObject json = new Gson().fromJson(bfr, JsonObject.class); + loadSavedChunkTickets(json); -+ file.delete(); ++ if (!file.delete()) { ++ throw new IOException(); ++ } + } catch (IOException e) { -+ e.printStackTrace(); ++ LeavesLogger.LOGGER.severe("Failed to load saved chunk tickets file", e); + } + } + } @@ -148,24 +144,22 @@ index 0000000000000000000000000000000000000000..47154500a4375ee8bfd45d5dbe372425 + } + + File file = MinecraftServer.getServer().getWorldPath(LevelResource.ROOT).resolve("chunk_tickets.leaves.json").toFile(); -+ if (!file.isFile()) { -+ try { -+ file.createNewFile(); -+ } catch (IOException e) { -+ e.printStackTrace(); -+ } -+ } + try (BufferedWriter bfw = Files.newBufferedWriter(file.toPath(), StandardCharsets.UTF_8)) { + bfw.write(new Gson().toJson(getSavedChunkTickets())); + } catch (IOException e) { -+ e.printStackTrace(); ++ LeavesLogger.LOGGER.severe("Failed to save chunk tickets file", e); + } + } + + public static void loadSavedChunkTickets(JsonObject json) { + MinecraftServer server = MinecraftServer.getServer(); + for (String worldKey : json.keySet()) { -+ ServerLevel level = server.getLevel(ResourceKey.create(Registries.DIMENSION, new ResourceLocation(worldKey))); ++ ResourceLocation dimensionKey = ResourceLocation.tryParse(worldKey); ++ if (dimensionKey == null) { ++ continue; ++ } ++ ++ ServerLevel level = server.getLevel(ResourceKey.create(Registries.DIMENSION, dimensionKey)); + if (level == null) { + continue; + } @@ -223,7 +217,7 @@ index 0000000000000000000000000000000000000000..47154500a4375ee8bfd45d5dbe372425 + JsonObject json = new JsonObject(); + json.addProperty("type", ticket.getType().toString()); + json.addProperty("ticketLevel", ticket.getTicketLevel()); -+ json.addProperty("removeDelay", ticket.removeDelay); ++ json.addProperty("removeDelay", ticket.moonrise$getRemoveDelay()); + if (ticket.key instanceof BlockPos pos) { + json.addProperty("key", pos.asLong()); + } else if (ticket.key instanceof ChunkPos pos) { @@ -246,16 +240,8 @@ index 0000000000000000000000000000000000000000..47154500a4375ee8bfd45d5dbe372425 + ticketType = TicketType.PORTAL; + key = BlockPos.of(json.get("key").getAsLong()); + } -+ case "entity_load" -> { -+ ticketType = TicketType.ENTITY_LOAD; -+ key = json.get("key").getAsLong(); -+ } -+ case "poi_load" -> { -+ ticketType = TicketType.POI_LOAD; -+ key = json.get("key").getAsLong(); -+ } -+ case "region_player_ticket" -> { -+ ticketType = RegionizedPlayerChunkLoader.REGION_PLAYER_TICKET; ++ case "player_ticket" -> { ++ ticketType = RegionizedPlayerChunkLoader.PLAYER_TICKET; + key = json.get("key").getAsLong(); + } + } @@ -266,7 +252,9 @@ index 0000000000000000000000000000000000000000..47154500a4375ee8bfd45d5dbe372425 + + int ticketLevel = json.get("ticketLevel").getAsInt(); + long removeDelay = json.get("removeDelay").getAsLong(); ++ Ticket ticket = new Ticket<>((TicketType) ticketType, ticketLevel, (T) key); ++ ticket.moonrise$setRemoveDelay(removeDelay); + -+ return new Ticket((TicketType) ticketType, ticketLevel, (T) key, removeDelay); ++ return ticket; + } +} diff --git a/patches/server/0131-Vanilla-hopper.patch b/patches/server/0123-Vanilla-hopper.patch similarity index 96% rename from patches/server/0131-Vanilla-hopper.patch rename to patches/server/0123-Vanilla-hopper.patch index 46cfb419..081cc7d7 100644 --- a/patches/server/0131-Vanilla-hopper.patch +++ b/patches/server/0123-Vanilla-hopper.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Vanilla hopper This is a temporary solution designed to attempt to restore the vanilla behavior of the funnel while preserving optimizations as much as possible. It should ultimately be replaced by the optimization solution provided by lithium. diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java -index 741ab2ffc8e4f40f43e24fed3b6d55580a3fdaca..1e5d41e6d0cb6af15d6a7771d9ee1bc9dc8dffac 100644 +index 76b3e6622aae61c058af2a0e84fa03082e968c79..7bdd056a25b0cfbd9e7f9e36ba0827ac606f53a7 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java -@@ -290,36 +290,49 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen +@@ -305,36 +305,49 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen ItemStack movedItem = origItemStack; final int originalItemCount = origItemStack.getCount(); final int movedItemCount = Math.min(level.spigotConfig.hopperAmount, originalItemCount); diff --git a/patches/server/0132-Force-minecraft-command.patch b/patches/server/0124-Force-minecraft-command.patch similarity index 64% rename from patches/server/0132-Force-minecraft-command.patch rename to patches/server/0124-Force-minecraft-command.patch index ffe387cd..1b7ed0ec 100644 --- a/patches/server/0132-Force-minecraft-command.patch +++ b/patches/server/0124-Force-minecraft-command.patch @@ -27,16 +27,3 @@ index 90ed57a7fbcd0625b64084347460e9864216f610..1dadec002e620b3e4906ab3381944cc9 + } + // Leaves end - force minecraft command } -diff --git a/src/main/java/org/leavesmc/leaves/LeavesConfig.java b/src/main/java/org/leavesmc/leaves/LeavesConfig.java -index 161870271e000effffe87c55c4d1d3e242e19c57..f74e84d68b043de8c9180d58f7f60da7fb19beaf 100644 ---- a/src/main/java/org/leavesmc/leaves/LeavesConfig.java -+++ b/src/main/java/org/leavesmc/leaves/LeavesConfig.java -@@ -853,7 +853,7 @@ public final class LeavesConfig { - public static boolean bstatsPrivacyMode = false; - - @GlobalConfig(name = "force-minecraft-command", category = "misc") -- public static boolean forceMinecraftCommand = true; -+ public static boolean forceMinecraftCommand = false; - - @GlobalConfig(name = "leaves-packet-event", category = "misc") - public static boolean leavesPacketEvent = true; diff --git a/patches/server/0124-Protection-stacking.patch b/patches/server/0124-Protection-stacking.patch deleted file mode 100644 index 3a1d8fcd..00000000 --- a/patches/server/0124-Protection-stacking.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: violetc <58360096+s-yh-china@users.noreply.github.com> -Date: Mon, 15 Jan 2024 20:47:05 +0800 -Subject: [PATCH] Protection stacking - - -diff --git a/src/main/java/net/minecraft/world/item/enchantment/ProtectionEnchantment.java b/src/main/java/net/minecraft/world/item/enchantment/ProtectionEnchantment.java -index 8f30cdd7f9f43e5a1d100f6c6d25fb54475289f1..d3942f1df56f8e265179ea81c7bafdc3dfe9e40a 100644 ---- a/src/main/java/net/minecraft/world/item/enchantment/ProtectionEnchantment.java -+++ b/src/main/java/net/minecraft/world/item/enchantment/ProtectionEnchantment.java -@@ -32,6 +32,11 @@ public class ProtectionEnchantment extends Enchantment { - - @Override - public boolean checkCompatibility(Enchantment other) { -+ // Leaves start - protection stacking -+ if (org.leavesmc.leaves.LeavesConfig.protectionStacking) { -+ return super.checkCompatibility(other); -+ } -+ // Leaves end - protection stacking - return other instanceof ProtectionEnchantment protectionEnchantment - ? this.type != protectionEnchantment.type - && (this.type == ProtectionEnchantment.Type.FALL || protectionEnchantment.type == ProtectionEnchantment.Type.FALL) diff --git a/patches/server/0133-Fix-falling-block-s-block-location.patch b/patches/server/0125-Fix-falling-block-s-block-location.patch similarity index 87% rename from patches/server/0133-Fix-falling-block-s-block-location.patch rename to patches/server/0125-Fix-falling-block-s-block-location.patch index 29732432..5d33c8c9 100644 --- a/patches/server/0133-Fix-falling-block-s-block-location.patch +++ b/patches/server/0125-Fix-falling-block-s-block-location.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix falling block's block location diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 2d40a0b3dc849a57abc4346aad2c01f3dc3e5d98..3db458324e56e9c3e8a6fe7916f31cb17b355e2b 100644 +index 4f984341827634d7a5eef449657c513bf8a70a0b..3431c34b719dafd29551079afed23985e72a0f65 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -4872,6 +4872,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4671,6 +4671,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess int j = Mth.floor(y); int k = Mth.floor(z); diff --git a/patches/server/0134-Fix-NPE-during-creating-GUI-graph.patch b/patches/server/0126-Fix-NPE-during-creating-GUI-graph.patch similarity index 100% rename from patches/server/0134-Fix-NPE-during-creating-GUI-graph.patch rename to patches/server/0126-Fix-NPE-during-creating-GUI-graph.patch diff --git a/patches/server/0126-Placing-locked-hopper-no-longer-send-NC-updates.patch b/patches/server/0126-Placing-locked-hopper-no-longer-send-NC-updates.patch deleted file mode 100644 index 1d71f9fb..00000000 --- a/patches/server/0126-Placing-locked-hopper-no-longer-send-NC-updates.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Fortern -Date: Sat, 20 Jan 2024 02:50:56 +0800 -Subject: [PATCH] Placing locked hopper no longer send NC updates - - -diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index ac9647b7232a860b87c0a15aa7971e243d311152..c9e7f2b93a3f5934710864310191433fe6d248d2 100644 ---- a/src/main/java/net/minecraft/world/level/Level.java -+++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -54,6 +54,7 @@ import net.minecraft.world.level.biome.BiomeManager; - import net.minecraft.world.level.block.BaseFireBlock; - import net.minecraft.world.level.block.Block; - import net.minecraft.world.level.block.Blocks; -+import net.minecraft.world.level.block.HopperBlock; - import net.minecraft.world.level.block.entity.BlockEntity; - import net.minecraft.world.level.block.entity.TickingBlockEntity; - import net.minecraft.world.level.block.state.BlockState; -@@ -1024,7 +1025,9 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - } - - if ((i & 1) != 0) { -- this.blockUpdated(blockposition, iblockdata1.getBlock()); -+ if (!(iblockdata.getBlock() instanceof HopperBlock) || iblockdata.getValue(HopperBlock.ENABLED)) { // Leaves - Placing locked hopper doesn't send NC updates. -+ this.blockUpdated(blockposition, iblockdata1.getBlock()); -+ } // Leaves - if (!this.isClientSide && iblockdata.hasAnalogOutputSignal()) { - this.updateNeighbourForOutputSignal(blockposition, newBlock.getBlock()); - } diff --git a/patches/server/0135-Bytebuf-API.patch b/patches/server/0127-Bytebuf-API.patch similarity index 95% rename from patches/server/0135-Bytebuf-API.patch rename to patches/server/0127-Bytebuf-API.patch index 06712e52..f11d8d00 100644 --- a/patches/server/0135-Bytebuf-API.patch +++ b/patches/server/0127-Bytebuf-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Bytebuf API diff --git a/src/main/java/net/minecraft/network/chat/Component.java b/src/main/java/net/minecraft/network/chat/Component.java -index 6dcade427f19771b08e04cfa036dedcfac30b5cd..3306d9f5aefe5863cff79374c75cc309c1699c3f 100644 +index 2de8da4dbe2f7b9da740a90829f18bff0b3d5b8c..a8af45393b4733ea3b6639ad7d890896752185fd 100644 --- a/src/main/java/net/minecraft/network/chat/Component.java +++ b/src/main/java/net/minecraft/network/chat/Component.java -@@ -291,7 +291,7 @@ public interface Component extends Message, FormattedText, Iterable { +@@ -296,7 +296,7 @@ public interface Component extends Message, FormattedText, Iterable { return (MutableComponent) ComponentSerialization.CODEC.parse(registries.createSerializationContext(JsonOps.INSTANCE), json).getOrThrow(JsonParseException::new); } @@ -18,15 +18,15 @@ index 6dcade427f19771b08e04cfa036dedcfac30b5cd..3306d9f5aefe5863cff79374c75cc309 } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 975062e67278614220eab0c301019a235c7953b7..810d92c033b556e8ae3a5e133a4e471e561eef2c 100644 +index 34b0a606a0bb2073b3ce151a2fdeeb3c7c9f2acb..6d9cd9df270ae2329fb749994804437997f22636 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -470,6 +470,12 @@ public abstract class PlayerList { +@@ -468,6 +468,12 @@ public abstract class PlayerList { return; } + // Leaves start - Bytebuf API -+ if (!(player instanceof ServerBot)) { ++ if (!(player instanceof ServerBot) && !(player instanceof ServerPhotographer)) { + this.cserver.getBytebufHandler().injectPlayer(player); + } + // Leaves end - Bytebuf API @@ -35,10 +35,10 @@ index 975062e67278614220eab0c301019a235c7953b7..810d92c033b556e8ae3a5e133a4e471e // Leaves start - bot support diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 98f10278b14d540e81703ee1330ddd7c6ed5f194..7954b73ddd2aa383aa72024058ed18a353d58e78 100644 +index a58a495d35c5963df7947b42c4000a0f6ba28534..3a83a6d09727b3912db15469c4288d62079c1c8c 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -309,6 +309,7 @@ public final class CraftServer implements Server { +@@ -311,6 +311,7 @@ public final class CraftServer implements Server { private final io.papermc.paper.potion.PaperPotionBrewer potionBrewer; // Paper - Custom Potion Mixes private final org.leavesmc.leaves.entity.CraftBotManager botManager = new org.leavesmc.leaves.entity.CraftBotManager(); // Leaves private final org.leavesmc.leaves.entity.CraftPhotographerManager photographerManager = new org.leavesmc.leaves.entity.CraftPhotographerManager(); // Leaves @@ -46,7 +46,7 @@ index 98f10278b14d540e81703ee1330ddd7c6ed5f194..7954b73ddd2aa383aa72024058ed18a3 // Paper start - Folia region threading API private final io.papermc.paper.threadedregions.scheduler.FallbackRegionScheduler regionizedScheduler = new io.papermc.paper.threadedregions.scheduler.FallbackRegionScheduler(); -@@ -3307,4 +3308,15 @@ public final class CraftServer implements Server { +@@ -3232,4 +3233,15 @@ public final class CraftServer implements Server { return photographerManager; } // Leaves end - replay mod api @@ -63,12 +63,12 @@ index 98f10278b14d540e81703ee1330ddd7c6ed5f194..7954b73ddd2aa383aa72024058ed18a3 + // Leaves end - Bytebuf API } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index a265dd6af9a58d1f71ea464a88c787749c79a111..d56814fd364681115dd37fe97536bc1580e05e5e 100644 +index 386d9d342cd63ab2bbbb218d1f4a10308e1ea032..8078b294b0546fbf5264d15cf612dfc24dd65662 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -3528,4 +3528,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player { - public void setSendViewDistance(final int viewDistance) { - this.getHandle().setSendViewDistance(viewDistance); +@@ -3553,4 +3553,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + ((ca.spottedleaf.moonrise.patches.chunk_system.player.ChunkSystemServerPlayer)this.getHandle()) + .moonrise$getViewDistanceHolder().setSendViewDistance(viewDistance); } + + // Leaves start - Bytebuf API diff --git a/patches/server/0128-Allow-grindstone-overstacking.patch b/patches/server/0128-Allow-grindstone-overstacking.patch new file mode 100644 index 00000000..1f45b9c0 --- /dev/null +++ b/patches/server/0128-Allow-grindstone-overstacking.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Lumine1909 <133463833+Lumine1909@users.noreply.github.com> +Date: Wed, 26 Jun 2024 17:59:56 +0800 +Subject: [PATCH] Allow grindstone overstacking + + +diff --git a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java +index 1678f6c8b2c7db761783e53043169bf12bc2cb29..13cfda7c065e0332133a1e1b60b454ae44e87d35 100644 +--- a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java ++++ b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java +@@ -202,7 +202,7 @@ public class GrindstoneMenu extends AbstractContainerMenu { + byte b0 = 1; + + if (!firstInput.isDamageableItem()) { +- if (firstInput.getMaxStackSize() < 2 || !ItemStack.matches(firstInput, secondInput)) { ++ if (!org.leavesmc.leaves.LeavesConfig.allowGrindstoneOverstacking && firstInput.getMaxStackSize() < 2 || !ItemStack.matches(firstInput, secondInput)) { // Leaves - allowGrindstoneOverstaking + return ItemStack.EMPTY; + } + +@@ -286,7 +286,7 @@ public class GrindstoneMenu extends AbstractContainerMenu { + ItemStack itemstack3 = this.repairSlots.getItem(1); + + if (slot == 2) { +- if (!this.moveItemStackTo(itemstack1, 3, 39, true)) { ++ if (!this.moveItemStackTo(itemstack1, 3, 39, true, org.leavesmc.leaves.LeavesConfig.allowGrindstoneOverstacking)) { // Leaves - allowGrindstoneOverstacking: Disable stack check + return ItemStack.EMPTY; + } + diff --git a/patches/server/0129-Configurable-MC-67.patch b/patches/server/0129-Configurable-MC-67.patch new file mode 100644 index 00000000..99b51fca --- /dev/null +++ b/patches/server/0129-Configurable-MC-67.patch @@ -0,0 +1,19 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Lumine1909 <133463833+Lumine1909@users.noreply.github.com> +Date: Wed, 26 Jun 2024 18:15:57 +0800 +Subject: [PATCH] Configurable MC-67 + + +diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java +index 3431c34b719dafd29551079afed23985e72a0f65..b6e3b14c00f461fb7a079ee6797617f975b8cb06 100644 +--- a/src/main/java/net/minecraft/world/entity/Entity.java ++++ b/src/main/java/net/minecraft/world/entity/Entity.java +@@ -3754,7 +3754,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + } + + public boolean canChangeDimensions(Level from, Level to) { +- return this.isAlive() && this.valid; // Paper - Fix item duplication and teleport issues ++ return !(!org.leavesmc.leaves.LeavesConfig.allowEntityPortalWithPassenger && (this.isPassenger() || this.isVehicle())) && this.isAlive() && this.valid; // Paper - Fix item duplication and teleport issues // Leaves - allowEntityPortalWithPassenger + } + + public float getBlockExplosionResistance(Explosion explosion, BlockGetter world, BlockPos pos, BlockState blockState, FluidState fluidState, float max) { diff --git a/patches/server/0130-Disable-end-gateway-portal-entity-ticking.patch b/patches/server/0130-Disable-end-gateway-portal-entity-ticking.patch new file mode 100644 index 00000000..b8d4407c --- /dev/null +++ b/patches/server/0130-Disable-end-gateway-portal-entity-ticking.patch @@ -0,0 +1,19 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: violetc <58360096+s-yh-china@users.noreply.github.com> +Date: Mon, 1 Jul 2024 22:09:33 +0800 +Subject: [PATCH] Disable end gateway portal entity ticking + + +diff --git a/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java b/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java +index 3087c60589de8fc38e12d322e58886ba76749507..d16f1defac4030248ad24b4c4a38ca1717908cd4 100644 +--- a/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java ++++ b/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java +@@ -128,7 +128,7 @@ public class EndGatewayBlock extends BaseEntityBlock implements Portal { + } + // Leaves end - force void trade + +- return vec3d != null ? new DimensionTransition(world, vec3d, EndGatewayBlock.calculateExitMovement(entity), entity.getYRot(), entity.getXRot(), DimensionTransition.PLACE_PORTAL_TICKET, PlayerTeleportEvent.TeleportCause.END_GATEWAY) : null; // CraftBukkit ++ return vec3d != null ? new DimensionTransition(world, vec3d, EndGatewayBlock.calculateExitMovement(entity), entity.getYRot(), entity.getXRot(), !org.leavesmc.leaves.LeavesConfig.disableGatewayPortalEntityTicking ? DimensionTransition.PLACE_PORTAL_TICKET : DimensionTransition.DO_NOTHING, PlayerTeleportEvent.TeleportCause.END_GATEWAY) : null; // CraftBukkit // Leaves - disable-gateway-portal-entity-ticking + } else { + return null; + } diff --git a/patches/server/0025-Optimize-random-calls-in-chunk-ticking.patch b/patches/server/0131-Optimize-random-calls-in-chunk-ticking.patch similarity index 50% rename from patches/server/0025-Optimize-random-calls-in-chunk-ticking.patch rename to patches/server/0131-Optimize-random-calls-in-chunk-ticking.patch index e6fa76be..fced1c75 100644 --- a/patches/server/0025-Optimize-random-calls-in-chunk-ticking.patch +++ b/patches/server/0131-Optimize-random-calls-in-chunk-ticking.patch @@ -1,45 +1,15 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: violetc <58360096+s-yh-china@users.noreply.github.com> -Date: Sun, 14 Aug 2022 11:01:17 +0800 +Date: Thu, 27 Jun 2024 20:15:05 +0800 Subject: [PATCH] Optimize random calls in chunk ticking This patch is Powered by Pufferfish(https://github.com/pufferfish-gg/Pufferfish) -diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index ffab3e27c0d9da2a380a14b6f6ebb243a6fb5e8d..6636bdc58be30f89cc52086f6741490fc9cb1653 100644 ---- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java -+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -493,6 +493,11 @@ public class ServerChunkCache extends ChunkSource { - ProfilerFiller gameprofilerfiller = this.level.getProfiler(); - - gameprofilerfiller.push("pollingChunks"); -+ // Leaves start - reset ice & snow tick random -+ if (org.leavesmc.leaves.LeavesConfig.optimizeChunkTicking) { -+ this.level.resetIceAndSnowTick(); -+ } -+ // Leaves end - reset ice & snow tick random - gameprofilerfiller.push("filteringLoadedChunks"); - // Paper - 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 84472442e0e68c22c4ebeaaf980aee1e8a234d81..38fcba055839fc1b5522e8a88bdaa63d6f24780d 100644 +index 463c60ab0a5cc697315cbc23651e63cb96b7d90c..89c4d7a3e9c4a260ee7c44832db341fd190a46c7 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -974,6 +974,13 @@ public class ServerLevel extends Level implements WorldGenLevel { - // private final io.papermc.paper.util.math.ThreadUnsafeRandom randomTickRandom = new io.papermc.paper.util.math.ThreadUnsafeRandom(this.random.nextLong()); // Leaves - moved to super - // Paper end - -+ // Leaves start - reset ice & snow tick random -+ private int currentIceAndSnowTick = 0; -+ protected void resetIceAndSnowTick() { -+ this.currentIceAndSnowTick = this.randomTickRandom.nextInt(16); -+ } -+ // Leaves end - reset ice & snow tick random -+ - public void tickChunk(LevelChunk chunk, int randomTickSpeed) { - ChunkPos chunkcoordintpair = chunk.getPos(); - boolean flag = this.isRaining(); -@@ -984,7 +991,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -832,7 +832,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. gameprofilerfiller.push("thunder"); final BlockPos.MutableBlockPos blockposition = this.chunkTickMutablePosition; // Paper - use mutable to reduce allocation rate, final to force compile fail on change @@ -49,16 +19,15 @@ index 84472442e0e68c22c4ebeaaf980aee1e8a234d81..38fcba055839fc1b5522e8a88bdaa63d if (this.isRainingAt(blockposition)) { diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -index 33673bde99023af6a136270091959cca69f514fb..f94ca04e55e02f2d8fcb98ad1868319d55da7468 100644 +index 94015519f379fab094b4b24c4b3a1900c1194e17..45a6b59ba3d869e0d6a28de0139908dd35ce6fd9 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -88,6 +88,18 @@ public class LevelChunk extends ChunkAccess { +@@ -86,6 +86,17 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p + private final LevelChunkTicks blockTicks; private final LevelChunkTicks fluidTicks; - public volatile FullChunkStatus chunkStatus = FullChunkStatus.INACCESSIBLE; // Paper - rewrite chunk system + // Leaves start - instead of using a random every time the chunk is ticked, define when lightning strikes preemptively + private int lightningTick; -+ // shouldDoLightning compiles down to 29 bytes, which with the default of 35 byte inlining should guarantee an inline + public final boolean shouldDoLightning(net.minecraft.util.RandomSource random) { + if (this.lightningTick-- <= 0) { + this.lightningTick = random.nextInt(this.level.spigotConfig.thunderChance) << 1; @@ -66,21 +35,17 @@ index 33673bde99023af6a136270091959cca69f514fb..f94ca04e55e02f2d8fcb98ad1868319d + } + return false; + } -+ // Leaves end - instead of using a random every time the chunk is ticked, define when lightning strikes preemptively ++ // Leaves end + public LevelChunk(Level world, ChunkPos pos) { this(world, pos, UpgradeData.EMPTY, new LevelChunkTicks<>(), new LevelChunkTicks<>(), 0L, (LevelChunkSection[]) null, (LevelChunk.PostLoadProcessor) null, (BlendingData) null); } -@@ -111,6 +123,12 @@ public class LevelChunk extends ChunkAccess { +@@ -109,6 +120,8 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p this.postLoad = entityLoader; this.blockTicks = blockTickScheduler; this.fluidTicks = fluidTickScheduler; -+ -+ // Leaves start - initialize lightning tick -+ if (org.leavesmc.leaves.LeavesConfig.optimizeChunkTicking) { -+ this.lightningTick = this.level.getThreadUnsafeRandom().nextInt(100000) << 1; -+ } -+ // Leaves end - initialize lightning tick ++ ++ if (org.leavesmc.leaves.LeavesConfig.optimizeChunkTicking) this.lightningTick = this.level.getThreadUnsafeRandom().nextInt(100000) << 1; // Leaves - initialize lightning tick } // CraftBukkit start diff --git a/patches/server/0084-Cache-CubeVoxelShape-shape-array.patch b/patches/unapplied/server/0078-Cache-CubeVoxelShape-shape-array.patch similarity index 82% rename from patches/server/0084-Cache-CubeVoxelShape-shape-array.patch rename to patches/unapplied/server/0078-Cache-CubeVoxelShape-shape-array.patch index d456cc0b..8b92249d 100644 --- a/patches/server/0084-Cache-CubeVoxelShape-shape-array.patch +++ b/patches/unapplied/server/0078-Cache-CubeVoxelShape-shape-array.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Cache CubeVoxelShape shape array This patch is Powered by Gale(https://github.com/GaleMC/Gale) diff --git a/src/main/java/net/minecraft/world/phys/shapes/CubeVoxelShape.java b/src/main/java/net/minecraft/world/phys/shapes/CubeVoxelShape.java -index b9af1d14c7815c99273bce8165cf384d669c1a75..832f9d8ee74823fb50b243033ce3de0e27ab4837 100644 +index d812949c7329ae2696b38dc792fa011ba87decb9..17781089b96a8ba54e06a4c8ead58cc31151be47 100644 --- a/src/main/java/net/minecraft/world/phys/shapes/CubeVoxelShape.java +++ b/src/main/java/net/minecraft/world/phys/shapes/CubeVoxelShape.java -@@ -5,6 +5,9 @@ import net.minecraft.core.Direction; +@@ -5,13 +5,28 @@ import net.minecraft.core.Direction; import net.minecraft.util.Mth; public final class CubeVoxelShape extends VoxelShape { @@ -18,11 +18,10 @@ index b9af1d14c7815c99273bce8165cf384d669c1a75..832f9d8ee74823fb50b243033ce3de0e + protected CubeVoxelShape(DiscreteVoxelShape voxels) { super(voxels); - this.initCache(); // Paper - optimise collisions -@@ -12,7 +15,19 @@ public final class CubeVoxelShape extends VoxelShape { + } @Override - protected DoubleList getCoords(Direction.Axis axis) { + public DoubleList getCoords(Direction.Axis axis) { - return new CubePointRange(this.shape.getSize(axis)); + // Leaves start - cache CubeVoxelShape shape array + if (!org.leavesmc.leaves.LeavesConfig.cacheCubeVoxelShapeShapeArray) { diff --git a/patches/unapplied/server/0115-Servux-Protocol.patch b/patches/unapplied/server/0115-Servux-Protocol.patch deleted file mode 100644 index 0d19cabf..00000000 --- a/patches/unapplied/server/0115-Servux-Protocol.patch +++ /dev/null @@ -1,199 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: violetc <58360096+s-yh-china@users.noreply.github.com> -Date: Wed, 13 Sep 2023 19:31:20 +0800 -Subject: [PATCH] Servux Protocol - - -diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -index 46230b09fc176665ba1d29ab3233c3b956a07710..abef121b9882c17a200e9f0186ee12634b8f8dfc 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -934,6 +934,7 @@ public class LevelChunk extends ChunkAccess { - // Leaves start - bbor - if (loaded) { - org.leavesmc.leaves.protocol.BBORProtocol.onChunkLoaded(this); -+ org.leavesmc.leaves.protocol.ServuxProtocol.onChunkLoaded(this); // and servux - } - // Leaves end - bbor - } -diff --git a/src/main/java/org/leavesmc/leaves/protocol/ServuxProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/ServuxProtocol.java -new file mode 100644 -index 0000000000000000000000000000000000000000..f6fa9368f66de0f23d5387b38c0cff35658d3d59 ---- /dev/null -+++ b/src/main/java/org/leavesmc/leaves/protocol/ServuxProtocol.java -@@ -0,0 +1,175 @@ -+package org.leavesmc.leaves.protocol; -+ -+import io.netty.buffer.Unpooled; -+import net.minecraft.core.Registry; -+import net.minecraft.core.registries.Registries; -+import net.minecraft.nbt.CompoundTag; -+import net.minecraft.nbt.ListTag; -+import net.minecraft.network.FriendlyByteBuf; -+import net.minecraft.resources.ResourceLocation; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.server.level.ServerPlayer; -+import net.minecraft.world.level.chunk.LevelChunk; -+import net.minecraft.world.level.levelgen.structure.BoundingBox; -+import net.minecraft.world.level.levelgen.structure.Structure; -+import net.minecraft.world.level.levelgen.structure.StructureStart; -+import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext; -+import org.jetbrains.annotations.Contract; -+import org.jetbrains.annotations.NotNull; -+import org.leavesmc.leaves.LeavesConfig; -+import org.leavesmc.leaves.protocol.core.LeavesProtocol; -+import org.leavesmc.leaves.protocol.core.ProtocolHandler; -+import org.leavesmc.leaves.protocol.core.ProtocolUtils; -+ -+import java.util.ArrayList; -+import java.util.HashMap; -+import java.util.HashSet; -+import java.util.List; -+import java.util.Map; -+import java.util.Set; -+import java.util.concurrent.ConcurrentHashMap; -+ -+@LeavesProtocol(namespace = "servux") -+public class ServuxProtocol { -+ -+ public static final String PROTOCOL_ID = "servux"; -+ -+ public static final int PROTOCOL_VERSION = 1; -+ public static final int PACKET_METADATA = 1; -+ public static final int PACKET_STRUCTURE_DATA = 2; -+ -+ public static final ResourceLocation CHANNEL = id("structures"); -+ -+ private static final Map players = new ConcurrentHashMap<>(); -+ private static final Map> playerBoundingBoxesCache = new HashMap<>(); -+ private static final Map> dimensionCache = new ConcurrentHashMap<>(); -+ -+ @Contract("_ -> new") -+ public static @NotNull ResourceLocation id(String path) { -+ return new ResourceLocation(PROTOCOL_ID, path); -+ } -+ -+ @ProtocolHandler.MinecraftRegister(channelId = "structures") -+ public static void onPlayerSubscribed(@NotNull ServerPlayer player) { -+ if (LeavesConfig.servuxProtocol) { -+ players.put(player.getId(), player); -+ -+ CompoundTag tag = new CompoundTag(); -+ tag.putInt("version", PROTOCOL_VERSION); -+ tag.putString("id", CHANNEL.toString()); -+ tag.putInt("timeout", Integer.MAX_VALUE - 200); -+ sendNBTPacket(player, PACKET_METADATA, tag); -+ } -+ } -+ -+ @ProtocolHandler.PlayerLeave -+ public static void onPlayerLoggedOut(@NotNull ServerPlayer player) { -+ if (LeavesConfig.servuxProtocol) { -+ players.remove(player.getId()); -+ playerBoundingBoxesCache.remove(player.getId()); -+ } -+ } -+ -+ @ProtocolHandler.Ticker -+ public static void tick() { -+ if (LeavesConfig.servuxProtocol) { -+ for (var playerEntry : players.entrySet()) { -+ sendBoundingToPlayer(playerEntry.getKey(), playerEntry.getValue()); -+ } -+ } -+ } -+ -+ public static void onChunkLoaded(@NotNull LevelChunk chunk) { -+ if (LeavesConfig.servuxProtocol) { -+ List structures = new ArrayList<>(); -+ final Registry structureFeatureRegistry = chunk.getLevel().registryAccess().registryOrThrow(Registries.STRUCTURE); -+ for (var es : chunk.getAllStarts().entrySet()) { -+ final var optional = structureFeatureRegistry.getResourceKey(es.getKey()); -+ optional.ifPresent(key -> structures.add(es.getValue())); -+ } -+ -+ if (!structures.isEmpty()) { -+ onStructuresLoaded((ServerLevel) chunk.getLevel(), structures); -+ } -+ } -+ } -+ -+ public static void onStructuresLoaded(@NotNull ServerLevel level, @NotNull List structures) { -+ Map cache = getOrCreateCache(level.dimension().location()); -+ for (StructureStart structureStart : structures) { -+ if (structureStart == null) { -+ return; -+ } -+ -+ StructurePieceSerializationContext ctx = StructurePieceSerializationContext.fromLevel(level); -+ -+ BoundingBox boundingBox = structureStart.getBoundingBox(); -+ if (cache.containsKey(boundingBox)) { -+ return; -+ } -+ -+ cache.put(boundingBox, structureStart.createTag(ctx, structureStart.getChunkPos())); -+ } -+ } -+ -+ private static void sendBoundingToPlayer(int id, ServerPlayer player) { -+ Map boundingBoxMap = dimensionCache.get(player.level().dimension().location()); -+ if (boundingBoxMap == null) { -+ return; -+ } -+ -+ Set playerBoundingBoxes = playerBoundingBoxesCache.computeIfAbsent(id, k -> new HashSet<>()); -+ -+ ListTag listTag = new ListTag(); -+ for (BoundingBox key : boundingBoxMap.keySet()) { -+ if (listTag.size() >= 50) { -+ break; -+ } -+ if (playerBoundingBoxes.contains(key)) { -+ continue; -+ } -+ -+ CompoundTag boundingBoxes = boundingBoxMap.get(key); -+ if (boundingBoxes != null) { -+ listTag.add(boundingBoxes); -+ } -+ playerBoundingBoxes.add(key); -+ } -+ -+ if (!listTag.isEmpty()) { -+ CompoundTag tag = new CompoundTag(); -+ tag.put("Structures", listTag); -+ sendNBTPacket(player, PACKET_STRUCTURE_DATA, tag); -+ } -+ } -+ -+ private static Map getOrCreateCache(ResourceLocation dimensionId) { -+ return dimensionCache.computeIfAbsent(dimensionId, dt -> new ConcurrentHashMap<>()); -+ } -+ -+ private static final int MAX_TOTAL_PER_PACKET_S2C = 1048576; -+ private static final int MAX_PAYLOAD_PER_PACKET_S2C = MAX_TOTAL_PER_PACKET_S2C - 5; -+ -+ public static void sendNBTPacket(ServerPlayer player, int packetType, CompoundTag data) { -+ FriendlyByteBuf packet = new FriendlyByteBuf(Unpooled.buffer()); -+ packet.writeVarInt(packetType); -+ packet.writeNbt(data); -+ -+ int len = packet.writerIndex(); -+ packet.readerIndex(0); -+ -+ for (int offset = 0; offset < len; offset += MAX_PAYLOAD_PER_PACKET_S2C) { -+ int thisLen = Math.min(len - offset, MAX_PAYLOAD_PER_PACKET_S2C); -+ FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer(thisLen)); -+ -+ if (offset == 0) { -+ buf.writeVarInt(len); -+ } -+ -+ buf.writeBytes(packet, thisLen); -+ ProtocolUtils.sendPayloadPacket(player, CHANNEL, buf1 -> buf1.writeBytes(buf)); -+ } -+ -+ packet.release(); -+ } -+} diff --git a/settings.gradle.kts b/settings.gradle.kts index 147f2fb4..7054254b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,6 +1,7 @@ pluginManagement { repositories { gradlePluginPortal() + maven("https://repo.leavesmc.org/snapshots/") maven("https://papermc.io/repo/repository/maven-public/") } }