commit 596c19c464c27f097bf4632460ffd135fd813526 Author: Apehum Date: Thu Dec 9 20:37:59 2021 +0800 upstream diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fd666df --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +Matter-API +Matter-Server + +build/ +.gradle/ +run/ \ No newline at end of file diff --git a/PATCHES-LICENSE b/PATCHES-LICENSE new file mode 100644 index 0000000..810fce6 --- /dev/null +++ b/PATCHES-LICENSE @@ -0,0 +1,621 @@ + 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/build-data/dev-imports.txt b/build-data/dev-imports.txt new file mode 100644 index 0000000..f35428a --- /dev/null +++ b/build-data/dev-imports.txt @@ -0,0 +1,10 @@ +# You can use this file to import files from minecraft libraries into the project +# format: +# +# both fully qualified and a file based syntax are accepted for : +# authlib com/mojang/authlib/yggdrasil/YggdrasilGameProfileRepository.java +# datafixerupper com.mojang.datafixers.DataFixerBuilder +# datafixerupper com/mojang/datafixers/util/Either.java +# To import classes from the vanilla Minecraft jar use `minecraft` as the artifactId: +# minecraft net.minecraft.world.level.entity.LevelEntityGetterAdapter +# minecraft net/minecraft/world/level/entity/LevelEntityGetter.java \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..e26f7d7 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,55 @@ +plugins { + java + id("com.github.johnrengelman.shadow") version "7.1.0" apply false + id("io.papermc.paperweight.patcher") version "1.3.1" +} + +repositories { + mavenCentral() + maven("https://papermc.io/repo/repository/maven-public/") +} + +dependencies { + remapper("net.fabricmc:tiny-remapper:0.7.0:fat") + decompiler("net.minecraftforge:forgeflower:1.5.498.22") + paperclip("io.papermc:paperclip:3.0.2") +} + +subprojects { + apply(plugin = "java") + + java { toolchain { languageVersion.set(JavaLanguageVersion.of(17)) } } + + tasks.withType().configureEach { + options.encoding = "UTF-8" + options.release.set(17) + } + + repositories { + mavenCentral() + maven("https://oss.sonatype.org/content/groups/public/") + maven("https://papermc.io/repo/repository/maven-public/") + maven("https://ci.emc.gs/nexus/content/groups/aikar/") + maven("https://repo.aikar.co/content/groups/aikar") + maven("https://repo.md-5.net/content/repositories/releases/") + maven("https://hub.spigotmc.org/nexus/content/groups/public/") + maven("https://oss.sonatype.org/content/repositories/snapshots/") + } +} + +paperweight { + serverProject.set(project(":Matter-Server")) + + remapRepo.set("https://maven.fabricmc.net/") + decompileRepo.set("https://files.minecraftforge.net/maven/") + + usePaperUpstream(providers.gradleProperty("paperRef")) { + withPaperPatcher { + apiPatchDir.set(layout.projectDirectory.dir("patches/api")) + serverPatchDir.set(layout.projectDirectory.dir("patches/server")) + + apiOutputDir.set(layout.projectDirectory.dir("Matter-API")) + serverOutputDir.set(layout.projectDirectory.dir("Matter-Server")) + } + } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..03bcf59 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,12 @@ +group = su.plo +version = 1.18-R0.1-SNAPSHOT + +mcVersion = 1.18 +packageVersion = 1_18_R1 +paperRef = 188a8dfc4c00e01387d0400f7c371bc0ae76f255 + +org.gradle.jvmargs=-Xmx2G + +org.gradle.caching=true +org.gradle.parallel=true +org.gradle.daemon=true diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..7454180 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..84d1f85 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.1-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..744e882 --- /dev/null +++ b/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MSYS* | MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/patches/server/0001-Feature-Secure-Seed.patch b/patches/server/0001-Feature-Secure-Seed.patch new file mode 100644 index 0000000..9dada7f --- /dev/null +++ b/patches/server/0001-Feature-Secure-Seed.patch @@ -0,0 +1,1232 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Apehum +Date: Thu, 9 Dec 2021 02:18:17 +0800 +Subject: [PATCH] Feature Secure Seed + + +diff --git a/build.gradle.kts b/build.gradle.kts +index 5678a9f8d2aa8a7afbc5729570ec297b12acf75d..f5733430deb3f5160397e43a45c2d363bd0c3e99 100644 +--- a/build.gradle.kts ++++ b/build.gradle.kts +@@ -18,8 +18,14 @@ repositories { + } + + dependencies { +- implementation(project(":paper-api")) +- implementation(project(":paper-mojangapi")) ++ ++ // Matter start ++ implementation(project(":Matter-API")) ++ implementation("io.papermc.paper:paper-mojangapi:1.18-R0.1-SNAPSHOT") { ++ exclude("io.papermc.paper", "paper-api") ++ } ++ // Matter end ++ + // Paper start + implementation("org.jline:jline-terminal-jansi:3.21.0") + implementation("net.minecrell:terminalconsoleappender:1.3.0") +diff --git a/src/main/java/net/minecraft/server/commands/SeedCommand.java b/src/main/java/net/minecraft/server/commands/SeedCommand.java +index 6f4aa3fce42a53883db1485731e03822887cadc0..90c95dd0d686e78c6df4a0c24a3a867d7ff9d21e 100644 +--- a/src/main/java/net/minecraft/server/commands/SeedCommand.java ++++ b/src/main/java/net/minecraft/server/commands/SeedCommand.java +@@ -10,6 +10,7 @@ import net.minecraft.network.chat.ComponentUtils; + import net.minecraft.network.chat.HoverEvent; + import net.minecraft.network.chat.TextComponent; + import net.minecraft.network.chat.TranslatableComponent; ++import su.plo.secure.Globals; + + public class SeedCommand { + public static void register(CommandDispatcher dispatcher, boolean dedicated) { +@@ -20,7 +21,20 @@ public class SeedCommand { + Component component = ComponentUtils.wrapInSquareBrackets((new TextComponent(String.valueOf(l))).withStyle((style) -> { + return style.withColor(ChatFormatting.GREEN).withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, String.valueOf(l))).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TranslatableComponent("chat.copy.click"))).withInsertion(String.valueOf(l)); + })); ++ ++ // Matter start ++ Globals.setupGlobals(context.getSource().getLevel()); ++ String seedStr = Globals.seedToString(Globals.worldSeed); ++ Component result = ComponentUtils.wrapInSquareBrackets(new TranslatableComponent("chat.copy.click")).withStyle(style -> { ++ return style.withColor(ChatFormatting.GREEN) ++ .withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, seedStr)) ++ .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TranslatableComponent("chat.copy.click"))) ++ .withInsertion(seedStr); ++ }); ++ + context.getSource().sendSuccess(new TranslatableComponent("commands.seed.success", component), false); ++ context.getSource().sendSuccess(new TranslatableComponent("Feature seed: %s", result), false); ++ // Matter end + return (int)l; + })); + } +diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java +index e7e110b53e79e0606262982555dd9eb096c7c4a8..f267bb064df9f2547dcd49d5273d8fe03ea8bb45 100644 +--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java ++++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java +@@ -49,6 +49,8 @@ import net.minecraft.world.level.storage.LevelStorageSource; + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; // Paper ++import su.plo.secure.Globals; ++ + import java.util.function.Function; // Paper + + public class ServerChunkCache extends ChunkSource { +@@ -1111,6 +1113,8 @@ public class ServerChunkCache extends ChunkSource { + } + + public ChunkGenerator getGenerator() { ++ // Matter ++ Globals.setupGlobals(level); + return this.chunkMap.generator(); + } + +diff --git a/src/main/java/net/minecraft/world/entity/monster/Slime.java b/src/main/java/net/minecraft/world/entity/monster/Slime.java +index 5722d9b30223fb229b80f54d7fb9edf41254a7f7..f0dc9c709659293d5e7b78a5e8f4fa6c5c980a5f 100644 +--- a/src/main/java/net/minecraft/world/entity/monster/Slime.java ++++ b/src/main/java/net/minecraft/world/entity/monster/Slime.java +@@ -336,7 +336,7 @@ public class Slime extends Mob implements Enemy { + } + + ChunkPos chunkcoordintpair = new ChunkPos(pos); +- boolean flag = world.getMinecraftWorld().paperConfig.allChunksAreSlimeChunks || WorldgenRandom.seedSlimeChunk(chunkcoordintpair.x, chunkcoordintpair.z, ((WorldGenLevel) world).getSeed(), world.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot // Paper ++ boolean flag = world.getMinecraftWorld().paperConfig.allChunksAreSlimeChunks || world.getChunk(chunkcoordintpair.x, chunkcoordintpair.z).isSlimeChunk(); // Spigot // Paper // Matter + + if (random.nextInt(10) == 0 && flag && pos.getY() < 40) { + return checkMobSpawnRules(type, world, spawnReason, pos, random); +diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java +index 96cb3e8cad9e7a5edd2a448ea88f2447104fbb5a..f20262677938917f0cd31f7ec640f5f7c848e92b 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java ++++ b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java +@@ -36,12 +36,7 @@ import net.minecraft.world.level.block.Block; + import net.minecraft.world.level.block.entity.BlockEntity; + import net.minecraft.world.level.block.state.BlockState; + import net.minecraft.world.level.gameevent.GameEventDispatcher; +-import net.minecraft.world.level.levelgen.Aquifer; +-import net.minecraft.world.level.levelgen.BelowZeroRetrogen; +-import net.minecraft.world.level.levelgen.Heightmap; +-import net.minecraft.world.level.levelgen.NoiseChunk; +-import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; +-import net.minecraft.world.level.levelgen.NoiseSampler; ++import net.minecraft.world.level.levelgen.*; + import net.minecraft.world.level.levelgen.blending.Blender; + import net.minecraft.world.level.levelgen.blending.BlendingData; + import net.minecraft.world.level.levelgen.feature.StructureFeature; +@@ -51,6 +46,7 @@ import net.minecraft.world.ticks.SerializableTickContainer; + import net.minecraft.world.ticks.TickContainerAccess; + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; ++import su.plo.secure.WorldgenCryptoRandom; + + public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiomeSource, FeatureAccess { + +@@ -77,6 +73,11 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom + protected final LevelHeightAccessor levelHeightAccessor; + protected final LevelChunkSection[] sections; + ++ // Matter start ++ private boolean slimeChunk; ++ private boolean hasComputedSlimeChunk; ++ // Matter end ++ + // CraftBukkit start - SPIGOT-6814: move to IChunkAccess to account for 1.17 to 1.18 chunk upgrading. + private static final org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry(); + public org.bukkit.craftbukkit.persistence.DirtyCraftPersistentDataContainer persistentDataContainer = new org.bukkit.craftbukkit.persistence.DirtyCraftPersistentDataContainer(ChunkAccess.DATA_TYPE_REGISTRY); +@@ -147,6 +148,17 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom + public final Registry biomeRegistry; + // CraftBukkit end + ++ // Matter start ++ public boolean isSlimeChunk() { ++ if (!hasComputedSlimeChunk) { ++ hasComputedSlimeChunk = true; ++ slimeChunk = WorldgenCryptoRandom.seedSlimeChunk(chunkPos.x, chunkPos.z).nextInt(10) == 0; ++ } ++ ++ return slimeChunk; ++ } ++ // Matter end ++ + private static void replaceMissingSections(LevelHeightAccessor world, Registry biome, LevelChunkSection[] sectionArray) { + for (int i = 0; i < sectionArray.length; ++i) { + if (sectionArray[i] == null) { +diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java +index e4591c0b3c8547cc6f4e2a0891fc378ee4334d9e..02cd49d1ec81df86e938686075e235e02bb98d8a 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java ++++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java +@@ -68,6 +68,8 @@ import net.minecraft.world.level.levelgen.placement.PlacedFeature; + import net.minecraft.world.level.levelgen.structure.BoundingBox; + import net.minecraft.world.level.levelgen.structure.StructureStart; + import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager; ++import su.plo.secure.Globals; ++import su.plo.secure.WorldgenCryptoRandom; + + public abstract class ChunkGenerator implements BiomeManager.NoiseBiomeSource { + +@@ -109,9 +111,9 @@ public abstract class ChunkGenerator implements BiomeManager.NoiseBiomeSource { + int i = structuresettingsstronghold.distance(); + int j = structuresettingsstronghold.count(); + int k = structuresettingsstronghold.spread(); +- Random random = new Random(); ++ // Matter ++ Random random = new WorldgenCryptoRandom(0, 0, Globals.Salt.STRONGHOLDS, 0); + +- random.setSeed(this.strongholdSeed); + double d0 = random.nextDouble() * 3.141592653589793D * 2.0D; + int l = 0; + int i1 = 0; +@@ -250,8 +252,12 @@ public abstract class ChunkGenerator implements BiomeManager.NoiseBiomeSource { + return structuregenerator.step().ordinal(); + })); + List list = this.biomeSource.featuresPerStep(); +- WorldgenRandom seededrandom = new WorldgenRandom(new XoroshiroRandomSource(RandomSupport.seedUniquifier())); ++ // Matter start ++ WorldgenRandom seededrandom = new WorldgenCryptoRandom( ++ blockposition.getX(), blockposition.getZ(), Globals.Salt.UNDEFINED, 0 ++ ); + long i = seededrandom.setDecorationSeed(generatoraccessseed.getSeed(), blockposition.getX(), blockposition.getZ()); ++ // Matter end + Set set = new ObjectArraySet(); + + if (this instanceof FlatLevelSource) { +diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkStatus.java b/src/main/java/net/minecraft/world/level/chunk/ChunkStatus.java +index 6c72854aa975800bd6160d104936a5ba978f4d67..be7bf237b1f885f00779ad1d043359d8abc31c9a 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/ChunkStatus.java ++++ b/src/main/java/net/minecraft/world/level/chunk/ChunkStatus.java +@@ -26,6 +26,7 @@ import net.minecraft.world.level.levelgen.GenerationStep; + import net.minecraft.world.level.levelgen.Heightmap; + import net.minecraft.world.level.levelgen.blending.Blender; + import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager; ++import su.plo.secure.Globals; + + public class ChunkStatus { + +@@ -268,6 +269,8 @@ public class ChunkStatus { + } + + public CompletableFuture> generate(Executor executor, ServerLevel world, ChunkGenerator generator, StructureManager structureManager, ThreadedLevelLightEngine lightingProvider, Function>> fullChunkConverter, List chunks, boolean flag) { ++ // Matter ++ Globals.setupGlobals(world); + ChunkAccess ichunkaccess = (ChunkAccess) chunks.get(chunks.size() / 2); + ProfiledDuration profiledduration = JvmProfiler.INSTANCE.onChunkGenerate(ichunkaccess.getPos(), world.dimension(), this.name); + CompletableFuture> completablefuture = this.generationTask.doWork(this, executor, world, generator, structureManager, lightingProvider, fullChunkConverter, chunks, ichunkaccess, flag); +diff --git a/src/main/java/net/minecraft/world/level/levelgen/WorldGenSettings.java b/src/main/java/net/minecraft/world/level/levelgen/WorldGenSettings.java +index 286c75989282c6d370ca64ac714ab15d784210ab..f07a9b04821edcc8fe7d995168a4023182d2e4dd 100644 +--- a/src/main/java/net/minecraft/world/level/levelgen/WorldGenSettings.java ++++ b/src/main/java/net/minecraft/world/level/levelgen/WorldGenSettings.java +@@ -20,6 +20,8 @@ import java.util.Properties; + import java.util.Random; + import java.util.function.Function; + import java.util.function.Supplier; ++import java.util.stream.LongStream; ++ + import net.minecraft.resources.ResourceKey; + import net.minecraft.server.packs.resources.ResourceManager; + import net.minecraft.util.GsonHelper; +@@ -37,16 +39,21 @@ import net.minecraft.core.Registry; + import net.minecraft.core.RegistryAccess; + // CraftBukkit start + import net.minecraft.resources.RegistryReadOps; ++import su.plo.secure.Globals; + + public class WorldGenSettings { +- + public static final Codec CODEC = RecordCodecBuilder.create((instance) -> { // CraftBukkit - decompile error +- return instance.group(Codec.LONG.fieldOf("seed").stable().forGetter(WorldGenSettings::seed), Codec.BOOL.fieldOf("generate_features").orElse(true).stable().forGetter(WorldGenSettings::generateFeatures), Codec.BOOL.fieldOf("bonus_chest").orElse(false).stable().forGetter(WorldGenSettings::generateBonusChest), MappedRegistry.dataPackCodec(Registry.LEVEL_STEM_REGISTRY, Lifecycle.stable(), LevelStem.CODEC).xmap(LevelStem::sortMap, Function.identity()).fieldOf("dimensions").forGetter(WorldGenSettings::dimensions), Codec.STRING.optionalFieldOf("legacy_custom_options").stable().forGetter((generatorsettings) -> { ++ return instance.group(Codec.LONG.fieldOf("seed").stable().forGetter(WorldGenSettings::seed), ++ Codec.LONG_STREAM.fieldOf("feature_seed").stable().forGetter((settings) -> LongStream.of(settings.featureSeed())), // Matter ++ Codec.BOOL.fieldOf("generate_features").orElse(true).stable().forGetter(WorldGenSettings::generateFeatures), ++ Codec.BOOL.fieldOf("bonus_chest").orElse(false).stable().forGetter(WorldGenSettings::generateBonusChest), MappedRegistry.dataPackCodec(Registry.LEVEL_STEM_REGISTRY, Lifecycle.stable(), LevelStem.CODEC).xmap(LevelStem::sortMap, Function.identity()).fieldOf("dimensions").forGetter(WorldGenSettings::dimensions), Codec.STRING.optionalFieldOf("legacy_custom_options").stable().forGetter((generatorsettings) -> { + return generatorsettings.legacyCustomOptions; + })).apply(instance, instance.stable(WorldGenSettings::new)); + }).comapFlatMap(WorldGenSettings::guardExperimental, Function.identity()); + private static final Logger LOGGER = LogManager.getLogger(); + private final long seed; ++ // Matter ++ private final long[] featureSeed; + private final boolean generateFeatures; + private final boolean generateBonusChest; + private final MappedRegistry dimensions; +@@ -62,8 +69,13 @@ public class WorldGenSettings { + return LevelStem.stable(this.seed, this.dimensions); + } + +- public WorldGenSettings(long seed, boolean generateStructures, boolean bonusChest, MappedRegistry options) { +- this(seed, generateStructures, bonusChest, options, Optional.empty()); ++ // Matter start ++ public WorldGenSettings(long seed, LongStream featureSeed, boolean generateStructures, boolean bonusChest, MappedRegistry options) { ++ this(seed, featureSeed.toArray(), generateStructures, bonusChest, options); ++ } ++ ++ public WorldGenSettings(long seed, long[] featureSeed, boolean generateStructures, boolean bonusChest, MappedRegistry options) { ++ this(seed, featureSeed, generateStructures, bonusChest, options, Optional.empty()); + LevelStem worlddimension = (LevelStem) options.get(LevelStem.OVERWORLD); + + if (worlddimension == null) { +@@ -71,24 +83,32 @@ public class WorldGenSettings { + } + } + +- private WorldGenSettings(long seed, boolean generateStructures, boolean bonusChest, MappedRegistry options, Optional legacyCustomOptions) { ++ public WorldGenSettings(long seed, LongStream featureSeed, boolean generateStructures, boolean bonusChest, MappedRegistry options, Optional legacyCustomOptions) { ++ this(seed, featureSeed.toArray(), generateStructures, bonusChest, options, legacyCustomOptions); ++ } ++ ++ private WorldGenSettings(long seed, long[] featureSeed, boolean generateStructures, boolean bonusChest, MappedRegistry options, Optional legacyCustomOptions) { + this.seed = seed; ++ this.featureSeed = featureSeed; + this.generateFeatures = generateStructures; + this.generateBonusChest = bonusChest; + this.dimensions = options; + this.legacyCustomOptions = legacyCustomOptions; + } ++ // Matter end + + public static WorldGenSettings demoSettings(RegistryAccess registryManager) { + int i = "North Carolina".hashCode(); + +- return new WorldGenSettings((long) i, true, true, WorldGenSettings.withOverworld(registryManager.registryOrThrow(Registry.DIMENSION_TYPE_REGISTRY), DimensionType.defaultDimensions(registryManager, (long) i), WorldGenSettings.makeDefaultOverworld(registryManager, (long) i))); ++ // Matter ++ return new WorldGenSettings((long) i, Globals.parseSeed("North Carolina"), true, true, WorldGenSettings.withOverworld(registryManager.registryOrThrow(Registry.DIMENSION_TYPE_REGISTRY), DimensionType.defaultDimensions(registryManager, (long) i), WorldGenSettings.makeDefaultOverworld(registryManager, (long) i))); + } + + public static WorldGenSettings makeDefault(RegistryAccess registryManager) { + long i = (new Random()).nextLong(); + +- return new WorldGenSettings(i, true, false, WorldGenSettings.withOverworld(registryManager.registryOrThrow(Registry.DIMENSION_TYPE_REGISTRY), DimensionType.defaultDimensions(registryManager, i), WorldGenSettings.makeDefaultOverworld(registryManager, i))); ++ // Matter ++ return new WorldGenSettings(i, Globals.createRandomWorldSeed(), true, false, WorldGenSettings.withOverworld(registryManager.registryOrThrow(Registry.DIMENSION_TYPE_REGISTRY), DimensionType.defaultDimensions(registryManager, i), WorldGenSettings.makeDefaultOverworld(registryManager, i))); + } + + public static NoiseBasedChunkGenerator makeDefaultOverworld(RegistryAccess registryManager, long seed) { +@@ -113,6 +133,12 @@ public class WorldGenSettings { + return this.seed; + } + ++ // Matter start ++ public long[] featureSeed() { ++ return this.featureSeed; ++ } ++ // Matter end ++ + public boolean generateFeatures() { + return this.generateFeatures; + } +@@ -187,24 +213,32 @@ public class WorldGenSettings { + } + + public WorldGenSettings withBonusChest() { +- return new WorldGenSettings(this.seed, this.generateFeatures, true, this.dimensions, this.legacyCustomOptions); ++ // Matter ++ return new WorldGenSettings(this.seed, this.featureSeed, this.generateFeatures, true, this.dimensions, this.legacyCustomOptions); + } + + public WorldGenSettings withFeaturesToggled() { +- return new WorldGenSettings(this.seed, !this.generateFeatures, this.generateBonusChest, this.dimensions); ++ // Matter ++ return new WorldGenSettings(this.seed, this.featureSeed, !this.generateFeatures, this.generateBonusChest, this.dimensions); + } + + public WorldGenSettings withBonusChestToggled() { +- return new WorldGenSettings(this.seed, this.generateFeatures, !this.generateBonusChest, this.dimensions); ++ // Matter ++ return new WorldGenSettings(this.seed, this.featureSeed, this.generateFeatures, !this.generateBonusChest, this.dimensions); + } + + public static WorldGenSettings create(RegistryAccess registryManager, Properties properties) { + String s = (String) MoreObjects.firstNonNull((String) properties.get("generator-settings"), ""); + + properties.put("generator-settings", s); ++ // Matter start + String s1 = (String) MoreObjects.firstNonNull((String) properties.get("level-seed"), ""); +- + properties.put("level-seed", s1); ++ ++ String featureSeedString = (String) MoreObjects.firstNonNull((String) properties.get("feature-level-seed"), ""); ++ properties.put("feature-level-seed", featureSeedString); ++ // Matter end ++ + String s2 = (String) properties.get("generate-structures"); + boolean flag = s2 == null || Boolean.parseBoolean(s2); + +@@ -229,6 +263,19 @@ public class WorldGenSettings { + } + } + ++ // Matter start ++ long[] featureSeed; ++ if (!featureSeedString.isEmpty()) { ++ try { ++ featureSeed = Globals.parseSeed(featureSeedString); ++ } catch (NumberFormatException e) { ++ featureSeed = Globals.createRandomWorldSeed(); ++ } ++ } else { ++ featureSeed = Globals.createRandomWorldSeed(); ++ } ++ // Matter end ++ + Registry iregistry = registryManager.registryOrThrow(Registry.DIMENSION_TYPE_REGISTRY); + Registry iregistry1 = registryManager.registryOrThrow(Registry.BIOME_REGISTRY); + MappedRegistry registrymaterials = DimensionType.defaultDimensions(registryManager, i); +@@ -264,22 +311,29 @@ public class WorldGenSettings { + Logger logger = WorldGenSettings.LOGGER; + + Objects.requireNonNull(logger); +- return new WorldGenSettings(i, flag, false, WorldGenSettings.withOverworld(iregistry, registrymaterials, new FlatLevelSource((FlatLevelGeneratorSettings) dataresult.resultOrPartial(logger::error).orElseGet(() -> { ++ // Matter ++ return new WorldGenSettings(i, featureSeed, flag, false, WorldGenSettings.withOverworld(iregistry, registrymaterials, new FlatLevelSource((FlatLevelGeneratorSettings) dataresult.resultOrPartial(logger::error).orElseGet(() -> { + return FlatLevelGeneratorSettings.getDefault(iregistry1); + })))); + case 1: +- return new WorldGenSettings(i, flag, false, WorldGenSettings.withOverworld(iregistry, registrymaterials, new DebugLevelSource(iregistry1))); ++ // Matter ++ return new WorldGenSettings(i, featureSeed, flag, false, WorldGenSettings.withOverworld(iregistry, registrymaterials, new DebugLevelSource(iregistry1))); + case 2: +- return new WorldGenSettings(i, flag, false, WorldGenSettings.withOverworld(iregistry, registrymaterials, WorldGenSettings.makeOverworld(registryManager, i, NoiseGeneratorSettings.AMPLIFIED))); ++ // Matter ++ return new WorldGenSettings(i, featureSeed, flag, false, WorldGenSettings.withOverworld(iregistry, registrymaterials, WorldGenSettings.makeOverworld(registryManager, i, NoiseGeneratorSettings.AMPLIFIED))); + case 3: +- return new WorldGenSettings(i, flag, false, WorldGenSettings.withOverworld(iregistry, registrymaterials, WorldGenSettings.makeOverworld(registryManager, i, NoiseGeneratorSettings.LARGE_BIOMES))); ++ // Matter ++ return new WorldGenSettings(i, featureSeed, flag, false, WorldGenSettings.withOverworld(iregistry, registrymaterials, WorldGenSettings.makeOverworld(registryManager, i, NoiseGeneratorSettings.LARGE_BIOMES))); + default: +- return new WorldGenSettings(i, flag, false, WorldGenSettings.withOverworld(iregistry, registrymaterials, WorldGenSettings.makeDefaultOverworld(registryManager, i))); ++ // Matter ++ return new WorldGenSettings(i, featureSeed, flag, false, WorldGenSettings.withOverworld(iregistry, registrymaterials, WorldGenSettings.makeDefaultOverworld(registryManager, i))); + } + } + + public WorldGenSettings withSeed(boolean hardcore, OptionalLong seed) { + long i = seed.orElse(this.seed); ++ // Matter ++ long[] featureSeed = Globals.createRandomWorldSeed(); + MappedRegistry registrymaterials; + + if (seed.isPresent()) { +@@ -300,9 +354,11 @@ public class WorldGenSettings { + WorldGenSettings generatorsettings; + + if (this.isDebug()) { +- generatorsettings = new WorldGenSettings(i, false, false, registrymaterials); ++ // Matter ++ generatorsettings = new WorldGenSettings(i, featureSeed, false, false, registrymaterials); + } else { +- generatorsettings = new WorldGenSettings(i, this.generateFeatures(), this.generateBonusChest() && !hardcore, registrymaterials); ++ // Matter ++ generatorsettings = new WorldGenSettings(i, featureSeed, this.generateFeatures(), this.generateBonusChest() && !hardcore, registrymaterials); + } + + return generatorsettings; +diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/BastionFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/BastionFeature.java +index 61fc0485c4896b62f74b92c3b4b93f22cbfb3ed7..8158bf845f962b041fa5472080d6c0430074fcb4 100644 +--- a/src/main/java/net/minecraft/world/level/levelgen/feature/BastionFeature.java ++++ b/src/main/java/net/minecraft/world/level/levelgen/feature/BastionFeature.java +@@ -1,10 +1,11 @@ + package net.minecraft.world.level.levelgen.feature; + + import com.mojang.serialization.Codec; +-import net.minecraft.world.level.levelgen.LegacyRandomSource; + import net.minecraft.world.level.levelgen.WorldgenRandom; + import net.minecraft.world.level.levelgen.feature.configurations.JigsawConfiguration; + import net.minecraft.world.level.levelgen.structure.pieces.PieceGeneratorSupplier; ++import su.plo.secure.Globals; ++import su.plo.secure.WorldgenCryptoRandom; + + public class BastionFeature extends JigsawFeature { + private static final int BASTION_SPAWN_HEIGHT = 33; +@@ -14,8 +15,11 @@ public class BastionFeature extends JigsawFeature { + } + + private static boolean checkLocation(PieceGeneratorSupplier.Context context) { +- WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L)); +- worldgenRandom.setLargeFeatureSeed(context.seed(), context.chunkPos().x, context.chunkPos().z); ++ // Matter start ++ WorldgenRandom worldgenRandom = new WorldgenCryptoRandom( ++ context.chunkPos().x, context.chunkPos().z, Globals.Salt.BASTION_FEATURE, 0 ++ ); ++ // Matter end + return worldgenRandom.nextInt(5) >= 2; + } + } +diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/BuriedTreasureFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/BuriedTreasureFeature.java +index c4ec2e41314da9501dc62baa024607b2782d2c73..b2e0e95fc80a85845bc5128cf67e551b441c6a52 100644 +--- a/src/main/java/net/minecraft/world/level/levelgen/feature/BuriedTreasureFeature.java ++++ b/src/main/java/net/minecraft/world/level/levelgen/feature/BuriedTreasureFeature.java +@@ -4,13 +4,14 @@ import com.mojang.serialization.Codec; + import net.minecraft.core.BlockPos; + import net.minecraft.world.level.ChunkPos; + import net.minecraft.world.level.levelgen.Heightmap; +-import net.minecraft.world.level.levelgen.LegacyRandomSource; + import net.minecraft.world.level.levelgen.WorldgenRandom; + import net.minecraft.world.level.levelgen.feature.configurations.ProbabilityFeatureConfiguration; + import net.minecraft.world.level.levelgen.structure.BuriedTreasurePieces; + import net.minecraft.world.level.levelgen.structure.pieces.PieceGenerator; + import net.minecraft.world.level.levelgen.structure.pieces.PieceGeneratorSupplier; + import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilder; ++import su.plo.secure.Globals; ++import su.plo.secure.WorldgenCryptoRandom; + + public class BuriedTreasureFeature extends StructureFeature { + private static final int RANDOM_SALT = 10387320; +@@ -20,8 +21,11 @@ public class BuriedTreasureFeature extends StructureFeature context) { +- WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L)); +- worldgenRandom.setLargeFeatureWithSalt(context.seed(), context.chunkPos().x, context.chunkPos().z, 10387320); ++ // Matter start ++ WorldgenRandom worldgenRandom = new WorldgenCryptoRandom( ++ context.chunkPos().x, context.chunkPos().z, Globals.Salt.BURIED_TREASURE_FEATURE, 0 ++ ); ++ // Matter end + return worldgenRandom.nextFloat() < (context.config()).probability && context.validBiomeOnTop(Heightmap.Types.OCEAN_FLOOR_WG); + } + +diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/GeodeFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/GeodeFeature.java +index 24110d4d412b5bd0a6c17215b889ea6c02558a2c..663cd7615fe36af5e39c59acd904dd4d35a3eecd 100644 +--- a/src/main/java/net/minecraft/world/level/levelgen/feature/GeodeFeature.java ++++ b/src/main/java/net/minecraft/world/level/levelgen/feature/GeodeFeature.java +@@ -24,6 +24,8 @@ import net.minecraft.world.level.levelgen.WorldgenRandom; + import net.minecraft.world.level.levelgen.feature.configurations.GeodeConfiguration; + import net.minecraft.world.level.levelgen.synth.NormalNoise; + import net.minecraft.world.level.material.FluidState; ++import su.plo.secure.Globals; ++import su.plo.secure.WorldgenCryptoRandom; + + public class GeodeFeature extends Feature { + private static final Direction[] DIRECTIONS = Direction.values(); +@@ -42,7 +44,8 @@ public class GeodeFeature extends Feature { + int j = geodeConfiguration.maxGenOffset; + List> list = Lists.newLinkedList(); + int k = geodeConfiguration.distributionPoints.sample(random); +- WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(worldGenLevel.getSeed())); ++ // Matter ++ WorldgenRandom worldgenRandom = new WorldgenCryptoRandom(0, 0, Globals.Salt.GEODE_FEATURE, 0); + NormalNoise normalNoise = NormalNoise.create(worldgenRandom, -4, 1.0D); + List list2 = Lists.newLinkedList(); + double d = (double)k / (double)geodeConfiguration.outerWallDistance.getMaxValue(); +diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/MineshaftFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/MineshaftFeature.java +index 45f11284bf65081b3b2e8da85114efbe5efd5b42..5b87ca415a0dd3429f98b8ab0ecfc4be08f08c37 100644 +--- a/src/main/java/net/minecraft/world/level/levelgen/feature/MineshaftFeature.java ++++ b/src/main/java/net/minecraft/world/level/levelgen/feature/MineshaftFeature.java +@@ -1,9 +1,6 @@ + package net.minecraft.world.level.levelgen.feature; + + import com.mojang.serialization.Codec; +-import java.util.Arrays; +-import java.util.Map; +-import java.util.stream.Collectors; + import net.minecraft.core.BlockPos; + import net.minecraft.core.QuartPos; + import net.minecraft.util.Mth; +@@ -12,13 +9,18 @@ import net.minecraft.world.level.block.Block; + import net.minecraft.world.level.block.Blocks; + import net.minecraft.world.level.block.state.BlockState; + import net.minecraft.world.level.levelgen.Heightmap; +-import net.minecraft.world.level.levelgen.LegacyRandomSource; + import net.minecraft.world.level.levelgen.WorldgenRandom; + import net.minecraft.world.level.levelgen.feature.configurations.MineshaftConfiguration; + import net.minecraft.world.level.levelgen.structure.MineShaftPieces; + import net.minecraft.world.level.levelgen.structure.pieces.PieceGenerator; + import net.minecraft.world.level.levelgen.structure.pieces.PieceGeneratorSupplier; + import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilder; ++import su.plo.secure.Globals; ++import su.plo.secure.WorldgenCryptoRandom; ++ ++import java.util.Arrays; ++import java.util.Map; ++import java.util.stream.Collectors; + + public class MineshaftFeature extends StructureFeature { + public MineshaftFeature(Codec configCodec) { +@@ -26,8 +28,11 @@ public class MineshaftFeature extends StructureFeature { + } + + private static boolean checkLocation(PieceGeneratorSupplier.Context context) { +- WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L)); +- worldgenRandom.setLargeFeatureSeed(context.seed(), context.chunkPos().x, context.chunkPos().z); ++ // Matter start ++ WorldgenRandom worldgenRandom = new WorldgenCryptoRandom( ++ context.chunkPos().x, context.chunkPos().z, Globals.Salt.MINESHAFT_FEATURE, 0 ++ ); ++ // Matter end + double d = (double)(context.config()).probability; + return worldgenRandom.nextDouble() >= d ? false : context.validBiome().test(context.chunkGenerator().getNoiseBiome(QuartPos.fromBlock(context.chunkPos().getMiddleBlockX()), QuartPos.fromBlock(50), QuartPos.fromBlock(context.chunkPos().getMiddleBlockZ()))); + } +diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/NetherFortressFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/NetherFortressFeature.java +index c833506d8b5b046e25532823c3501e4c1cfaf52e..25b3690d1e15a66e8739a880ccc953894da7bf34 100644 +--- a/src/main/java/net/minecraft/world/level/levelgen/feature/NetherFortressFeature.java ++++ b/src/main/java/net/minecraft/world/level/levelgen/feature/NetherFortressFeature.java +@@ -14,6 +14,8 @@ import net.minecraft.world.level.levelgen.structure.StructurePiece; + import net.minecraft.world.level.levelgen.structure.pieces.PieceGenerator; + import net.minecraft.world.level.levelgen.structure.pieces.PieceGeneratorSupplier; + import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilder; ++import su.plo.secure.Globals; ++import su.plo.secure.WorldgenCryptoRandom; + + public class NetherFortressFeature extends StructureFeature { + public static final WeightedRandomList FORTRESS_ENEMIES = WeightedRandomList.create(new MobSpawnSettings.SpawnerData(EntityType.BLAZE, 10, 2, 3), new MobSpawnSettings.SpawnerData(EntityType.ZOMBIFIED_PIGLIN, 5, 4, 4), new MobSpawnSettings.SpawnerData(EntityType.WITHER_SKELETON, 8, 5, 5), new MobSpawnSettings.SpawnerData(EntityType.SKELETON, 2, 5, 5), new MobSpawnSettings.SpawnerData(EntityType.MAGMA_CUBE, 3, 4, 4)); +@@ -23,8 +25,11 @@ public class NetherFortressFeature extends StructureFeature context) { +- WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L)); +- worldgenRandom.setLargeFeatureSeed(context.seed(), context.chunkPos().x, context.chunkPos().z); ++ // Matter start ++ WorldgenRandom worldgenRandom = new WorldgenCryptoRandom( ++ context.chunkPos().x, context.chunkPos().z, Globals.Salt.NETHER_FORTRESS_FEATURE, 0 ++ ); ++ // Matter end + return worldgenRandom.nextInt(5) >= 2 ? false : context.validBiome().test(context.chunkGenerator().getNoiseBiome(QuartPos.fromBlock(context.chunkPos().getMiddleBlockX()), QuartPos.fromBlock(64), QuartPos.fromBlock(context.chunkPos().getMiddleBlockZ()))); + } + +diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/OceanMonumentFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/OceanMonumentFeature.java +index bcfd54e917a638815813b89ab794cdc259b89cae..c794c7f1545764c89ee994f90c8129e379ee66a5 100644 +--- a/src/main/java/net/minecraft/world/level/levelgen/feature/OceanMonumentFeature.java ++++ b/src/main/java/net/minecraft/world/level/levelgen/feature/OceanMonumentFeature.java +@@ -1,7 +1,6 @@ + package net.minecraft.world.level.levelgen.feature; + + import com.mojang.serialization.Codec; +-import java.util.Objects; + import net.minecraft.core.Direction; + import net.minecraft.util.random.WeightedRandomList; + import net.minecraft.world.entity.EntityType; +@@ -9,8 +8,6 @@ import net.minecraft.world.level.ChunkPos; + import net.minecraft.world.level.biome.Biome; + import net.minecraft.world.level.biome.MobSpawnSettings; + import net.minecraft.world.level.levelgen.Heightmap; +-import net.minecraft.world.level.levelgen.LegacyRandomSource; +-import net.minecraft.world.level.levelgen.RandomSupport; + import net.minecraft.world.level.levelgen.WorldgenRandom; + import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + import net.minecraft.world.level.levelgen.structure.BoundingBox; +@@ -20,6 +17,10 @@ import net.minecraft.world.level.levelgen.structure.pieces.PieceGenerator; + import net.minecraft.world.level.levelgen.structure.pieces.PieceGeneratorSupplier; + import net.minecraft.world.level.levelgen.structure.pieces.PiecesContainer; + import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilder; ++import su.plo.secure.Globals; ++import su.plo.secure.WorldgenCryptoRandom; ++ ++import java.util.Objects; + + public class OceanMonumentFeature extends StructureFeature { + public static final WeightedRandomList MONUMENT_ENEMIES = WeightedRandomList.create(new MobSpawnSettings.SpawnerData(EntityType.GUARDIAN, 1, 2, 4)); +@@ -61,7 +62,11 @@ public class OceanMonumentFeature extends StructureFeature OUTPOST_ENEMIES = WeightedRandomList.create(new MobSpawnSettings.SpawnerData(EntityType.PILLAGER, 1, 1, 1)); +@@ -22,8 +24,11 @@ public class PillagerOutpostFeature extends JigsawFeature { + private static boolean checkLocation(PieceGeneratorSupplier.Context context) { + int i = context.chunkPos().x >> 4; + int j = context.chunkPos().z >> 4; +- WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L)); +- worldgenRandom.setSeed((long)(i ^ j << 4) ^ context.seed()); ++ // Matter start ++ WorldgenRandom worldgenRandom = new WorldgenCryptoRandom( ++ i, j, Globals.Salt.PILLAGER_OUTPOST_FEATURE, 0 ++ ); ++ // Matter end + worldgenRandom.nextInt(); + if (worldgenRandom.nextInt(5) != 0) { + return false; +diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/RuinedPortalFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/RuinedPortalFeature.java +index b34750b7165ff3ec2f703d29040099f160fe6c78..76996f295b4dedc9c401460f0b3ecbb4b18a8ac7 100644 +--- a/src/main/java/net/minecraft/world/level/levelgen/feature/RuinedPortalFeature.java ++++ b/src/main/java/net/minecraft/world/level/levelgen/feature/RuinedPortalFeature.java +@@ -2,12 +2,6 @@ package net.minecraft.world.level.levelgen.feature; + + import com.google.common.collect.ImmutableList; + import com.mojang.serialization.Codec; +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import java.util.Optional; +-import java.util.Random; +-import java.util.stream.Collectors; + import net.minecraft.Util; + import net.minecraft.core.BlockPos; + import net.minecraft.core.QuartPos; +@@ -22,7 +16,6 @@ import net.minecraft.world.level.block.Rotation; + import net.minecraft.world.level.block.state.BlockState; + import net.minecraft.world.level.chunk.ChunkGenerator; + import net.minecraft.world.level.levelgen.Heightmap; +-import net.minecraft.world.level.levelgen.LegacyRandomSource; + import net.minecraft.world.level.levelgen.WorldgenRandom; + import net.minecraft.world.level.levelgen.feature.configurations.RuinedPortalConfiguration; + import net.minecraft.world.level.levelgen.structure.BoundingBox; +@@ -30,6 +23,11 @@ import net.minecraft.world.level.levelgen.structure.RuinedPortalPiece; + import net.minecraft.world.level.levelgen.structure.pieces.PieceGenerator; + import net.minecraft.world.level.levelgen.structure.pieces.PieceGeneratorSupplier; + import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; ++import su.plo.secure.Globals; ++import su.plo.secure.WorldgenCryptoRandom; ++ ++import java.util.*; ++import java.util.stream.Collectors; + + public class RuinedPortalFeature extends StructureFeature { + private static final String[] STRUCTURE_LOCATION_PORTALS = new String[]{"ruined_portal/portal_1", "ruined_portal/portal_2", "ruined_portal/portal_3", "ruined_portal/portal_4", "ruined_portal/portal_5", "ruined_portal/portal_6", "ruined_portal/portal_7", "ruined_portal/portal_8", "ruined_portal/portal_9", "ruined_portal/portal_10"}; +@@ -49,8 +47,11 @@ public class RuinedPortalFeature extends StructureFeature> pieceGeneratorSupplier(PieceGeneratorSupplier.Context context) { + RuinedPortalPiece.Properties properties = new RuinedPortalPiece.Properties(); + RuinedPortalConfiguration ruinedPortalConfiguration = context.config(); +- WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L)); +- worldgenRandom.setLargeFeatureSeed(context.seed(), context.chunkPos().x, context.chunkPos().z); ++ // Matter start ++ WorldgenRandom worldgenRandom = new WorldgenCryptoRandom( ++ context.chunkPos().x, context.chunkPos().z, Globals.Salt.RUINED_PORTAL_FEATURE, 0 ++ ); ++ // Matter end + RuinedPortalPiece.VerticalPlacement verticalPlacement; + if (ruinedPortalConfiguration.portalType == RuinedPortalFeature.Type.DESERT) { + verticalPlacement = RuinedPortalPiece.VerticalPlacement.PARTLY_BURIED; +diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/StructureFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/StructureFeature.java +index 461464a4208bbb09800d87bcdb54978758863c7b..a7c9f53ee00a56a4d6d8f82026be10da3181c39e 100644 +--- a/src/main/java/net/minecraft/world/level/levelgen/feature/StructureFeature.java ++++ b/src/main/java/net/minecraft/world/level/levelgen/feature/StructureFeature.java +@@ -54,6 +54,8 @@ import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilde + import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager; + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; ++import su.plo.secure.Globals; ++import su.plo.secure.WorldgenCryptoRandom; + + public class StructureFeature { + public static final BiMap> STRUCTURES_REGISTRY = HashBiMap.create(); +@@ -213,8 +215,11 @@ public class StructureFeature { + int j = config.separation(); + int k = Math.floorDiv(x, i); + int l = Math.floorDiv(z, i); +- WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L)); +- worldgenRandom.setLargeFeatureWithSalt(seed, k, l, config.salt()); ++ // Matter start ++ WorldgenRandom worldgenRandom = new WorldgenCryptoRandom( ++ k, l, Globals.Salt.POTENTIONAL_FEATURE, config.salt() ++ ); ++ // Matter end + int m; + int n; + if (this.linearSeparation()) { +@@ -234,8 +239,11 @@ public class StructureFeature { + Optional> optional = this.pieceGenerator.createGenerator(new PieceGeneratorSupplier.Context<>(chunkGenerator, biomeSource, worldSeed, pos, config, world, biomePredicate, structureManager, registryManager)); + if (optional.isPresent()) { + StructurePiecesBuilder structurePiecesBuilder = new StructurePiecesBuilder(); +- WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L)); +- worldgenRandom.setLargeFeatureSeed(worldSeed, pos.x, pos.z); ++ // Matter start ++ WorldgenRandom worldgenRandom = new WorldgenCryptoRandom( ++ pos.x, pos.z, Globals.Salt.GENERATE_FEATURE, 0 ++ ); ++ // Matter end + optional.get().generatePieces(structurePiecesBuilder, new PieceGenerator.Context<>(config, chunkGenerator, structureManager, pos, world, worldgenRandom, worldSeed)); + StructureStart structureStart = new StructureStart<>(this, pos, structureReferences, structurePiecesBuilder.build()); + if (structureStart.isValid()) { +diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/WoodlandMansionFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/WoodlandMansionFeature.java +index ef068df9d6ac363509ca5828e7dc8dcba4cec2a3..e399efdf53ec74525e7003c004c42f7497df8484 100644 +--- a/src/main/java/net/minecraft/world/level/levelgen/feature/WoodlandMansionFeature.java ++++ b/src/main/java/net/minecraft/world/level/levelgen/feature/WoodlandMansionFeature.java +@@ -2,9 +2,6 @@ package net.minecraft.world.level.levelgen.feature; + + import com.google.common.collect.Lists; + import com.mojang.serialization.Codec; +-import java.util.List; +-import java.util.Optional; +-import java.util.Random; + import net.minecraft.core.BlockPos; + import net.minecraft.core.QuartPos; + import net.minecraft.world.level.ChunkPos; +@@ -13,7 +10,6 @@ import net.minecraft.world.level.WorldGenLevel; + import net.minecraft.world.level.block.Blocks; + import net.minecraft.world.level.block.Rotation; + import net.minecraft.world.level.chunk.ChunkGenerator; +-import net.minecraft.world.level.levelgen.LegacyRandomSource; + import net.minecraft.world.level.levelgen.WorldgenRandom; + import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + import net.minecraft.world.level.levelgen.structure.BoundingBox; +@@ -21,6 +17,12 @@ import net.minecraft.world.level.levelgen.structure.WoodlandMansionPieces; + import net.minecraft.world.level.levelgen.structure.pieces.PieceGenerator; + import net.minecraft.world.level.levelgen.structure.pieces.PieceGeneratorSupplier; + import net.minecraft.world.level.levelgen.structure.pieces.PiecesContainer; ++import su.plo.secure.Globals; ++import su.plo.secure.WorldgenCryptoRandom; ++ ++import java.util.List; ++import java.util.Optional; ++import java.util.Random; + + public class WoodlandMansionFeature extends StructureFeature { + public WoodlandMansionFeature(Codec configCodec) { +@@ -33,8 +35,11 @@ public class WoodlandMansionFeature extends StructureFeature> pieceGeneratorSupplier(PieceGeneratorSupplier.Context context) { +- WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L)); +- worldgenRandom.setLargeFeatureSeed(context.seed(), context.chunkPos().x, context.chunkPos().z); ++ // Matter start ++ WorldgenRandom worldgenRandom = new WorldgenCryptoRandom( ++ context.chunkPos().x, context.chunkPos().z, Globals.Salt.WOODLAND_MANSION_FEATURE, 0 ++ ); ++ // Matter end + Rotation rotation = Rotation.getRandom(worldgenRandom); + int i = 5; + int j = 5; +diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/structures/JigsawPlacement.java b/src/main/java/net/minecraft/world/level/levelgen/feature/structures/JigsawPlacement.java +index ccc08dc68ebccb30995983f029c14d6e1272417b..9d1acbf9e84de841a986a8e1bac8502719197c22 100644 +--- a/src/main/java/net/minecraft/world/level/levelgen/feature/structures/JigsawPlacement.java ++++ b/src/main/java/net/minecraft/world/level/levelgen/feature/structures/JigsawPlacement.java +@@ -2,17 +2,7 @@ package net.minecraft.world.level.levelgen.feature.structures; + + import com.google.common.collect.Lists; + import com.google.common.collect.Queues; +-import java.util.Deque; +-import java.util.List; +-import java.util.Objects; +-import java.util.Optional; +-import java.util.Random; +-import java.util.function.Predicate; +-import net.minecraft.core.BlockPos; +-import net.minecraft.core.Direction; +-import net.minecraft.core.QuartPos; +-import net.minecraft.core.Registry; +-import net.minecraft.core.RegistryAccess; ++import net.minecraft.core.*; + import net.minecraft.data.worldgen.Pools; + import net.minecraft.resources.ResourceLocation; + import net.minecraft.world.level.LevelHeightAccessor; +@@ -21,7 +11,6 @@ import net.minecraft.world.level.block.JigsawBlock; + import net.minecraft.world.level.block.Rotation; + import net.minecraft.world.level.chunk.ChunkGenerator; + import net.minecraft.world.level.levelgen.Heightmap; +-import net.minecraft.world.level.levelgen.LegacyRandomSource; + import net.minecraft.world.level.levelgen.WorldgenRandom; + import net.minecraft.world.level.levelgen.feature.StructureFeature; + import net.minecraft.world.level.levelgen.feature.configurations.JigsawConfiguration; +@@ -38,13 +27,21 @@ import net.minecraft.world.phys.shapes.VoxelShape; + import org.apache.commons.lang3.mutable.MutableObject; + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; ++import su.plo.secure.Globals; ++import su.plo.secure.WorldgenCryptoRandom; ++ ++import java.util.*; ++import java.util.function.Predicate; + + public class JigsawPlacement { + static final Logger LOGGER = LogManager.getLogger(); + + public static Optional> addPieces(PieceGeneratorSupplier.Context context, JigsawPlacement.PieceFactory pieceFactory, BlockPos pos, boolean bl, boolean bl2) { +- WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L)); +- worldgenRandom.setLargeFeatureSeed(context.seed(), context.chunkPos().x, context.chunkPos().z); ++ // Matter start ++ WorldgenRandom worldgenRandom = new WorldgenCryptoRandom( ++ context.chunkPos().x, context.chunkPos().z, Globals.Salt.JIGSAW_PLACEMENT, 0 ++ ); ++ // Matter end + RegistryAccess registryAccess = context.registryAccess(); + JigsawConfiguration jigsawConfiguration = context.config(); + ChunkGenerator chunkGenerator = context.chunkGenerator(); +@@ -199,18 +196,20 @@ public class JigsawPlacement { + if (!boundingBox2.isInside(structureBlockInfox.pos.relative(JigsawBlock.getFrontFacing(structureBlockInfox.state)))) { + return 0; + } else { +- ResourceLocation resourceLocation = new ResourceLocation(structureBlockInfox.nbt.getString("pool")); +- Optional optional = this.pools.getOptional(resourceLocation); +- Optional optional2 = optional.flatMap((pool) -> { ++ // Matter start - compile fix ++ ResourceLocation resourceLocation1 = new ResourceLocation(structureBlockInfox.nbt.getString("pool")); ++ Optional optional1 = this.pools.getOptional(resourceLocation1); ++ Optional optional1_2 = optional.flatMap((pool) -> { + return this.pools.getOptional(pool.getFallback()); + }); +- int i = optional.map((pool) -> { ++ int i1 = optional1.map((pool) -> { + return pool.getMaxSize(this.structureManager); + }).orElse(0); +- int j = optional2.map((pool) -> { ++ int j1 = optional1_2.map((pool) -> { + return pool.getMaxSize(this.structureManager); + }).orElse(0); +- return Math.max(i, j); ++ return Math.max(i1, j1); ++ // Matter end + } + }).max().orElse(0); + } else { +diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/NetherFossilFeature.java b/src/main/java/net/minecraft/world/level/levelgen/structure/NetherFossilFeature.java +index 66dc81f3116b10df660fc37c392ce55bde0e2ffe..0155605e6547a30d82fe476f183cbb8f5b3e9bb5 100644 +--- a/src/main/java/net/minecraft/world/level/levelgen/structure/NetherFossilFeature.java ++++ b/src/main/java/net/minecraft/world/level/levelgen/structure/NetherFossilFeature.java +@@ -15,6 +15,8 @@ import net.minecraft.world.level.levelgen.WorldgenRandom; + import net.minecraft.world.level.levelgen.feature.configurations.RangeConfiguration; + import net.minecraft.world.level.levelgen.structure.pieces.PieceGenerator; + import net.minecraft.world.level.levelgen.structure.pieces.PieceGeneratorSupplier; ++import su.plo.secure.Globals; ++import su.plo.secure.WorldgenCryptoRandom; + + public class NetherFossilFeature extends NoiseAffectingStructureFeature { + public NetherFossilFeature(Codec configCodec) { +@@ -22,8 +24,11 @@ public class NetherFossilFeature extends NoiseAffectingStructureFeature> pieceGeneratorSupplier(PieceGeneratorSupplier.Context context) { +- WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L)); +- worldgenRandom.setLargeFeatureSeed(context.seed(), context.chunkPos().x, context.chunkPos().z); ++ // Matter start ++ WorldgenRandom worldgenRandom = new WorldgenCryptoRandom( ++ context.chunkPos().x, context.chunkPos().z, Globals.Salt.NETHER_FOSSIL_FEATURE, 0 ++ ); ++ // Matter end + int i = context.chunkPos().getMinBlockX() + worldgenRandom.nextInt(16); + int j = context.chunkPos().getMinBlockZ() + worldgenRandom.nextInt(16); + int k = context.chunkGenerator().getSeaLevel(); +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java +index db344e5b9f96f317a232304587e6b1673fc6067d..9a2d1a9b210eb1c0f6f61939dded30a69c7c62fc 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java +@@ -205,7 +205,7 @@ public class CraftChunk implements Chunk { + @Override + public boolean isSlimeChunk() { + // 987234911L is deterimined in EntitySlime when seeing if a slime can spawn in a chunk +- return WorldgenRandom.seedSlimeChunk(this.getX(), this.getZ(), this.getWorld().getSeed(), worldServer.spigotConfig.slimeSeed).nextInt(10) == 0; ++ return worldServer.getChunk(this.getX(), this.getZ()).isSlimeChunk(); // Matter + } + + @Override +diff --git a/src/main/java/su/plo/secure/Globals.java b/src/main/java/su/plo/secure/Globals.java +new file mode 100644 +index 0000000000000000000000000000000000000000..2261001a90ba78ed4610efd21d4e663b1a216cc9 +--- /dev/null ++++ b/src/main/java/su/plo/secure/Globals.java +@@ -0,0 +1,81 @@ ++package su.plo.secure; ++ ++import com.google.common.collect.Iterables; ++import net.minecraft.server.level.ServerLevel; ++ ++import java.math.BigInteger; ++import java.security.SecureRandom; ++ ++public class Globals { ++ public static final int WORLD_SEED_LONGS = 16; ++ public static final int WORLD_SEED_BITS = WORLD_SEED_LONGS * 64; ++ ++ public static final long[] worldSeed = new long[WORLD_SEED_LONGS]; ++ public static final ThreadLocal dimension = ThreadLocal.withInitial(() -> 0); ++ ++ public enum Salt { ++ UNDEFINED, ++ BASTION_FEATURE, ++ WOODLAND_MANSION_FEATURE, ++ MINESHAFT_FEATURE, ++ BURIED_TREASURE_FEATURE, ++ NETHER_FORTRESS_FEATURE, ++ PILLAGER_OUTPOST_FEATURE, ++ GEODE_FEATURE, ++ NETHER_FOSSIL_FEATURE, ++ OCEAN_MONUMENT_FEATURE, ++ RUINED_PORTAL_FEATURE, ++ POTENTIONAL_FEATURE, ++ GENERATE_FEATURE, ++ JIGSAW_PLACEMENT, ++ STRONGHOLDS, ++ POPULATION, ++ DECORATION, ++ SLIME_CHUNK ++ } ++ ++ public static void setupGlobals(ServerLevel world) { ++ long[] seed = world.getServer().getWorldData().worldGenSettings().featureSeed(); ++ System.arraycopy(seed, 0, worldSeed, 0, WORLD_SEED_LONGS); ++ int worldIndex = Iterables.indexOf(world.getServer().levelKeys(), it -> it == world.dimension()); ++ if (worldIndex == -1) worldIndex = world.getServer().levelKeys().size(); // if we are in world construction it may not have been added to the map yet ++ dimension.set(worldIndex); ++ } ++ ++ public static long[] createRandomWorldSeed() { ++ long[] seed = new long[WORLD_SEED_LONGS]; ++ SecureRandom rand = new SecureRandom(); ++ for (int i = 0; i < WORLD_SEED_LONGS; i++) { ++ seed[i] = rand.nextLong(); ++ } ++ return seed; ++ } ++ ++ public static long[] parseSeed(String seedStr) throws NumberFormatException { ++ long[] seed = new long[WORLD_SEED_LONGS]; ++ BigInteger seedBigInt = new BigInteger(seedStr); ++ if (seedBigInt.signum() < 0) { ++ seedBigInt = seedBigInt.and(BigInteger.ONE.shiftLeft(WORLD_SEED_BITS).subtract(BigInteger.ONE)); ++ } ++ for (int i = 0; i < WORLD_SEED_LONGS; i++) { ++ BigInteger[] divRem = seedBigInt.divideAndRemainder(BigInteger.ONE.shiftLeft(64)); ++ seed[i] = divRem[1].longValue(); ++ seedBigInt = divRem[0]; ++ } ++ ++ return seed; ++ } ++ ++ public static String seedToString(long[] seed) { ++ BigInteger seedBigInt = BigInteger.ZERO; ++ for (int i = WORLD_SEED_LONGS - 1; i >= 0; i--) { ++ BigInteger val = BigInteger.valueOf(seed[i]); ++ if (val.signum() < 0) { ++ val = val.add(BigInteger.ONE.shiftLeft(64)); ++ } ++ seedBigInt = seedBigInt.shiftLeft(64).add(val); ++ } ++ ++ return seedBigInt.toString(); ++ } ++} +diff --git a/src/main/java/su/plo/secure/Hashing.java b/src/main/java/su/plo/secure/Hashing.java +new file mode 100644 +index 0000000000000000000000000000000000000000..02fa195e8c7f7d000f25672178dd495a8c28b0b5 +--- /dev/null ++++ b/src/main/java/su/plo/secure/Hashing.java +@@ -0,0 +1,74 @@ ++package su.plo.secure; ++ ++public class Hashing { ++ // https://en.wikipedia.org/wiki/BLAKE_(hash_function) ++ // https://github.com/bcgit/bc-java/blob/master/core/src/main/java/org/bouncycastle/crypto/digests/Blake2bDigest.java ++ ++ private final static long[] blake2b_IV = { ++ 0x6a09e667f3bcc908L, 0xbb67ae8584caa73bL, 0x3c6ef372fe94f82bL, ++ 0xa54ff53a5f1d36f1L, 0x510e527fade682d1L, 0x9b05688c2b3e6c1fL, ++ 0x1f83d9abfb41bd6bL, 0x5be0cd19137e2179L ++ }; ++ ++ private final static byte[][] blake2b_sigma = { ++ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, ++ {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}, ++ {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4}, ++ {7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8}, ++ {9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13}, ++ {2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9}, ++ {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11}, ++ {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10}, ++ {6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5}, ++ {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0}, ++ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, ++ {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3} ++ }; ++ ++ public static long[] hashWorldSeed(long[] worldSeed) { ++ long[] result = blake2b_IV.clone(); ++ result[0] ^= 0x01010040; ++ hash(worldSeed, result, new long[16], 0, false); ++ return result; ++ } ++ ++ public static void hash(long[] message, long[] chainValue, long[] internalState, long messageOffset, boolean isFinal) { ++ assert message.length == 16; ++ assert chainValue.length == 8; ++ assert internalState.length == 16; ++ ++ System.arraycopy(chainValue, 0, internalState, 0, chainValue.length); ++ System.arraycopy(blake2b_IV, 0, internalState, chainValue.length, 4); ++ internalState[12] = messageOffset ^ blake2b_IV[4]; ++ internalState[13] = blake2b_IV[5]; ++ if (isFinal) internalState[14] = ~blake2b_IV[6]; ++ internalState[15] = blake2b_IV[7]; ++ ++ for (int round = 0; round < 12; round++) { ++ G(message[blake2b_sigma[round][0]], message[blake2b_sigma[round][1]], 0, 4, 8, 12, internalState); ++ G(message[blake2b_sigma[round][2]], message[blake2b_sigma[round][3]], 1, 5, 9, 13, internalState); ++ G(message[blake2b_sigma[round][4]], message[blake2b_sigma[round][5]], 2, 6, 10, 14, internalState); ++ G(message[blake2b_sigma[round][6]], message[blake2b_sigma[round][7]], 3, 7, 11, 15, internalState); ++ G(message[blake2b_sigma[round][8]], message[blake2b_sigma[round][9]], 0, 5, 10, 15, internalState); ++ G(message[blake2b_sigma[round][10]], message[blake2b_sigma[round][11]], 1, 6, 11, 12, internalState); ++ G(message[blake2b_sigma[round][12]], message[blake2b_sigma[round][13]], 2, 7, 8, 13, internalState); ++ G(message[blake2b_sigma[round][14]], message[blake2b_sigma[round][15]], 3, 4, 9, 14, internalState); ++ } ++ ++ for (int i = 0; i < 8; i++) { ++ chainValue[i] ^= internalState[i] ^ internalState[i + 8]; ++ } ++ } ++ ++ private static void G(long m1, long m2, int posA, int posB, int posC, int posD, long[] internalState) ++ { ++ internalState[posA] = internalState[posA] + internalState[posB] + m1; ++ internalState[posD] = Long.rotateRight(internalState[posD] ^ internalState[posA], 32); ++ internalState[posC] = internalState[posC] + internalState[posD]; ++ internalState[posB] = Long.rotateRight(internalState[posB] ^ internalState[posC], 24); // replaces 25 of BLAKE ++ internalState[posA] = internalState[posA] + internalState[posB] + m2; ++ internalState[posD] = Long.rotateRight(internalState[posD] ^ internalState[posA], 16); ++ internalState[posC] = internalState[posC] + internalState[posD]; ++ internalState[posB] = Long.rotateRight(internalState[posB] ^ internalState[posC], 63); // replaces 11 of BLAKE ++ } ++} +diff --git a/src/main/java/su/plo/secure/WorldgenCryptoRandom.java b/src/main/java/su/plo/secure/WorldgenCryptoRandom.java +new file mode 100644 +index 0000000000000000000000000000000000000000..6963dac2056184790fc3f6ef197d4dfeac00752b +--- /dev/null ++++ b/src/main/java/su/plo/secure/WorldgenCryptoRandom.java +@@ -0,0 +1,142 @@ ++package su.plo.secure; ++ ++import net.minecraft.util.Mth; ++import net.minecraft.world.level.levelgen.LegacyRandomSource; ++import net.minecraft.world.level.levelgen.PositionalRandomFactory; ++import net.minecraft.world.level.levelgen.RandomSource; ++import net.minecraft.world.level.levelgen.WorldgenRandom; ++ ++import java.util.Arrays; ++import java.util.Random; ++ ++public class WorldgenCryptoRandom extends WorldgenRandom { ++ // hash the world seed to guard against badly chosen world seeds ++ private static final long[] HASHED_ZERO_SEED = Hashing.hashWorldSeed(new long[Globals.WORLD_SEED_LONGS]); ++ private static final ThreadLocal LAST_SEEN_WORLD_SEED = ThreadLocal.withInitial(() -> new long[Globals.WORLD_SEED_LONGS]); ++ private static final ThreadLocal HASHED_WORLD_SEED = ThreadLocal.withInitial(() -> HASHED_ZERO_SEED); ++ ++ private final long[] worldSeed = new long[Globals.WORLD_SEED_LONGS]; ++ private final long[] randomBits = new long[8]; ++ private int randomBitIndex; ++ private static final int MAX_RANDOM_BIT_INDEX = 64 * 8; ++ private static final int LOG2_MAX_RANDOM_BIT_INDEX = 9; ++ private long counter; ++ private final long[] message = new long[16]; ++ private final long[] cachedInternalState = new long[16]; ++ ++ public WorldgenCryptoRandom(int x, int z, Globals.Salt typeSalt, long salt) { ++ super(new LegacyRandomSource(0L)); ++ this.setSecureSeed(x, z, typeSalt, salt); ++ } ++ ++ public void setSecureSeed(int x, int z, Globals.Salt typeSalt, long salt) { ++ System.arraycopy(Globals.worldSeed, 0, this.worldSeed, 0, Globals.WORLD_SEED_LONGS); ++ message[0] = ((long) x << 32) | ((long) z & 0xffffffffL); ++ message[1] = ((long) Globals.dimension.get() << 32) | ((long) salt & 0xffffffffL); ++ message[2] = typeSalt.ordinal(); ++ message[3] = counter = 0; ++ randomBitIndex = MAX_RANDOM_BIT_INDEX; ++ } ++ ++ private long[] getHashedWorldSeed() { ++ if (!Arrays.equals(worldSeed, LAST_SEEN_WORLD_SEED.get())) { ++ HASHED_WORLD_SEED.set(Hashing.hashWorldSeed(worldSeed)); ++ System.arraycopy(worldSeed, 0, LAST_SEEN_WORLD_SEED.get(), 0, Globals.WORLD_SEED_LONGS); ++ } ++ return HASHED_WORLD_SEED.get(); ++ } ++ ++ private void moreRandomBits() { ++ message[3] = counter++; ++ System.arraycopy(getHashedWorldSeed(), 0, randomBits, 0, 8); ++ Hashing.hash(message, randomBits, cachedInternalState, 64, true); ++ } ++ ++ private long getBits(int count) { ++ if (randomBitIndex >= MAX_RANDOM_BIT_INDEX) { ++ moreRandomBits(); ++ randomBitIndex -= MAX_RANDOM_BIT_INDEX; ++ } ++ ++ int alignment = randomBitIndex & 63; ++ if ((randomBitIndex >>> 6) == ((randomBitIndex + count) >>> 6)) { ++ long result = (randomBits[randomBitIndex >>> 6] >>> alignment) & ((1L << count) - 1); ++ randomBitIndex += count; ++ return result; ++ } else { ++ long result = (randomBits[randomBitIndex >>> 6] >>> alignment) & ((1L << (64 - alignment)) - 1); ++ randomBitIndex += count; ++ if (randomBitIndex >= MAX_RANDOM_BIT_INDEX) { ++ moreRandomBits(); ++ randomBitIndex -= MAX_RANDOM_BIT_INDEX; ++ } ++ alignment = randomBitIndex & 63; ++ result <<= alignment; ++ result |= (randomBits[randomBitIndex >>> 6] >>> (64 - alignment)) & ((1L << alignment) - 1); ++ ++ return result; ++ } ++ } ++ ++ @Override ++ public int next(int bits) { ++ return (int) getBits(bits); ++ } ++ ++ @Override ++ public void consumeCount(int count) { ++ randomBitIndex += count; ++ if (randomBitIndex >= MAX_RANDOM_BIT_INDEX * 2) { ++ randomBitIndex -= MAX_RANDOM_BIT_INDEX; ++ counter += randomBitIndex >>> LOG2_MAX_RANDOM_BIT_INDEX; ++ randomBitIndex &= MAX_RANDOM_BIT_INDEX - 1; ++ randomBitIndex += MAX_RANDOM_BIT_INDEX; ++ } ++ } ++ ++ @Override ++ public int nextInt(int bound) { ++ int bits = Mth.ceillog2(bound); ++ int result; ++ do { ++ result = (int) getBits(bits); ++ } while (result >= bound); ++ ++ return result; ++ } ++ ++ @Override ++ public long nextLong() { ++ return getBits(64); ++ } ++ ++ @Override ++ public double nextDouble() { ++ return getBits(53) * 0x1.0p-53; ++ } ++ ++ @Override ++ public long setDecorationSeed(long worldSeed, int blockX, int blockZ) { ++ setSecureSeed(blockX, blockZ, Globals.Salt.POPULATION, 0); ++ return ((long) blockX << 32) | ((long) blockZ & 0xffffffffL); ++ } ++ ++ @Override ++ public void setFeatureSeed(long populationSeed, int index, int step) { ++ setSecureSeed((int) (populationSeed >> 32), (int) populationSeed, Globals.Salt.DECORATION, index + 10000L * step); ++ } ++ ++ @Override ++ public void setLargeFeatureSeed(long worldSeed, int chunkX, int chunkZ) { ++ super.setLargeFeatureSeed(worldSeed, chunkX, chunkZ); ++ } ++ ++ @Override ++ public void setLargeFeatureWithSalt(long worldSeed, int regionX, int regionZ, int salt) { ++ super.setLargeFeatureWithSalt(worldSeed, regionX, regionZ, salt); ++ } ++ ++ public static Random seedSlimeChunk(int chunkX, int chunkZ) { ++ return new WorldgenCryptoRandom(chunkX, chunkZ, Globals.Salt.SLIME_CHUNK, 0); ++ } ++} diff --git a/scripts/apatch.sh b/scripts/apatch.sh new file mode 100644 index 0000000..bae11d4 --- /dev/null +++ b/scripts/apatch.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash + +gitcmd="git -c commit.gpgsign=false" + +noapply=1 +isreject=0 +if [[ $1 == "--noapplied" ]]; then + noapply=1 + shift +fi + +if [ ! -z "$1" ]; then + file="$1" +elif [ -z "$1" ] && [ -f .git/rebase-apply/patch ]; then + file=".git/rebase-apply/patch" + noapply=1 + isreject=1 +else + echo "Please specify a file" + exit 1 +fi +applied=$(echo $file | sed 's/.patch$/-applied\.patch/g') +if [ "$1" == "--reset" ]; then + $gitcmd am --abort + $gitcmd reset --hard + $gitcmd clean -f + exit 0 +fi + + +(test "$isreject" != "1" && $gitcmd am -3 $file) || ( + echo "Failures - Wiggling" + $gitcmd reset --hard + $gitcmd clean -f + errors=$($gitcmd apply --rej $file 2>&1) + echo "$errors" >> ~/patch.log + export missingfiles="" + export summaryfail="" + export summarygood="" + for i in $(find . -name \*.rej); do + base=$(echo "$i" | sed 's/.rej//g') + if [ -f "$i" ]; then + sed -e 's/^diff a\/\(.*\) b\/\(.*\)[[:space:]].*rejected.*$/--- \1\n+++ \2/' -i $i && wiggle -v -l --replace "$base" "$i" + rm "$base.porig" "$i" + else + echo "No such file: $base" + missingfiles="$missingfiles\n$base" + fi + done + for i in $($gitcmd status --porcelain | awk '{print $2}'); do + filedata=$(cat "$i") + if [ -f "$file" ] && [[ "$filedata" == *"<<<<<"* ]]; then + export summaryfail="$summaryfail\nFAILED TO APPLY: $i" + else + $gitcmd add --force "$i" + export summarygood="$summarygood\nAPPLIED CLEAN: $i" + fi + done + echo -e "$summarygood" + echo -e "$summaryfail" + if [[ "$errors" == *"No such file"* ]]; then + echo "==========================="; + echo " " + echo " MISSING FILES" + echo $(echo "$errors" | grep "No such file") + echo -e "$missingfiles" + echo " " + echo "==========================="; + fi + $gitcmd status + $gitcmd diff +) +if [[ "$noapply" != "1" ]] && [[ "$file" != *-applied.patch ]]; then + mv "$file" "$applied" +fi \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..83cc4fa --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,11 @@ +pluginManagement { + repositories { + mavenLocal() + gradlePluginPortal() + maven("https://papermc.io/repo/repository/maven-public/") + } +} + +rootProject.name = "Matter" + +include("Matter-API", "Matter-Server") \ No newline at end of file