commit 6179d4fbc9603d2e1cf849ff52ec433f7498fa77 Author: M1rsem Date: Fri May 1 23:51:16 2026 +0300 govno kod diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..0f1eb0b --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,92 @@ +name: Build + +on: + push: + branches: + - '**' # run on all branches + tags-ignore: + - '**' # ignore all tags + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Set up BuildTools + run: wget -O BuildTools.jar https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar + - name: Install JDK 8 + uses: actions/setup-java@v3 + with: + distribution: 'temurin' + java-version: '8' + cache: 'maven' + - name: Install CraftBukkit 1.8.8, 1.12.2, 1.16.5 + run: | + java -jar BuildTools.jar --rev 1.8.8 --compile craftbukkit + java -jar BuildTools.jar --rev 1.12.2 --compile craftbukkit + java -jar BuildTools.jar --rev 1.16.5 --compile craftbukkit + - name: Install JDK 17 + uses: actions/setup-java@v3 + with: + distribution: 'microsoft' + java-version: '17' + cache: 'maven' + - name: Install CraftBukkit 1.17.1, 1.18.2, 1.19.4, 1.20.1, 1.20.4 + run: | + java -jar BuildTools.jar --rev 1.17.1 --compile craftbukkit --remapped + java -jar BuildTools.jar --rev 1.18.2 --compile craftbukkit --remapped + java -jar BuildTools.jar --rev 1.19.4 --compile craftbukkit --remapped + java -jar BuildTools.jar --rev 1.20.1 --compile craftbukkit --remapped + java -jar BuildTools.jar --rev 1.20.4 --compile craftbukkit --remapped + - name: Install JDK 21 + uses: actions/setup-java@v4 + with: + distribution: 'microsoft' + java-version: '21' + cache: 'maven' + - name: Install CraftBukkit 1.20.6, 1.21, 1.21, 1.21.4, 1.21.5, 1.21.7, 1.21.9, 1.21.11 + # Use build number 4287 to compile CraftBukkit 1.21, + # Use build number 4522 to compile CraftBukkit 1.21.7, + # Use build number 4539 to compile CraftBukkit 1.21.9 + # https://hub.spigotmc.org/jira/browse/BUILDTOOLS-658 + # https://hub.spigotmc.org/versions/ + run: | + java -jar BuildTools.jar --rev 1.20.6 --compile craftbukkit --remapped + java -jar BuildTools.jar --rev 4287 --compile craftbukkit --remapped + java -jar BuildTools.jar --rev 1.21.1 --compile craftbukkit --remapped + java -jar BuildTools.jar --rev 1.21.4 --compile craftbukkit --remapped + java -jar BuildTools.jar --rev 1.21.5 --compile craftbukkit --remapped + java -jar BuildTools.jar --rev 4522 --compile craftbukkit --remapped + java -jar BuildTools.jar --rev 4539 --compile craftbukkit --remapped + java -jar BuildTools.jar --rev 4576 --compile craftbukkit --remapped + - name: Install Paper 1.21.11 + run: | + mvn ca.bkaw:paper-nms-maven-plugin:init --pl :impl_paper_1_21_11 + - name: Install JDK 25 + uses: actions/setup-java@v5 + with: + distribution: 'microsoft' + java-version: '25' + cache: 'maven' + # Use build number 4617 to compile CraftBukkit 26.1.1 + # https://hub.spigotmc.org/versions/ + - name: Install CraftBukkit 26.1.1 + run: | + java -jar BuildTools.jar --rev 4617 --compile craftbukkit + - name: Install Paper 26.1.1 + run: | + mvn ca.bkaw:paper-nms-maven-plugin:init --pl :impl_paper_26_1_1 + - name: Compile InvSee++ + run: mvn clean package install --batch-mode --update-snapshots + - name: Deploy Javadoc + uses: MathieuSoysal/Javadoc-publisher.yml@v2.4.0 + if: github.ref == 'refs/heads/master' + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + javadoc-branch: javadoc + java-distribution: temurin + java-version: 25 + custom-command: 'mvn package javadoc:aggregate -pl :invsee-plus-plus,:invsee-plus-plus_plugin,:invsee-plus-plus_common' + target-folder: javadoc + project: maven \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..93423b7 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,206 @@ +name: Release + +on: + push: + tags: + - '*' + +env: + # Single line string with spaces between values. + MINECRAFT_VERSIONS: >- + 1.8.8 + 1.12.2 + 1.16.5 + 1.17.1 + 1.18.2 + 1.19.4 + 1.20.1 + 1.20.4 + 1.20.6 + 1.21 + 1.21.1 + 1.21.4 + 1.21.5 + 1.21.7 + 1.21.8 + 1.21.9 + 1.21.10 + 1.21.11 + 26.1 + 26.1.1 + 26.1.2 + # TODO can we auto-detect the versions based on the implementations present? probably yes! + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v6 + - name: Set up BuildTools + run: wget -O BuildTools.jar https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar + - name: Install JDK 8 + uses: actions/setup-java@v5 + with: + distribution: 'temurin' + java-version: '8' + cache: 'maven' + - name: Install CraftBukkit 1.8.8, 1.12.2, 1.16.5 + run: | + java -jar BuildTools.jar --rev 1.8.8 --compile craftbukkit + java -jar BuildTools.jar --rev 1.12.2 --compile craftbukkit + java -jar BuildTools.jar --rev 1.16.5 --compile craftbukkit + - name: Install JDK 17 + uses: actions/setup-java@v5 + with: + distribution: 'microsoft' + java-version: '17' + cache: 'maven' + - name: Install CraftBukkit 1.17.1, 1.18.2, 1.19.4, 1.20.1, 1.20.4 + run: | + java -jar BuildTools.jar --rev 1.17.1 --compile craftbukkit --remapped + java -jar BuildTools.jar --rev 1.18.2 --compile craftbukkit --remapped + java -jar BuildTools.jar --rev 1.19.4 --compile craftbukkit --remapped + java -jar BuildTools.jar --rev 1.20.1 --compile craftbukkit --remapped + java -jar BuildTools.jar --rev 1.20.4 --compile craftbukkit --remapped + - name: Install JDK 21 + uses: actions/setup-java@v5 + with: + distribution: 'microsoft' + java-version: '21' + cache: 'maven' + - name: Install CraftBukkit 1.20.6, 1.21, 1.21, 1.21.4, 1.21.5, 1.21.7, 1.21.9, 1.21.11 + # Use build number 4287 to compile CraftBukkit 1.21, + # Use build number 4522 to compile CraftBukkit 1.21.7, + # Use build number 4539 to compile CraftBukkit 1.21.9 + # https://hub.spigotmc.org/jira/browse/BUILDTOOLS-658 + # https://hub.spigotmc.org/versions/ + run: | + java -jar BuildTools.jar --rev 1.20.6 --compile craftbukkit --remapped + java -jar BuildTools.jar --rev 4287 --compile craftbukkit --remapped + java -jar BuildTools.jar --rev 1.21.1 --compile craftbukkit --remapped + java -jar BuildTools.jar --rev 1.21.4 --compile craftbukkit --remapped + java -jar BuildTools.jar --rev 1.21.5 --compile craftbukkit --remapped + java -jar BuildTools.jar --rev 4522 --compile craftbukkit --remapped + java -jar BuildTools.jar --rev 4539 --compile craftbukkit --remapped + java -jar BuildTools.jar --rev 4576 --compile craftbukkit --remapped + - name: Install Paper 1.21.11 + run: | + mvn ca.bkaw:paper-nms-maven-plugin:init --pl :impl_paper_1_21_11 + - name: Install JDK 25 + uses: actions/setup-java@v5 + with: + distribution: 'microsoft' + java-version: '25' + cache: 'maven' + # Use build number 4617 to compile CraftBukkit 26.1.1 + # https://hub.spigotmc.org/versions/ + - name: Install CraftBukkit 26.1.1 + run: | + java -jar BuildTools.jar --rev 4617 --compile craftbukkit + - name: Install Paper 26.1.1 + run: | + mvn ca.bkaw:paper-nms-maven-plugin:init --pl :impl_paper_26_1_1 + - name: Compile InvSee++ + run: mvn clean package install --batch-mode --update-snapshots + - name: Upload InvSee++ + uses: actions/upload-artifact@v7 + with: + name: InvSee++ + archive: false + path: InvSee++_Plugin/target/InvSee++.jar + - name: Upload InvSee++_Give + uses: actions/upload-artifact@v7 + with: + name: InvSee++_Give + archive: false + path: InvSee++_Give_Plugin/target/InvSee++_Give.jar + - name: Upload InvSee++_Clear + uses: actions/upload-artifact@v7 + with: + name: InvSee++_Clear + archive: false + path: InvSee++_Clear_Plugin/target/InvSee++_Clear.jar + - name: Upload InvSee++_Clone + uses: actions/upload-artifact@v7 + with: + name: InvSee++_Clone + archive: false + path: InvSee++_Clone_Plugin/target/InvSee++_Clone.jar + + release_github: + runs-on: ubuntu-latest + needs: build + + steps: + - name: Download InvSee++ and addons + uses: actions/download-artifact@v8 + with: + path: plugins + merge-multiple: true + - name: Set download-source to GitHub + run: | + echo GitHub > download-source.txt + zip plugins/InvSee++.jar download-source.txt + - name: Create Release on GitHub + env: + GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} + uses: softprops/action-gh-release@v1 + with: + files: | + plugins/InvSee++.jar + plugins/InvSee++_Give.jar + plugins/InvSee++_Clear.jar + plugins/InvSee++_Clone.jar + + release_hangar: + runs-on: ubuntu-latest + needs: build + + steps: + - name: Download Hangar upload script + uses: actions/checkout@v6 + with: + sparse-checkout: | + release-scripts + - name: Download InvSee++ and addons + uses: actions/download-artifact@v8 + with: + path: plugins + merge-multiple: true + - name: Set download-source to Hangar + run: | + echo Hangar > download-source.txt + zip plugins/InvSee++.jar download-source.txt + - name: Publish new version to Hangar + env: + HANGAR_TOKEN: ${{ secrets.HANGAR_TOKEN }} + run: | + chmod +x release-scripts/mill-dist-1.1.5-mill.sh + ./release-scripts/mill-dist-1.1.5-mill.sh release-scripts/hangar/HangarVersionUploader.java + + release_modrinth: + runs-on: ubuntu-latest + needs: build + + steps: + - name: Download Modrinth upload script + uses: actions/checkout@v6 + with: + sparse-checkout: | + release-scripts + - name: Download InvSee++ and addons + uses: actions/download-artifact@v8 + with: + path: plugins + merge-multiple: true + - name: Set download-source to Modrinth + run: | + echo Modrinth > download-source.txt + zip plugins/InvSee++.jar download-source.txt + - name: Publish new version to Modrinth + env: + MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }} + run: | + chmod +x release-scripts/mill-dist-1.1.5-mill.sh + ./release-scripts/mill-dist-1.1.5-mill.sh release-scripts/modrinth/ModrinthVersionUploader.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e7c3b2e --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +#IntelliJ +.idea/* +**.iml +.bsp +.scala-build + +#Maven +target/* + +#paper-nms-maven-plugin +**/.paper-nms + +#Eclipse +**/.settings/* +**/.project +**/.classpath \ No newline at end of file diff --git a/.libs/BungeePerms-3.0-dev-80.jar b/.libs/BungeePerms-3.0-dev-80.jar new file mode 100644 index 0000000..beb9ac7 Binary files /dev/null and b/.libs/BungeePerms-3.0-dev-80.jar differ diff --git a/.libs/UltraPermissionsAPI-5.5.2.jar b/.libs/UltraPermissionsAPI-5.5.2.jar new file mode 100644 index 0000000..c59a0fe Binary files /dev/null and b/.libs/UltraPermissionsAPI-5.5.2.jar differ diff --git a/.libs/glowstone.jar b/.libs/glowstone.jar new file mode 100644 index 0000000..635c2b7 Binary files /dev/null and b/.libs/glowstone.jar differ diff --git a/.libs/perworldinventory-kt-2.3.2.jar b/.libs/perworldinventory-kt-2.3.2.jar new file mode 100644 index 0000000..0e0b642 Binary files /dev/null and b/.libs/perworldinventory-kt-2.3.2.jar differ diff --git a/.tools/BuildTools.jar b/.tools/BuildTools.jar new file mode 100644 index 0000000..5cb2a55 Binary files /dev/null and b/.tools/BuildTools.jar differ diff --git a/.tools/apache-maven-3.9.9/LICENSE b/.tools/apache-maven-3.9.9/LICENSE new file mode 100644 index 0000000..b249f9c --- /dev/null +++ b/.tools/apache-maven-3.9.9/LICENSE @@ -0,0 +1,760 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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 + + http://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. + + +Apache Maven includes a number of components and libraries with separate +copyright notices and license terms. Your use of those components are +subject to the terms and conditions of the following licenses: + + + + + + + + + + + +- lib/aopalliance-1.0.jar: aopalliance:aopalliance:jar:1.0 + Project: AOP alliance +Project URL: http://aopalliance.sourceforge.net + License: Public Domain (unrecognized) + + License URL: $license.url (lib/aopalliance.license) + + + + + + + + + + + + + + + +- lib/failureaccess-1.0.2.jar: com.google.guava:failureaccess:bundle:1.0.2 + Project: Guava InternalFutureFailureAccess and InternalFutures +Project URL: https://github.com/google/guava/ + License: The Apache Software License, Version 2.0 (Apache-2.0) + + License URL: http://www.apache.org/licenses/LICENSE-2.0.txt (lib/failureaccess.license) + + + + + + + + + + + + + + +- lib/guava-33.2.1-jre.jar: com.google.guava:guava:bundle:33.2.1-jre + Project: Guava: Google Core Libraries for Java +Project URL: https://github.com/google/guava + License: Apache License, Version 2.0 (Apache-2.0) + + License URL: http://www.apache.org/licenses/LICENSE-2.0.txt (lib/guava.license) + + + + + + + + + + + + + + + +- lib/guice-5.1.0.jar: com.google.inject:guice:jar:5.1.0 + Project: Google Guice - Core Library +Project URL: https://github.com/google/guice/ + License: The Apache Software License, Version 2.0 (Apache-2.0) + + License URL: http://www.apache.org/licenses/LICENSE-2.0.txt (lib/guice.license) + + + + + + + + + + + + + + +- lib/commons-cli-1.8.0.jar: commons-cli:commons-cli:jar:1.8.0 + Project: Apache Commons CLI +Project URL: https://commons.apache.org/proper/commons-cli/ + License: Apache-2.0 (Apache-2.0) + + License URL: https://www.apache.org/licenses/LICENSE-2.0.txt (lib/commons-cli.license) + + + + + + + + + + + + + + +- lib/commons-codec-1.17.1.jar: commons-codec:commons-codec:jar:1.17.1 + Project: Apache Commons Codec +Project URL: https://commons.apache.org/proper/commons-codec/ + License: Apache-2.0 (Apache-2.0) + + License URL: https://www.apache.org/licenses/LICENSE-2.0.txt (lib/commons-codec.license) + + + + + + + + + + + + + + +- lib/javax.annotation-api-1.3.2.jar: javax.annotation:javax.annotation-api:jar:1.3.2 + Project: javax.annotation API +Project URL: http://jcp.org/en/jsr/detail?id=250 + License: CDDL + GPLv2 with classpath exception (unrecognized) + + License URL: https://github.com/javaee/javax.annotation/blob/master/LICENSE (lib/javax.annotation-api.license) + + + + + + + + + + + + + + +- lib/javax.inject-1.jar: javax.inject:javax.inject:jar:1 + Project: javax.inject +Project URL: http://code.google.com/p/atinject/ + License: The Apache Software License, Version 2.0 (Apache-2.0) + + License URL: http://www.apache.org/licenses/LICENSE-2.0.txt (lib/javax.inject.license) + + + + + + + + + + + + + + +- lib/httpclient-4.5.14.jar: org.apache.httpcomponents:httpclient:jar:4.5.14 + Project: Apache HttpClient +Project URL: http://hc.apache.org/httpcomponents-client-ga + License: Apache License, Version 2.0 (Apache-2.0) + + License URL: http://www.apache.org/licenses/LICENSE-2.0.txt (lib/httpclient.license) + + + + + + + + + + + + + + +- lib/httpcore-4.4.16.jar: org.apache.httpcomponents:httpcore:jar:4.4.16 + Project: Apache HttpCore +Project URL: http://hc.apache.org/httpcomponents-core-ga + License: Apache License, Version 2.0 (Apache-2.0) + + License URL: http://www.apache.org/licenses/LICENSE-2.0.txt (lib/httpcore.license) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +- lib/plexus-cipher-2.0.jar: org.codehaus.plexus:plexus-cipher:jar:2.0 + Project: Plexus Cipher: encryption/decryption Component +Project URL: https://codehaus-plexus.github.io/plexus-cipher/ + License: Apache License, Version 2.0 (Apache-2.0) + + License URL: http://www.apache.org/licenses/LICENSE-2.0.txt (lib/plexus-cipher.license) + + + + + + + + + + + + + + + +- boot/plexus-classworlds-2.8.0.jar: org.codehaus.plexus:plexus-classworlds:bundle:2.8.0 + Project: Plexus Classworlds +Project URL: https://codehaus-plexus.github.io/plexus-classworlds/ + License: Apache License, Version 2.0 (Apache-2.0) + + License URL: https://www.apache.org/licenses/LICENSE-2.0.txt (boot/plexus-classworlds.license) + + + + + + + + + + + + + + +- lib/plexus-component-annotations-2.1.0.jar: org.codehaus.plexus:plexus-component-annotations:jar:2.1.0 + Project: Plexus :: Component Annotations +Project URL: http://codehaus-plexus.github.io/plexus-containers/plexus-component-annotations/ + License: Apache License, Version 2.0 (Apache-2.0) + + License URL: http://www.apache.org/licenses/LICENSE-2.0.txt (lib/plexus-component-annotations.license) + + + + + + + + + + + + + + +- lib/plexus-interpolation-1.27.jar: org.codehaus.plexus:plexus-interpolation:bundle:1.27 + Project: Plexus Interpolation API +Project URL: https://codehaus-plexus.github.io/plexus-pom/plexus-interpolation/ + License: Apache License, Version 2.0 (Apache-2.0) + + License URL: https://www.apache.org/licenses/LICENSE-2.0.txt (lib/plexus-interpolation.license) + + + + + + + + + + + + + + +- lib/plexus-sec-dispatcher-2.0.jar: org.codehaus.plexus:plexus-sec-dispatcher:jar:2.0 + Project: Plexus Security Dispatcher Component +Project URL: https://codehaus-plexus.github.io/plexus-sec-dispatcher/ + License: Apache License, Version 2.0 (Apache-2.0) + + License URL: http://www.apache.org/licenses/LICENSE-2.0.txt (lib/plexus-sec-dispatcher.license) + + + + + + + + + + + + + + +- lib/plexus-utils-3.5.1.jar: org.codehaus.plexus:plexus-utils:jar:3.5.1 + Project: Plexus Common Utilities +Project URL: https://codehaus-plexus.github.io/plexus-utils/ + License: Apache License, Version 2.0 (Apache-2.0) + + License URL: http://www.apache.org/licenses/LICENSE-2.0.txt (lib/plexus-utils.license) + + + + + + + + + + + + + + +- lib/plexus-xml-3.0.1.jar: org.codehaus.plexus:plexus-xml:jar:3.0.1 + Project: Plexus XML Utilities +Project URL: https://codehaus-plexus.github.io/plexus-xml/ + License: Apache License, Version 2.0 (Apache-2.0) + + License URL: https://www.apache.org/licenses/LICENSE-2.0.txt (lib/plexus-xml.license) + + + + + + + + + + + + + + + +- lib/org.eclipse.sisu.inject-0.9.0.M3.jar: org.eclipse.sisu:org.eclipse.sisu.inject:jar:0.9.0.M3 + Project: org.eclipse.sisu.inject +Project URL: https://www.eclipse.org/sisu/ + License: Eclipse Public License, Version 2.0 (EPL-2.0) + + License URL: https://www.eclipse.org/legal/epl-v20.html (lib/org.eclipse.sisu.inject.license) + + + + + + + + + + + + + + + +- lib/org.eclipse.sisu.plexus-0.9.0.M3.jar: org.eclipse.sisu:org.eclipse.sisu.plexus:jar:0.9.0.M3 + Project: org.eclipse.sisu.plexus +Project URL: https://www.eclipse.org/sisu/ + License: Eclipse Public License, Version 2.0 (EPL-2.0) + + License URL: https://www.eclipse.org/legal/epl-v20.html (lib/org.eclipse.sisu.plexus.license) + + + + + + + + + + + + + + +- lib/jansi-2.4.1.jar: org.fusesource.jansi:jansi:jar:2.4.1 + Project: Jansi +Project URL: http://fusesource.github.io/jansi + License: Apache License, Version 2.0 (Apache-2.0) + + License URL: http://www.apache.org/licenses/LICENSE-2.0.txt (lib/jansi.license) + + + + + + + + + + + + + + +- lib/jcl-over-slf4j-1.7.36.jar: org.slf4j:jcl-over-slf4j:jar:1.7.36 + Project: JCL 1.2 implemented over SLF4J +Project URL: http://www.slf4j.org + License: Apache License, Version 2.0 (Apache-2.0) + + License URL: https://www.apache.org/licenses/LICENSE-2.0.txt (lib/jcl-over-slf4j.license) + + + + + + + + + + + + + + +- lib/slf4j-api-1.7.36.jar: org.slf4j:slf4j-api:jar:1.7.36 + Project: SLF4J API Module +Project URL: http://www.slf4j.org + License: MIT License (MIT) + + License URL: http://www.opensource.org/licenses/mit-license.php (lib/slf4j-api.license) + + + diff --git a/.tools/apache-maven-3.9.9/NOTICE b/.tools/apache-maven-3.9.9/NOTICE new file mode 100644 index 0000000..4375095 --- /dev/null +++ b/.tools/apache-maven-3.9.9/NOTICE @@ -0,0 +1,104 @@ +Apache Maven Distribution +Copyright 2001-2024 The Apache Software Foundation + + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). +This software bundles the following NOTICE files from third party library providers: + +META-INF/NOTICE in archive lib/guice-5.1.0.jar +Google Guice - Core Library +Copyright 2006-2022 Google, Inc. +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +META-INF/NOTICE in archive lib/plexus-utils-3.2.1.jar +This product includes software developed by the Indiana University + Extreme! Lab (http://www.extreme.indiana.edu/). +This product includes software developed by +The Apache Software Foundation (http://www.apache.org/). +This product includes software developed by +ThoughtWorks (http://www.thoughtworks.com). +This product includes software developed by +javolution (http://javolution.org/). +This product includes software developed by +Rome (https://rome.dev.java.net/). + +about.html in archive lib/org.eclipse.sisu.inject-0.3.5.jar + + + + + +About org.eclipse.sisu.inject + + +

About org.eclipse.sisu.inject

+ +

November 5, 2013

+

License

+ +

The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content.

+ +

If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at http://www.eclipse.org.

+ +

Third Party Content

+

The Content includes items that have been sourced from third parties as set +out below. If you did not receive this Content directly from the Eclipse Foundation, +the following is provided for informational purposes only, and you should look +to the Redistributor's license for terms and conditions of use.

+ +

ASM 4.1

+

The plug-in includes software developed by the ObjectWeb consortium as part +of the ASM project at http://asm.ow2.org/.

+ +

A subset of ASM is re-packaged within the source and binary of the plug-in (org.eclipse.sisu.space.asm.*) +to avoid version collisions with other usage and is also available from the plug-in's github repository.

+ +

Your use of the ASM code is subject to the terms and conditions of the ASM License +below which is also available at http://asm.ow2.org/license.html.

+ +
+Copyright (c) 2000-2011 INRIA, France Telecom
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holders nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+
+ + + diff --git a/.tools/apache-maven-3.9.9/README.txt b/.tools/apache-maven-3.9.9/README.txt new file mode 100644 index 0000000..6d959bb --- /dev/null +++ b/.tools/apache-maven-3.9.9/README.txt @@ -0,0 +1,41 @@ + + Apache Maven + + What is it? + ----------- + + Maven is a software project management and comprehension tool. Based on + the concept of a Project Object Model (POM), Maven can manage a project's + build, reporting and documentation from a central piece of information. + + Documentation + ------------- + + The most up-to-date documentation can be found at https://maven.apache.org/. + + Release Notes + ------------- + + The full list of changes, system requirements and related can be found at https://maven.apache.org/docs/history.html. + + Installing Maven + ---------------- + + For complete documentation see https://maven.apache.org/download.html#Installation + + Licensing + --------- + + Please see the file called LICENSE. + + Maven URLS + ---------- + + Home Page: https://maven.apache.org/ + Downloads: https://maven.apache.org/download.html + Release Notes: https://maven.apache.org/docs/history.html + Mailing Lists: https://maven.apache.org/mailing-lists.html + Source Code: https://gitbox.apache.org/repos/asf/maven.git + Issue Tracking: https://issues.apache.org/jira/browse/MNG + Wiki: https://cwiki.apache.org/confluence/display/MAVEN/ + Available Plugins: https://maven.apache.org/plugins/ diff --git a/.tools/apache-maven-3.9.9/bin/m2.conf b/.tools/apache-maven-3.9.9/bin/m2.conf new file mode 100644 index 0000000..c446568 --- /dev/null +++ b/.tools/apache-maven-3.9.9/bin/m2.conf @@ -0,0 +1,10 @@ +main is org.apache.maven.cli.MavenCli from plexus.core + +set maven.conf default ${maven.home}/conf + +[plexus.core] +load ${maven.conf}/logging +optionally ${maven.home}/lib/ext/redisson/*.jar +optionally ${maven.home}/lib/ext/hazelcast/*.jar +optionally ${maven.home}/lib/ext/*.jar +load ${maven.home}/lib/*.jar diff --git a/.tools/apache-maven-3.9.9/bin/mvn b/.tools/apache-maven-3.9.9/bin/mvn new file mode 100644 index 0000000..38b036a --- /dev/null +++ b/.tools/apache-maven-3.9.9/bin/mvn @@ -0,0 +1,207 @@ +#!/bin/sh + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 +# +# http://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. + +# ----------------------------------------------------------------------------- +# Apache Maven Startup Script +# +# Environment Variable Prerequisites +# +# JAVA_HOME Must point at your Java Development Kit installation. +# MAVEN_ARGS (Optional) Arguments passed to Maven before CLI arguments. +# MAVEN_OPTS (Optional) Java runtime options used when Maven is executed. +# MAVEN_SKIP_RC (Optional) Flag to disable loading of mavenrc files. +# ----------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +mingw=false; +case "`uname`" in + CYGWIN*) cygwin=true;; + MINGW*) mingw=true;; +esac + +## resolve links - $0 may be a link to Maven's home +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 + +saveddir=`pwd` + +MAVEN_HOME=`dirname "$PRG"`/.. + +# make it fully qualified +MAVEN_HOME=`cd "$MAVEN_HOME" && pwd` + +cd "$saveddir" + +# For Cygwin, ensure paths are in Unix format before anything is touched +if $cygwin ; then + [ -n "$MAVEN_HOME" ] && + MAVEN_HOME=`cygpath --unix "$MAVEN_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For MinGW, ensure paths are in Unix format before anything is touched +if $mingw ; then + [ -n "$MAVEN_HOME" ] && + MAVEN_HOME=`(cd "$MAVEN_HOME"; pwd)` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`(cd "$JAVA_HOME"; pwd)` + # TODO classpath? +fi + +if [ -z "$JAVA_HOME" ] ; then + JAVACMD="`\\unset -f command; \\command -v java`" +else + JAVACMD="$JAVA_HOME/bin/java" +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "The JAVA_HOME environment variable is not defined correctly," >&2 + echo "this environment variable is needed to run this program." >&2 + exit 1 +fi + +CLASSWORLDS_JAR=`echo "${MAVEN_HOME}"/boot/plexus-classworlds-*.jar` +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + [ -n "$MAVEN_HOME" ] && + MAVEN_HOME=`cygpath --path --windows "$MAVEN_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$CLASSWORLDS_JAR" ] && + CLASSWORLDS_JAR=`cygpath --path --windows "$CLASSWORLDS_JAR"` +fi + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { +( + basedir=`find_file_argument_basedir "$@"` + wdir="${basedir}" + while : + do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + if [ "$wdir" = '/' ] ; then + break + fi + wdir=`cd "$wdir/.."; pwd` + done + echo "${basedir}" +) +} + +find_file_argument_basedir() { +( + basedir=`pwd` + + found_file_switch=0 + for arg in "$@"; do + if [ ${found_file_switch} -eq 1 ]; then + if [ -d "${arg}" ]; then + basedir=`cd "${arg}" && pwd -P` + elif [ -f "${arg}" ]; then + basedir=`dirname "${arg}"` + basedir=`cd "${basedir}" && pwd -P` + if [ ! -d "${basedir}" ]; then + echo "Directory ${basedir} extracted from the -f/--file command-line argument ${arg} does not exist" >&2 + exit 1 + fi + else + echo "POM file ${arg} specified with the -f/--file command line argument does not exist" >&2 + exit 1 + fi + break + fi + if [ "$arg" = "-f" -o "$arg" = "--file" ]; then + found_file_switch=1 + fi + done + echo "${basedir}" +) +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "`tr -s '\r\n' ' ' < "$1"`" + fi +} + +MAVEN_PROJECTBASEDIR="${MAVEN_BASEDIR:-`find_maven_basedir "$@"`}" +MAVEN_OPTS="`concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config"` $MAVEN_OPTS" + +# For Cygwin, switch project base directory path to Windows format before +# executing Maven otherwise this will cause Maven not to consider it. +if $cygwin ; then + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +export MAVEN_PROJECTBASEDIR + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ + -classpath "${CLASSWORLDS_JAR}" \ + "-Dclassworlds.conf=${MAVEN_HOME}/bin/m2.conf" \ + "-Dmaven.home=${MAVEN_HOME}" \ + "-Dlibrary.jansi.path=${MAVEN_HOME}/lib/jansi-native" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${CLASSWORLDS_LAUNCHER} ${MAVEN_ARGS} "$@" diff --git a/.tools/apache-maven-3.9.9/bin/mvn.cmd b/.tools/apache-maven-3.9.9/bin/mvn.cmd new file mode 100644 index 0000000..065f3c3 --- /dev/null +++ b/.tools/apache-maven-3.9.9/bin/mvn.cmd @@ -0,0 +1,202 @@ +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. + +@REM ----------------------------------------------------------------------------- +@REM Apache Maven Startup Script +@REM +@REM Environment Variable Prerequisites +@REM +@REM JAVA_HOME Must point at your Java Development Kit installation. +@REM MAVEN_ARGS (Optional) Arguments passed to Maven before CLI arguments. +@REM MAVEN_BATCH_ECHO (Optional) Set to 'on' to enable the echoing of the batch commands. +@REM MAVEN_BATCH_PAUSE (Optional) set to 'on' to wait for a key stroke before ending. +@REM MAVEN_OPTS (Optional) Java runtime options used when Maven is executed. +@REM MAVEN_SKIP_RC (Optional) Flag to disable loading of mavenrc files. +@REM ----------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%"=="on" echo %MAVEN_BATCH_ECHO% + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* +if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%"=="" goto OkJHome +for %%i in (java.exe) do set "JAVACMD=%%~$PATH:i" +goto checkJCmd + +:OkJHome +set "JAVACMD=%JAVA_HOME%\bin\java.exe" + +:checkJCmd +if exist "%JAVACMD%" goto chkMHome + +echo The JAVA_HOME environment variable is not defined correctly, >&2 +echo this environment variable is needed to run this program. >&2 +goto error + +:chkMHome +set "MAVEN_HOME=%~dp0" +set "MAVEN_HOME=%MAVEN_HOME:~0,-5%" +if not "%MAVEN_HOME%"=="" goto checkMCmd +goto error + +:checkMCmd +if exist "%MAVEN_HOME%\bin\mvn.cmd" goto init +goto error +@REM ==== END VALIDATION ==== + +:init + +set MAVEN_CMD_LINE_ARGS=%* + +@REM Find the project basedir, i.e., the directory that contains the directory ".mvn". +@REM Fallback to current working directory if not found. + +set "MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%" +if not "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set "EXEC_DIR=%CD%" +set "WDIR=%EXEC_DIR%" + +@REM Look for the --file switch and start the search for the .mvn directory from the specified +@REM POM location, if supplied. + +set FILE_ARG= +:arg_loop +if "%~1" == "-f" ( + set "FILE_ARG=%~2" + shift + goto process_file_arg +) +if "%~1" == "--file" ( + set "FILE_ARG=%~2" + shift + goto process_file_arg +) +@REM If none of the above, skip the argument +shift +if not "%~1" == "" ( + goto arg_loop +) else ( + goto findBaseDir +) + +:process_file_arg +if "%FILE_ARG%" == "" ( + goto findBaseDir +) +if not exist "%FILE_ARG%" ( + echo POM file "%FILE_ARG%" specified the -f/--file command-line argument does not exist >&2 + goto error +) +if exist "%FILE_ARG%\*" ( + set "POM_DIR=%FILE_ARG%" +) else ( + call :get_directory_from_file "%FILE_ARG%" +) +if not exist "%POM_DIR%" ( + echo Directory "%POM_DIR%" extracted from the -f/--file command-line argument "%FILE_ARG%" does not exist >&2 + goto error +) +set "WDIR=%POM_DIR%" +goto findBaseDir + +:get_directory_from_file +set "POM_DIR=%~dp1" +:stripPomDir +if not "_%POM_DIR:~-1%"=="_\" goto pomDirStripped +set "POM_DIR=%POM_DIR:~0,-1%" +goto stripPomDir +:pomDirStripped +exit /b + +:findBaseDir +cd /d "%WDIR%" +set "WDIR=%CD%" +:findBaseDirLoop +if exist ".mvn" goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set "WDIR=%CD%" +goto findBaseDirLoop + +:baseDirFound +set "MAVEN_PROJECTBASEDIR=%WDIR%" +cd /d "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +if "_%EXEC_DIR:~-1%"=="_\" set "EXEC_DIR=%EXEC_DIR:~0,-1%" +set "MAVEN_PROJECTBASEDIR=%EXEC_DIR%" +cd /d "%EXEC_DIR%" + +:endDetectBaseDir + +set "jvmConfig=\.mvn\jvm.config" +if not exist "%MAVEN_PROJECTBASEDIR%%jvmConfig%" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +for %%i in ("%MAVEN_HOME%"\boot\plexus-classworlds-*) do set CLASSWORLDS_JAR="%%i" +set CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +"%JAVACMD%" ^ + %JVM_CONFIG_MAVEN_PROPS% ^ + %MAVEN_OPTS% ^ + %MAVEN_DEBUG_OPTS% ^ + -classpath %CLASSWORLDS_JAR% ^ + "-Dclassworlds.conf=%MAVEN_HOME%\bin\m2.conf" ^ + "-Dmaven.home=%MAVEN_HOME%" ^ + "-Dlibrary.jansi.path=%MAVEN_HOME%\lib\jansi-native" ^ + "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ + %CLASSWORLDS_LAUNCHER% %MAVEN_ARGS% %MAVEN_CMD_LINE_ARGS% +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" +if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%"=="on" pause + +if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% + +exit /b %ERROR_CODE% diff --git a/.tools/apache-maven-3.9.9/bin/mvnDebug b/.tools/apache-maven-3.9.9/bin/mvnDebug new file mode 100644 index 0000000..2d7cafe --- /dev/null +++ b/.tools/apache-maven-3.9.9/bin/mvnDebug @@ -0,0 +1,36 @@ +#!/bin/sh + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 +# +# http://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. + +# ----------------------------------------------------------------------------- +# Apache Maven Debug Script +# +# Environment Variable Prerequisites +# +# JAVA_HOME Must point at your Java Development Kit installation. +# MAVEN_ARGS (Optional) Arguments passed to Maven before CLI arguments. +# MAVEN_OPTS (Optional) Java runtime options used when Maven is executed. +# MAVEN_SKIP_RC (Optional) Flag to disable loading of mavenrc files. +# MAVEN_DEBUG_ADDRESS (Optional) Set the debug address. Default value is 8000 +# ----------------------------------------------------------------------------- + +MAVEN_DEBUG_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=${MAVEN_DEBUG_ADDRESS:-8000}" + +echo Preparing to execute Maven in debug mode + +env MAVEN_OPTS="$MAVEN_OPTS" MAVEN_DEBUG_OPTS="$MAVEN_DEBUG_OPTS" "`dirname "$0"`/mvn" "$@" diff --git a/.tools/apache-maven-3.9.9/bin/mvnDebug.cmd b/.tools/apache-maven-3.9.9/bin/mvnDebug.cmd new file mode 100644 index 0000000..9777cf9 --- /dev/null +++ b/.tools/apache-maven-3.9.9/bin/mvnDebug.cmd @@ -0,0 +1,45 @@ +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. + +@REM ----------------------------------------------------------------------------- +@REM Apache Maven Debug Script +@REM +@REM Environment Variable Prerequisites +@REM +@REM JAVA_HOME Must point at your Java Development Kit installation. +@REM MAVEN_ARGS (Optional) Arguments passed to Maven before CLI arguments. +@REM MAVEN_BATCH_ECHO (Optional) Set to 'on' to enable the echoing of the batch commands. +@REM MAVEN_BATCH_PAUSE (Optional) set to 'on' to wait for a key stroke before ending. +@REM MAVEN_OPTS (Optional) Java runtime options used when Maven is executed. +@REM MAVEN_SKIP_RC (Optional) Flag to disable loading of mavenrc files. +@REM MAVEN_DEBUG_ADDRESS (Optional) Set the debug address. Default value is 8000 +@REM ----------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%"=="on" echo %MAVEN_BATCH_ECHO% + +@setlocal + +IF "%MAVEN_DEBUG_ADDRESS%"=="" @set MAVEN_DEBUG_ADDRESS=8000 + +@set MAVEN_DEBUG_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=%MAVEN_DEBUG_ADDRESS% + +@call "%~dp0"mvn.cmd %* diff --git a/.tools/apache-maven-3.9.9/bin/mvnyjp b/.tools/apache-maven-3.9.9/bin/mvnyjp new file mode 100644 index 0000000..6e21a0e --- /dev/null +++ b/.tools/apache-maven-3.9.9/bin/mvnyjp @@ -0,0 +1,36 @@ +#!/bin/sh + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 +# +# http://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. + +# ----------------------------------------------------------------------------- +# Apache Maven YourKit Profiler Startup Script +# +# Environment Variable Prerequisites +# +# JAVA_HOME Must point at your Java Development Kit installation. +# MAVEN_ARGS (Optional) Arguments passed to Maven before CLI arguments. +# MAVEN_OPTS (Optional) Java runtime options used when Maven is executed. +# MAVEN_SKIP_RC (Optional) Flag to disable loading of mavenrc files. +# ----------------------------------------------------------------------------- + +if [ ! -f "$YJPLIB" ]; then + echo "Error: Unable to autodetect the YJP library location. Please set YJPLIB variable" >&2 + exit 1 +fi + +env MAVEN_OPTS="-agentpath:$YJPLIB=onexit=snapshot,onexit=memory,tracing,onlylocal $MAVEN_OPTS" "`dirname "$0"`/mvn" "$@" diff --git a/.tools/apache-maven-3.9.9/boot/plexus-classworlds-2.8.0.jar b/.tools/apache-maven-3.9.9/boot/plexus-classworlds-2.8.0.jar new file mode 100644 index 0000000..21180ae Binary files /dev/null and b/.tools/apache-maven-3.9.9/boot/plexus-classworlds-2.8.0.jar differ diff --git a/.tools/apache-maven-3.9.9/boot/plexus-classworlds.license b/.tools/apache-maven-3.9.9/boot/plexus-classworlds.license new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/.tools/apache-maven-3.9.9/boot/plexus-classworlds.license @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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 + + http://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. diff --git a/.tools/apache-maven-3.9.9/conf/logging/simplelogger.properties b/.tools/apache-maven-3.9.9/conf/logging/simplelogger.properties new file mode 100644 index 0000000..8c4a5d1 --- /dev/null +++ b/.tools/apache-maven-3.9.9/conf/logging/simplelogger.properties @@ -0,0 +1,30 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 +# +# http://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. + +org.slf4j.simpleLogger.defaultLogLevel=info +org.slf4j.simpleLogger.showDateTime=false +org.slf4j.simpleLogger.showThreadName=false +org.slf4j.simpleLogger.showLogName=false +org.slf4j.simpleLogger.logFile=System.out +org.slf4j.simpleLogger.cacheOutputStream=true +org.slf4j.simpleLogger.levelInBrackets=true +org.slf4j.simpleLogger.log.Sisu=info +org.slf4j.simpleLogger.warnLevelString=WARNING + +# MNG-6181: mvn -X also prints all debug logging from HttpClient +org.slf4j.simpleLogger.log.org.apache.http=off +org.slf4j.simpleLogger.log.org.apache.http.wire=off diff --git a/.tools/apache-maven-3.9.9/conf/settings.xml b/.tools/apache-maven-3.9.9/conf/settings.xml new file mode 100644 index 0000000..0d64976 --- /dev/null +++ b/.tools/apache-maven-3.9.9/conf/settings.xml @@ -0,0 +1,265 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maven-default-http-blocker + external:http:* + Pseudo repository to mirror external repositories initially using HTTP. + http://0.0.0.0/ + true + + + + + + + + + + + + diff --git a/.tools/apache-maven-3.9.9/conf/toolchains.xml b/.tools/apache-maven-3.9.9/conf/toolchains.xml new file mode 100644 index 0000000..b263072 --- /dev/null +++ b/.tools/apache-maven-3.9.9/conf/toolchains.xml @@ -0,0 +1,103 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.tools/apache-maven-3.9.9/lib/aopalliance-1.0.jar b/.tools/apache-maven-3.9.9/lib/aopalliance-1.0.jar new file mode 100644 index 0000000..578b1a0 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/aopalliance-1.0.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/aopalliance.license b/.tools/apache-maven-3.9.9/lib/aopalliance.license new file mode 100644 index 0000000..a7a158b --- /dev/null +++ b/.tools/apache-maven-3.9.9/lib/aopalliance.license @@ -0,0 +1 @@ +Public Domain \ No newline at end of file diff --git a/.tools/apache-maven-3.9.9/lib/commons-cli-1.8.0.jar b/.tools/apache-maven-3.9.9/lib/commons-cli-1.8.0.jar new file mode 100644 index 0000000..27d2933 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/commons-cli-1.8.0.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/commons-cli.license b/.tools/apache-maven-3.9.9/lib/commons-cli.license new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/.tools/apache-maven-3.9.9/lib/commons-cli.license @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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 + + http://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. diff --git a/.tools/apache-maven-3.9.9/lib/commons-codec-1.17.1.jar b/.tools/apache-maven-3.9.9/lib/commons-codec-1.17.1.jar new file mode 100644 index 0000000..5023670 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/commons-codec-1.17.1.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/commons-codec.license b/.tools/apache-maven-3.9.9/lib/commons-codec.license new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/.tools/apache-maven-3.9.9/lib/commons-codec.license @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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 + + http://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. diff --git a/.tools/apache-maven-3.9.9/lib/ext/README.txt b/.tools/apache-maven-3.9.9/lib/ext/README.txt new file mode 100644 index 0000000..ab7f12a --- /dev/null +++ b/.tools/apache-maven-3.9.9/lib/ext/README.txt @@ -0,0 +1,2 @@ +Use this directory to add third party extensions to Maven Core. These extensions can either extend or override +Maven's default implementation. diff --git a/.tools/apache-maven-3.9.9/lib/ext/hazelcast/README.txt b/.tools/apache-maven-3.9.9/lib/ext/hazelcast/README.txt new file mode 100644 index 0000000..77d19b1 --- /dev/null +++ b/.tools/apache-maven-3.9.9/lib/ext/hazelcast/README.txt @@ -0,0 +1,6 @@ +This directory is intended to contain Hazelcast [1] JARs for Maven Resolver Named Locks using Hazelcast. + +See here [2] on how to add necessary JARs. + +[1] https://github.com/hazelcast/hazelcast +[2] https://maven.apache.org/resolver/maven-resolver-named-locks-hazelcast/index.html#installation-testing diff --git a/.tools/apache-maven-3.9.9/lib/ext/redisson/README.txt b/.tools/apache-maven-3.9.9/lib/ext/redisson/README.txt new file mode 100644 index 0000000..58342b1 --- /dev/null +++ b/.tools/apache-maven-3.9.9/lib/ext/redisson/README.txt @@ -0,0 +1,6 @@ +This directory is intended to contain Redisson [1] JARs for Maven Resolver Named Locks using Redisson. + +See here [2] on how to add necessary JARs. + +[1] https://github.com/redisson/redisson +[2] https://maven.apache.org/resolver/maven-resolver-named-locks-redisson/index.html#installation-testing diff --git a/.tools/apache-maven-3.9.9/lib/failureaccess-1.0.2.jar b/.tools/apache-maven-3.9.9/lib/failureaccess-1.0.2.jar new file mode 100644 index 0000000..d73ab80 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/failureaccess-1.0.2.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/failureaccess.license b/.tools/apache-maven-3.9.9/lib/failureaccess.license new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/.tools/apache-maven-3.9.9/lib/failureaccess.license @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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 + + http://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. diff --git a/.tools/apache-maven-3.9.9/lib/guava-33.2.1-jre.jar b/.tools/apache-maven-3.9.9/lib/guava-33.2.1-jre.jar new file mode 100644 index 0000000..10d10b6 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/guava-33.2.1-jre.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/guava.license b/.tools/apache-maven-3.9.9/lib/guava.license new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/.tools/apache-maven-3.9.9/lib/guava.license @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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 + + http://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. diff --git a/.tools/apache-maven-3.9.9/lib/guice-5.1.0.jar b/.tools/apache-maven-3.9.9/lib/guice-5.1.0.jar new file mode 100644 index 0000000..31c448f Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/guice-5.1.0.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/guice.license b/.tools/apache-maven-3.9.9/lib/guice.license new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/.tools/apache-maven-3.9.9/lib/guice.license @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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 + + http://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. diff --git a/.tools/apache-maven-3.9.9/lib/httpclient-4.5.14.jar b/.tools/apache-maven-3.9.9/lib/httpclient-4.5.14.jar new file mode 100644 index 0000000..2bb7c07 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/httpclient-4.5.14.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/httpclient.license b/.tools/apache-maven-3.9.9/lib/httpclient.license new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/.tools/apache-maven-3.9.9/lib/httpclient.license @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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 + + http://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. diff --git a/.tools/apache-maven-3.9.9/lib/httpcore-4.4.16.jar b/.tools/apache-maven-3.9.9/lib/httpcore-4.4.16.jar new file mode 100644 index 0000000..f0bdebe Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/httpcore-4.4.16.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/httpcore.license b/.tools/apache-maven-3.9.9/lib/httpcore.license new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/.tools/apache-maven-3.9.9/lib/httpcore.license @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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 + + http://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. diff --git a/.tools/apache-maven-3.9.9/lib/jansi-2.4.1.jar b/.tools/apache-maven-3.9.9/lib/jansi-2.4.1.jar new file mode 100644 index 0000000..3635b57 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/jansi-2.4.1.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/jansi-native/README.txt b/.tools/apache-maven-3.9.9/lib/jansi-native/README.txt new file mode 100644 index 0000000..26a957e --- /dev/null +++ b/.tools/apache-maven-3.9.9/lib/jansi-native/README.txt @@ -0,0 +1,8 @@ +This directory contains Jansi native libraries extracted from Jansi JAR. + +You can add your own build for platforms not natively supported by Jansi. +See here [1] on how to compile for your platform and and here [2] how libraries +follow Jansi's directory and filename conventions. + +[1] https://github.com/fusesource/jansi/tree/master/src/main/native +[2] https://github.com/fusesource/jansi/blob/321a8ff71c731e10f4ea05c607860180276b2215/src/main/java/org/fusesource/jansi/internal/OSInfo.java diff --git a/.tools/apache-maven-3.9.9/lib/jansi-native/Windows/arm64/libjansi.so b/.tools/apache-maven-3.9.9/lib/jansi-native/Windows/arm64/libjansi.so new file mode 100644 index 0000000..cce0178 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/jansi-native/Windows/arm64/libjansi.so differ diff --git a/.tools/apache-maven-3.9.9/lib/jansi-native/Windows/x86/jansi.dll b/.tools/apache-maven-3.9.9/lib/jansi-native/Windows/x86/jansi.dll new file mode 100644 index 0000000..8843d02 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/jansi-native/Windows/x86/jansi.dll differ diff --git a/.tools/apache-maven-3.9.9/lib/jansi-native/Windows/x86_64/jansi.dll b/.tools/apache-maven-3.9.9/lib/jansi-native/Windows/x86_64/jansi.dll new file mode 100644 index 0000000..aeec4e3 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/jansi-native/Windows/x86_64/jansi.dll differ diff --git a/.tools/apache-maven-3.9.9/lib/jansi.license b/.tools/apache-maven-3.9.9/lib/jansi.license new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/.tools/apache-maven-3.9.9/lib/jansi.license @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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 + + http://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. diff --git a/.tools/apache-maven-3.9.9/lib/javax.annotation-api-1.3.2.jar b/.tools/apache-maven-3.9.9/lib/javax.annotation-api-1.3.2.jar new file mode 100644 index 0000000..a8a470a Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/javax.annotation-api-1.3.2.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/javax.annotation-api.license b/.tools/apache-maven-3.9.9/lib/javax.annotation-api.license new file mode 100644 index 0000000..b1c74f9 --- /dev/null +++ b/.tools/apache-maven-3.9.9/lib/javax.annotation-api.license @@ -0,0 +1,759 @@ +COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.1 + +1. Definitions. + + 1.1. "Contributor" means each individual or entity that creates or + contributes to the creation of Modifications. + + 1.2. "Contributor Version" means the combination of the Original + Software, prior Modifications used by a Contributor (if any), and + the Modifications made by that particular Contributor. + + 1.3. "Covered Software" means (a) the Original Software, or (b) + Modifications, or (c) the combination of files containing Original + Software with files containing Modifications, in each case including + portions thereof. + + 1.4. "Executable" means the Covered Software in any form other than + Source Code. + + 1.5. "Initial Developer" means the individual or entity that first + makes Original Software available under this License. + + 1.6. "Larger Work" means a work which combines Covered Software or + portions thereof with code not governed by the terms of this License. + + 1.7. "License" means this document. + + 1.8. "Licensable" means having the right to grant, to the maximum + extent possible, whether at the time of the initial grant or + subsequently acquired, any and all of the rights conveyed herein. + + 1.9. "Modifications" means the Source Code and Executable form of + any of the following: + + A. Any file that results from an addition to, deletion from or + modification of the contents of a file containing Original Software + or previous Modifications; + + B. Any new file that contains any part of the Original Software or + previous Modification; or + + C. Any new file that is contributed or otherwise made available + under the terms of this License. + + 1.10. "Original Software" means the Source Code and Executable form + of computer software code that is originally released under this + License. + + 1.11. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation, method, process, + and apparatus claims, in any patent Licensable by grantor. + + 1.12. "Source Code" means (a) the common form of computer software + code in which modifications are made and (b) associated + documentation included in or with such code. + + 1.13. "You" (or "Your") means an individual or a legal entity + exercising rights under, and complying with all of the terms of, + this License. For legal entities, "You" includes any entity which + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants. + + 2.1. The Initial Developer Grant. + + Conditioned upon Your compliance with Section 3.1 below and subject + to third party intellectual property claims, the Initial Developer + hereby grants You a world-wide, royalty-free, non-exclusive license: + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Initial Developer, to use, reproduce, + modify, display, perform, sublicense and distribute the Original + Software (or portions thereof), with or without Modifications, + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using or selling of + Original Software, to make, have made, use, practice, sell, and + offer for sale, and/or otherwise dispose of the Original Software + (or portions thereof). + + (c) The licenses granted in Sections 2.1(a) and (b) are effective on + the date Initial Developer first distributes or otherwise makes the + Original Software available to a third party under the terms of this + License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is + granted: (1) for code that You delete from the Original Software, or + (2) for infringements caused by: (i) the modification of the + Original Software, or (ii) the combination of the Original Software + with other software or devices. + + 2.2. Contributor Grant. + + Conditioned upon Your compliance with Section 3.1 below and subject + to third party intellectual property claims, each Contributor hereby + grants You a world-wide, royalty-free, non-exclusive license: + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Contributor to use, reproduce, modify, + display, perform, sublicense and distribute the Modifications + created by such Contributor (or portions thereof), either on an + unmodified basis, with other Modifications, as Covered Software + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or selling + of Modifications made by that Contributor either alone and/or in + combination with its Contributor Version (or portions of such + combination), to make, use, sell, offer for sale, have made, and/or + otherwise dispose of: (1) Modifications made by that Contributor (or + portions thereof); and (2) the combination of Modifications made by + that Contributor with its Contributor Version (or portions of such + combination). + + (c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective + on the date Contributor first distributes or otherwise makes the + Modifications available to a third party. + + (d) Notwithstanding Section 2.2(b) above, no patent license is + granted: (1) for any code that Contributor has deleted from the + Contributor Version; (2) for infringements caused by: (i) third + party modifications of Contributor Version, or (ii) the combination + of Modifications made by that Contributor with other software + (except as part of the Contributor Version) or other devices; or (3) + under Patent Claims infringed by Covered Software in the absence of + Modifications made by that Contributor. + +3. Distribution Obligations. + + 3.1. Availability of Source Code. + + Any Covered Software that You distribute or otherwise make available + in Executable form must also be made available in Source Code form + and that Source Code form must be distributed only under the terms + of this License. You must include a copy of this License with every + copy of the Source Code form of the Covered Software You distribute + or otherwise make available. You must inform recipients of any such + Covered Software in Executable form as to how they can obtain such + Covered Software in Source Code form in a reasonable manner on or + through a medium customarily used for software exchange. + + 3.2. Modifications. + + The Modifications that You create or to which You contribute are + governed by the terms of this License. You represent that You + believe Your Modifications are Your original creation(s) and/or You + have sufficient rights to grant the rights conveyed by this License. + + 3.3. Required Notices. + + You must include a notice in each of Your Modifications that + identifies You as the Contributor of the Modification. You may not + remove or alter any copyright, patent or trademark notices contained + within the Covered Software, or any notices of licensing or any + descriptive text giving attribution to any Contributor or the + Initial Developer. + + 3.4. Application of Additional Terms. + + You may not offer or impose any terms on any Covered Software in + Source Code form that alters or restricts the applicable version of + this License or the recipients' rights hereunder. You may choose to + offer, and to charge a fee for, warranty, support, indemnity or + liability obligations to one or more recipients of Covered Software. + However, you may do so only on Your own behalf, and not on behalf of + the Initial Developer or any Contributor. You must make it + absolutely clear that any such warranty, support, indemnity or + liability obligation is offered by You alone, and You hereby agree + to indemnify the Initial Developer and every Contributor for any + liability incurred by the Initial Developer or such Contributor as a + result of warranty, support, indemnity or liability terms You offer. + + 3.5. Distribution of Executable Versions. + + You may distribute the Executable form of the Covered Software under + the terms of this License or under the terms of a license of Your + choice, which may contain terms different from this License, + provided that You are in compliance with the terms of this License + and that the license for the Executable form does not attempt to + limit or alter the recipient's rights in the Source Code form from + the rights set forth in this License. If You distribute the Covered + Software in Executable form under a different license, You must make + it absolutely clear that any terms which differ from this License + are offered by You alone, not by the Initial Developer or + Contributor. You hereby agree to indemnify the Initial Developer and + every Contributor for any liability incurred by the Initial + Developer or such Contributor as a result of any such terms You offer. + + 3.6. Larger Works. + + You may create a Larger Work by combining Covered Software with + other code not governed by the terms of this License and distribute + the Larger Work as a single product. In such a case, You must make + sure the requirements of this License are fulfilled for the Covered + Software. + +4. Versions of the License. + + 4.1. New Versions. + + Oracle is the initial license steward and may publish revised and/or + new versions of this License from time to time. Each version will be + given a distinguishing version number. Except as provided in Section + 4.3, no one other than the license steward has the right to modify + this License. + + 4.2. Effect of New Versions. + + You may always continue to use, distribute or otherwise make the + Covered Software available under the terms of the version of the + License under which You originally received the Covered Software. If + the Initial Developer includes a notice in the Original Software + prohibiting it from being distributed or otherwise made available + under any subsequent version of the License, You must distribute and + make the Covered Software available under the terms of the version + of the License under which You originally received the Covered + Software. Otherwise, You may also choose to use, distribute or + otherwise make the Covered Software available under the terms of any + subsequent version of the License published by the license steward. + + 4.3. Modified Versions. + + When You are an Initial Developer and You want to create a new + license for Your Original Software, You may create and use a + modified version of this License if You: (a) rename the license and + remove any references to the name of the license steward (except to + note that the license differs from this License); and (b) otherwise + make it clear that the license contains terms which differ from this + License. + +5. DISCLAIMER OF WARRANTY. + + COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, + INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE + IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR + NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF + THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE + DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY + OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, + REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN + ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS + AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +6. TERMINATION. + + 6.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to + cure such breach within 30 days of becoming aware of the breach. + Provisions which, by their nature, must remain in effect beyond the + termination of this License shall survive. + + 6.2. If You assert a patent infringement claim (excluding + declaratory judgment actions) against Initial Developer or a + Contributor (the Initial Developer or Contributor against whom You + assert such claim is referred to as "Participant") alleging that the + Participant Software (meaning the Contributor Version where the + Participant is a Contributor or the Original Software where the + Participant is the Initial Developer) directly or indirectly + infringes any patent, then any and all rights granted directly or + indirectly to You by such Participant, the Initial Developer (if the + Initial Developer is not the Participant) and all Contributors under + Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice + from Participant terminate prospectively and automatically at the + expiration of such 60 day notice period, unless if within such 60 + day period You withdraw Your claim with respect to the Participant + Software against such Participant either unilaterally or pursuant to + a written agreement with Participant. + + 6.3. If You assert a patent infringement claim against Participant + alleging that the Participant Software directly or indirectly + infringes any patent where such claim is resolved (such as by + license or settlement) prior to the initiation of patent + infringement litigation, then the reasonable value of the licenses + granted by such Participant under Sections 2.1 or 2.2 shall be taken + into account in determining the amount or value of any payment or + license. + + 6.4. In the event of termination under Sections 6.1 or 6.2 above, + all end user licenses that have been validly granted by You or any + distributor hereunder prior to termination (excluding licenses + granted to You by any distributor) shall survive termination. + +7. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE + INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF + COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE + TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR + CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT + LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER + FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR + LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE + POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT + APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH + PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH + LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR + LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION + AND LIMITATION MAY NOT APPLY TO YOU. + +8. U.S. GOVERNMENT END USERS. + + The Covered Software is a "commercial item," as that term is defined + in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer + software" (as that term is defined at 48 C.F.R. § + 252.227-7014(a)(1)) and "commercial computer software documentation" + as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent + with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 + (June 1995), all U.S. Government End Users acquire Covered Software + with only those rights set forth herein. This U.S. Government Rights + clause is in lieu of, and supersedes, any other FAR, DFAR, or other + clause or provision that addresses Government rights in computer + software under this License. + +9. MISCELLANEOUS. + + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. This License shall be governed by + the law of the jurisdiction specified in a notice contained within + the Original Software (except to the extent applicable law, if any, + provides otherwise), excluding such jurisdiction's conflict-of-law + provisions. Any litigation relating to this License shall be subject + to the jurisdiction of the courts located in the jurisdiction and + venue specified in a notice contained within the Original Software, + with the losing party responsible for costs, including, without + limitation, court costs and reasonable attorneys' fees and expenses. + The application of the United Nations Convention on Contracts for + the International Sale of Goods is expressly excluded. Any law or + regulation which provides that the language of a contract shall be + construed against the drafter shall not apply to this License. You + agree that You alone are responsible for compliance with the United + States export administration regulations (and the export control + laws and regulation of any other countries) when You use, distribute + or otherwise make available any Covered Software. + +10. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or indirectly, + out of its utilization of rights under this License and You agree to + work with Initial Developer and Contributors to distribute such + responsibility on an equitable basis. Nothing herein is intended or + shall be deemed to constitute any admission of liability. + +------------------------------------------------------------------------ + +NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION +LICENSE (CDDL) + +The code released under the CDDL shall be governed by the laws of the +State of California (excluding conflict-of-law provisions). Any +litigation relating to this License shall be subject to the jurisdiction +of the Federal Courts of the Northern District of California and the +state courts of the State of California, with venue lying in Santa Clara +County, California. + + + + The GNU General Public License (GPL) Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +51 Franklin Street, Fifth Floor +Boston, MA 02110-1335 +USA + +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your freedom to +share and change it. By contrast, the GNU General Public License is +intended to guarantee your freedom to share and change free software--to +make sure the software is free for all its users. This General Public +License applies to most of the Free Software Foundation's software and +to any other program whose authors commit to using it. (Some other Free +Software Foundation software is covered by the GNU Library General +Public License instead.) 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 this +service 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 make restrictions that forbid anyone +to deny you these rights or to ask you to surrender the rights. These +restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis +or for a fee, you must give the recipients all the rights that you have. +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. + +We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + +Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + +Finally, any free program is threatened constantly by software patents. +We wish to avoid the danger that redistributors of a free program will +individually obtain patent licenses, in effect making the program +proprietary. To prevent this, we have made it clear that any patent must +be licensed for everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and +modification follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a +notice placed by the copyright holder saying it may be distributed under +the terms of this General Public License. The "Program", below, refers +to any such program or work, and a "work based on the Program" means +either the Program or any derivative work under copyright law: that is +to say, a work containing the Program or a portion of it, either +verbatim or with modifications and/or translated into another language. +(Hereinafter, translation is included without limitation in the term +"modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of running +the Program is not restricted, and the output from the Program is +covered only if its contents constitute a work based on the Program +(independent of having been made by running the Program). Whether that +is true depends on what the Program does. + +1. You may copy and distribute 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 +and disclaimer of warranty; keep intact all the notices that refer to +this License and to the absence of any warranty; and give any other +recipients of the Program a copy of this License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of +it, thus forming a work based on the Program, and copy and distribute +such modifications or work under the terms of Section 1 above, provided +that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any part + thereof, to be licensed as a whole at no charge to all third parties + under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a notice + that there is no warranty (or else, saying that you provide a + warranty) and that users may redistribute the program under these + conditions, and telling the user how to view a copy of this License. + (Exception: if the Program itself is interactive but does not + normally print such an announcement, your work based on the Program + is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, and +can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based on +the Program, the distribution of the whole must be on the terms of this +License, whose permissions for other licensees extend to the entire +whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of a +storage or distribution medium does not bring the other work under the +scope of this License. + +3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections 1 + and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your cost + of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer to + distribute corresponding source code. (This alternative is allowed + only for noncommercial distribution and only if you received the + program in object code or executable form with such an offer, in + accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source code +means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to control +compilation and installation of the executable. However, as a special +exception, the source code distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies the +executable. + +If distribution of executable or object code is made by offering access +to copy from a designated place, then offering equivalent access to copy +the source code from the same place counts as distribution of the source +code, even though third parties are not compelled to copy the source +along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt otherwise +to copy, modify, sublicense or distribute the Program is void, and will +automatically terminate your rights under this License. However, parties +who have received copies, or rights, from you under this License will +not have their licenses terminated so long as such parties remain in +full compliance. + +5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and all +its terms and conditions for copying, distributing or modifying the +Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further restrictions +on the recipients' exercise of the rights granted herein. You are not +responsible for enforcing compliance by third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +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 distribute +so as to satisfy simultaneously your obligations under this License and +any other pertinent obligations, then as a consequence you may not +distribute the Program at all. For example, if a patent license would +not permit royalty-free redistribution of the Program by all those who +receive copies directly or indirectly through you, then the only way you +could satisfy both it and this License would be to refrain entirely from +distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is implemented +by public license practices. Many people have made generous +contributions to the wide range of software distributed through that +system in reliance on consistent application of that system; it is up to +the author/donor to decide if he or she is willing to distribute +software through any other system and a licensee cannot impose that choice. + +This section is intended to make thoroughly clear what is believed to be +a consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License may +add an explicit geographical distribution limitation excluding those +countries, so that distribution is permitted only in or among countries +not thus excluded. In such case, this License incorporates the +limitation as if written in the body of this License. + +9. The Free Software Foundation may publish revised and/or new +versions of the 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 a version number of this License which applies to it and "any +later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Program does not specify a version +number of this License, you may choose any version ever published by the +Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the +author to ask for permission. For software which is copyrighted by the +Free Software Foundation, write to the Free Software Foundation; we +sometimes make exceptions for this. Our decision will be guided by the +two goals of preserving the free status of all derivatives of our free +software and of promoting the sharing and reuse of software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE 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. + +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to +attach them to the start of each source file to most effectively convey +the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + One line to give the program's name and a brief idea of what it does. + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type + `show w'. This is free software, and you are welcome to redistribute + it under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the +appropriate parts of the General Public License. Of course, the commands +you use may be called something other than `show w' and `show c'; they +could even be mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + program `Gnomovision' (which makes passes at compilers) written by + James Hacker. + + signature of Ty Coon, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications +with the library. If this is what you want to do, use the GNU Library +General Public License instead of this License. + +# + +Certain source files distributed by Oracle America, Inc. and/or its +affiliates are subject to the following clarification and special +exception to the GPLv2, based on the GNU Project exception for its +Classpath libraries, known as the GNU Classpath Exception, but only +where Oracle has expressly included in the particular source file's +header the words "Oracle designates this particular file as subject to +the "Classpath" exception as provided by Oracle in the LICENSE file +that accompanied this code." + +You should also note that Oracle includes multiple, independent +programs in this software package. Some of those programs are provided +under licenses deemed incompatible with the GPLv2 by the Free Software +Foundation and others. For example, the package includes programs +licensed under the Apache License, Version 2.0. Such programs are +licensed to you under their original licenses. + +Oracle facilitates your further distribution of this package by adding +the Classpath Exception to the necessary parts of its GPLv2 code, which +permits you to use that code in combination with other independent +modules not licensed under the GPLv2. However, note that this would +not permit you to commingle code under an incompatible license with +Oracle's GPLv2 licensed code by, for example, cutting and pasting such +code into a file also containing Oracle's GPLv2 licensed code and then +distributing the result. Additionally, if you were to remove the +Classpath Exception from any of the files to which it applies and +distribute the result, you would likely be required to license some or +all of the other code in that distribution under the GPLv2 as well, and +since the GPLv2 is incompatible with the license terms of some items +included in the distribution by Oracle, removing the Classpath +Exception could therefore effectively compromise your ability to +further distribute the package. + +Proceed with caution and we recommend that you obtain the advice of a +lawyer skilled in open source matters before removing the Classpath +Exception or making modifications to this package which may +subsequently be redistributed and/or involve the use of third party +software. + +CLASSPATH EXCEPTION +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License version 2 cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from or +based on this library. If you modify this library, you may extend this +exception to your version of the library, but you are not obligated to +do so. If you do not wish to do so, delete this exception statement +from your version. diff --git a/.tools/apache-maven-3.9.9/lib/javax.inject-1.jar b/.tools/apache-maven-3.9.9/lib/javax.inject-1.jar new file mode 100644 index 0000000..b2a9d0b Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/javax.inject-1.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/javax.inject.license b/.tools/apache-maven-3.9.9/lib/javax.inject.license new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/.tools/apache-maven-3.9.9/lib/javax.inject.license @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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 + + http://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. diff --git a/.tools/apache-maven-3.9.9/lib/jcl-over-slf4j-1.7.36.jar b/.tools/apache-maven-3.9.9/lib/jcl-over-slf4j-1.7.36.jar new file mode 100644 index 0000000..3ecd7d5 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/jcl-over-slf4j-1.7.36.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/jcl-over-slf4j.license b/.tools/apache-maven-3.9.9/lib/jcl-over-slf4j.license new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/.tools/apache-maven-3.9.9/lib/jcl-over-slf4j.license @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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 + + http://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. diff --git a/.tools/apache-maven-3.9.9/lib/maven-artifact-3.9.9.jar b/.tools/apache-maven-3.9.9/lib/maven-artifact-3.9.9.jar new file mode 100644 index 0000000..b014207 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/maven-artifact-3.9.9.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/maven-builder-support-3.9.9.jar b/.tools/apache-maven-3.9.9/lib/maven-builder-support-3.9.9.jar new file mode 100644 index 0000000..de75eea Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/maven-builder-support-3.9.9.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/maven-compat-3.9.9.jar b/.tools/apache-maven-3.9.9/lib/maven-compat-3.9.9.jar new file mode 100644 index 0000000..5b99205 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/maven-compat-3.9.9.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/maven-core-3.9.9.jar b/.tools/apache-maven-3.9.9/lib/maven-core-3.9.9.jar new file mode 100644 index 0000000..fcdf49c Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/maven-core-3.9.9.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/maven-embedder-3.9.9.jar b/.tools/apache-maven-3.9.9/lib/maven-embedder-3.9.9.jar new file mode 100644 index 0000000..8a377aa Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/maven-embedder-3.9.9.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/maven-model-3.9.9.jar b/.tools/apache-maven-3.9.9/lib/maven-model-3.9.9.jar new file mode 100644 index 0000000..ad8765e Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/maven-model-3.9.9.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/maven-model-builder-3.9.9.jar b/.tools/apache-maven-3.9.9/lib/maven-model-builder-3.9.9.jar new file mode 100644 index 0000000..bd68a80 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/maven-model-builder-3.9.9.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/maven-plugin-api-3.9.9.jar b/.tools/apache-maven-3.9.9/lib/maven-plugin-api-3.9.9.jar new file mode 100644 index 0000000..488fed8 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/maven-plugin-api-3.9.9.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/maven-repository-metadata-3.9.9.jar b/.tools/apache-maven-3.9.9/lib/maven-repository-metadata-3.9.9.jar new file mode 100644 index 0000000..fb725bf Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/maven-repository-metadata-3.9.9.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/maven-resolver-api-1.9.22.jar b/.tools/apache-maven-3.9.9/lib/maven-resolver-api-1.9.22.jar new file mode 100644 index 0000000..1847797 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/maven-resolver-api-1.9.22.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/maven-resolver-connector-basic-1.9.22.jar b/.tools/apache-maven-3.9.9/lib/maven-resolver-connector-basic-1.9.22.jar new file mode 100644 index 0000000..a9ad770 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/maven-resolver-connector-basic-1.9.22.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/maven-resolver-impl-1.9.22.jar b/.tools/apache-maven-3.9.9/lib/maven-resolver-impl-1.9.22.jar new file mode 100644 index 0000000..7febfea Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/maven-resolver-impl-1.9.22.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/maven-resolver-named-locks-1.9.22.jar b/.tools/apache-maven-3.9.9/lib/maven-resolver-named-locks-1.9.22.jar new file mode 100644 index 0000000..6b32547 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/maven-resolver-named-locks-1.9.22.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/maven-resolver-provider-3.9.9.jar b/.tools/apache-maven-3.9.9/lib/maven-resolver-provider-3.9.9.jar new file mode 100644 index 0000000..5c8082f Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/maven-resolver-provider-3.9.9.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/maven-resolver-spi-1.9.22.jar b/.tools/apache-maven-3.9.9/lib/maven-resolver-spi-1.9.22.jar new file mode 100644 index 0000000..c473f1c Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/maven-resolver-spi-1.9.22.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/maven-resolver-transport-file-1.9.22.jar b/.tools/apache-maven-3.9.9/lib/maven-resolver-transport-file-1.9.22.jar new file mode 100644 index 0000000..04fbe9f Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/maven-resolver-transport-file-1.9.22.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/maven-resolver-transport-http-1.9.22.jar b/.tools/apache-maven-3.9.9/lib/maven-resolver-transport-http-1.9.22.jar new file mode 100644 index 0000000..e116b90 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/maven-resolver-transport-http-1.9.22.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/maven-resolver-transport-wagon-1.9.22.jar b/.tools/apache-maven-3.9.9/lib/maven-resolver-transport-wagon-1.9.22.jar new file mode 100644 index 0000000..047affa Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/maven-resolver-transport-wagon-1.9.22.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/maven-resolver-util-1.9.22.jar b/.tools/apache-maven-3.9.9/lib/maven-resolver-util-1.9.22.jar new file mode 100644 index 0000000..a99ded1 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/maven-resolver-util-1.9.22.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/maven-settings-3.9.9.jar b/.tools/apache-maven-3.9.9/lib/maven-settings-3.9.9.jar new file mode 100644 index 0000000..5b37131 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/maven-settings-3.9.9.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/maven-settings-builder-3.9.9.jar b/.tools/apache-maven-3.9.9/lib/maven-settings-builder-3.9.9.jar new file mode 100644 index 0000000..0cb6ebb Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/maven-settings-builder-3.9.9.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/maven-shared-utils-3.4.2.jar b/.tools/apache-maven-3.9.9/lib/maven-shared-utils-3.4.2.jar new file mode 100644 index 0000000..a72853d Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/maven-shared-utils-3.4.2.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/maven-slf4j-provider-3.9.9.jar b/.tools/apache-maven-3.9.9/lib/maven-slf4j-provider-3.9.9.jar new file mode 100644 index 0000000..868c199 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/maven-slf4j-provider-3.9.9.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/org.eclipse.sisu.inject-0.9.0.M3.jar b/.tools/apache-maven-3.9.9/lib/org.eclipse.sisu.inject-0.9.0.M3.jar new file mode 100644 index 0000000..fc768dc Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/org.eclipse.sisu.inject-0.9.0.M3.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/org.eclipse.sisu.inject.license b/.tools/apache-maven-3.9.9/lib/org.eclipse.sisu.inject.license new file mode 100644 index 0000000..e55f344 --- /dev/null +++ b/.tools/apache-maven-3.9.9/lib/org.eclipse.sisu.inject.license @@ -0,0 +1,277 @@ +Eclipse Public License - v 2.0 + + THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE + PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION + OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + + a) in the case of the initial Contributor, the initial content + Distributed under this Agreement, and + + b) in the case of each subsequent Contributor: + i) changes to the Program, and + ii) additions to the Program; + where such changes and/or additions to the Program originate from + and are Distributed by that particular Contributor. A Contribution + "originates" from a Contributor if it was added to the Program by + such Contributor itself or anyone acting on such Contributor's behalf. + Contributions do not include changes or additions to the Program that + are not Modified Works. + +"Contributor" means any person or entity that Distributes the Program. + +"Licensed Patents" mean patent claims licensable by a Contributor which +are necessarily infringed by the use or sale of its Contribution alone +or when combined with the Program. + +"Program" means the Contributions Distributed in accordance with this +Agreement. + +"Recipient" means anyone who receives the Program under this Agreement +or any Secondary License (as applicable), including Contributors. + +"Derivative Works" shall mean any work, whether in Source Code or other +form, that is based on (or derived from) the Program and for which the +editorial revisions, annotations, elaborations, or other modifications +represent, as a whole, an original work of authorship. + +"Modified Works" shall mean any work in Source Code or other form that +results from an addition to, deletion from, or modification of the +contents of the Program, including, for purposes of clarity any new file +in Source Code form that contains any contents of the Program. Modified +Works shall not include works that contain only declarations, +interfaces, types, classes, structures, or files of the Program solely +in each case in order to link to, bind by name, or subclass the Program +or Modified Works thereof. + +"Distribute" means the acts of a) distributing or b) making available +in any manner that enables the transfer of a copy. + +"Source Code" means the form of a Program preferred for making +modifications, including but not limited to software source code, +documentation source, and configuration files. + +"Secondary License" means either the GNU General Public License, +Version 2.0, or any later versions of that license, including any +exceptions or additional permissions as identified by the initial +Contributor. + +2. GRANT OF RIGHTS + + a) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free copyright + license to reproduce, prepare Derivative Works of, publicly display, + publicly perform, Distribute and sublicense the Contribution of such + Contributor, if any, and such Derivative Works. + + b) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free patent + license under Licensed Patents to make, use, sell, offer to sell, + import and otherwise transfer the Contribution of such Contributor, + if any, in Source Code or other form. This patent license shall + apply to the combination of the Contribution and the Program if, at + the time the Contribution is added by the Contributor, such addition + of the Contribution causes such combination to be covered by the + Licensed Patents. The patent license shall not apply to any other + combinations which include the Contribution. No hardware per se is + licensed hereunder. + + c) Recipient understands that although each Contributor grants the + licenses to its Contributions set forth herein, no assurances are + provided by any Contributor that the Program does not infringe the + patent or other intellectual property rights of any other entity. + Each Contributor disclaims any liability to Recipient for claims + brought by any other entity based on infringement of intellectual + property rights or otherwise. As a condition to exercising the + rights and licenses granted hereunder, each Recipient hereby + assumes sole responsibility to secure any other intellectual + property rights needed, if any. For example, if a third party + patent license is required to allow Recipient to Distribute the + Program, it is Recipient's responsibility to acquire that license + before distributing the Program. + + d) Each Contributor represents that to its knowledge it has + sufficient copyright rights in its Contribution, if any, to grant + the copyright license set forth in this Agreement. + + e) Notwithstanding the terms of any Secondary License, no + Contributor makes additional grants to any Recipient (other than + those set forth in this Agreement) as a result of such Recipient's + receipt of the Program under the terms of a Secondary License + (if permitted under the terms of Section 3). + +3. REQUIREMENTS + +3.1 If a Contributor Distributes the Program in any form, then: + + a) the Program must also be made available as Source Code, in + accordance with section 3.2, and the Contributor must accompany + the Program with a statement that the Source Code for the Program + is available under this Agreement, and informs Recipients how to + obtain it in a reasonable manner on or through a medium customarily + used for software exchange; and + + b) the Contributor may Distribute the Program under a license + different than this Agreement, provided that such license: + i) effectively disclaims on behalf of all other Contributors all + warranties and conditions, express and implied, including + warranties or conditions of title and non-infringement, and + implied warranties or conditions of merchantability and fitness + for a particular purpose; + + ii) effectively excludes on behalf of all other Contributors all + liability for damages, including direct, indirect, special, + incidental and consequential damages, such as lost profits; + + iii) does not attempt to limit or alter the recipients' rights + in the Source Code under section 3.2; and + + iv) requires any subsequent distribution of the Program by any + party to be under a license that satisfies the requirements + of this section 3. + +3.2 When the Program is Distributed as Source Code: + + a) it must be made available under this Agreement, or if the + Program (i) is combined with other material in a separate file or + files made available under a Secondary License, and (ii) the initial + Contributor attached to the Source Code the notice described in + Exhibit A of this Agreement, then the Program may be made available + under the terms of such Secondary Licenses, and + + b) a copy of this Agreement must be included with each copy of + the Program. + +3.3 Contributors may not remove or alter any copyright, patent, +trademark, attribution notices, disclaimers of warranty, or limitations +of liability ("notices") contained within the Program from any copy of +the Program which they Distribute, provided that Contributors may add +their own appropriate notices. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities +with respect to end users, business partners and the like. While this +license is intended to facilitate the commercial use of the Program, +the Contributor who includes the Program in a commercial product +offering should do so in a manner which does not create potential +liability for other Contributors. Therefore, if a Contributor includes +the Program in a commercial product offering, such Contributor +("Commercial Contributor") hereby agrees to defend and indemnify every +other Contributor ("Indemnified Contributor") against any losses, +damages and costs (collectively "Losses") arising from claims, lawsuits +and other legal actions brought by a third party against the Indemnified +Contributor to the extent caused by the acts or omissions of such +Commercial Contributor in connection with its distribution of the Program +in a commercial product offering. The obligations in this section do not +apply to any claims or Losses relating to any actual or alleged +intellectual property infringement. In order to qualify, an Indemnified +Contributor must: a) promptly notify the Commercial Contributor in +writing of such claim, and b) allow the Commercial Contributor to control, +and cooperate with the Commercial Contributor in, the defense and any +related settlement negotiations. The Indemnified Contributor may +participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial +product offering, Product X. That Contributor is then a Commercial +Contributor. If that Commercial Contributor then makes performance +claims, or offers warranties related to Product X, those performance +claims and warranties are such Commercial Contributor's responsibility +alone. Under this section, the Commercial Contributor would have to +defend claims against the other Contributors related to those performance +claims and warranties, and if a court requires any other Contributor to +pay any damages as a result, the Commercial Contributor must pay +those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT +PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS" +BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR +IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF +TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR +PURPOSE. Each Recipient is solely responsible for determining the +appropriateness of using and distributing the Program and assumes all +risks associated with its exercise of rights under this Agreement, +including but not limited to the risks and costs of program errors, +compliance with applicable laws, damage to or loss of data, programs +or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT +PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS +SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST +PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE +EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under +applicable law, it shall not affect the validity or enforceability of +the remainder of the terms of this Agreement, and without further +action by the parties hereto, such provision shall be reformed to the +minimum extent necessary to make such provision valid and enforceable. + +If Recipient institutes patent litigation against any entity +(including a cross-claim or counterclaim in a lawsuit) alleging that the +Program itself (excluding combinations of the Program with other software +or hardware) infringes such Recipient's patent(s), then such Recipient's +rights granted under Section 2(b) shall terminate as of the date such +litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it +fails to comply with any of the material terms or conditions of this +Agreement and does not cure such failure in a reasonable period of +time after becoming aware of such noncompliance. If all Recipient's +rights under this Agreement terminate, Recipient agrees to cease use +and distribution of the Program as soon as reasonably practicable. +However, Recipient's obligations under this Agreement and any licenses +granted by Recipient relating to the Program shall continue and survive. + +Everyone is permitted to copy and distribute copies of this Agreement, +but in order to avoid inconsistency the Agreement is copyrighted and +may only be modified in the following manner. The Agreement Steward +reserves the right to publish new versions (including revisions) of +this Agreement from time to time. No one other than the Agreement +Steward has the right to modify this Agreement. The Eclipse Foundation +is the initial Agreement Steward. The Eclipse Foundation may assign the +responsibility to serve as the Agreement Steward to a suitable separate +entity. Each new version of the Agreement will be given a distinguishing +version number. The Program (including Contributions) may always be +Distributed subject to the version of the Agreement under which it was +received. In addition, after a new version of the Agreement is published, +Contributor may elect to Distribute the Program (including its +Contributions) under the new version. + +Except as expressly stated in Sections 2(a) and 2(b) above, Recipient +receives no rights or licenses to the intellectual property of any +Contributor under this Agreement, whether expressly, by implication, +estoppel or otherwise. All rights in the Program not expressly granted +under this Agreement are reserved. Nothing in this Agreement is intended +to be enforceable by any entity that is not a Contributor or Recipient. +No third-party beneficiary rights are created under this Agreement. + +Exhibit A - Form of Secondary Licenses Notice + +"This Source Code may also be made available under the following +Secondary Licenses when the conditions for such availability set forth +in the Eclipse Public License, v. 2.0 are satisfied: {name license(s), +version(s), and exceptions or additional permissions here}." + + Simply including a copy of this Agreement, including this Exhibit A + is not sufficient to license the Source Code under Secondary Licenses. + + If it is not possible or desirable to put the notice in a particular + file, then You may include the notice in a location (such as a LICENSE + file in a relevant directory) where a recipient would be likely to + look for such a notice. + + You may add additional accurate notices of copyright ownership. \ No newline at end of file diff --git a/.tools/apache-maven-3.9.9/lib/org.eclipse.sisu.plexus-0.9.0.M3.jar b/.tools/apache-maven-3.9.9/lib/org.eclipse.sisu.plexus-0.9.0.M3.jar new file mode 100644 index 0000000..f2c4d1c Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/org.eclipse.sisu.plexus-0.9.0.M3.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/org.eclipse.sisu.plexus.license b/.tools/apache-maven-3.9.9/lib/org.eclipse.sisu.plexus.license new file mode 100644 index 0000000..e55f344 --- /dev/null +++ b/.tools/apache-maven-3.9.9/lib/org.eclipse.sisu.plexus.license @@ -0,0 +1,277 @@ +Eclipse Public License - v 2.0 + + THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE + PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION + OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + + a) in the case of the initial Contributor, the initial content + Distributed under this Agreement, and + + b) in the case of each subsequent Contributor: + i) changes to the Program, and + ii) additions to the Program; + where such changes and/or additions to the Program originate from + and are Distributed by that particular Contributor. A Contribution + "originates" from a Contributor if it was added to the Program by + such Contributor itself or anyone acting on such Contributor's behalf. + Contributions do not include changes or additions to the Program that + are not Modified Works. + +"Contributor" means any person or entity that Distributes the Program. + +"Licensed Patents" mean patent claims licensable by a Contributor which +are necessarily infringed by the use or sale of its Contribution alone +or when combined with the Program. + +"Program" means the Contributions Distributed in accordance with this +Agreement. + +"Recipient" means anyone who receives the Program under this Agreement +or any Secondary License (as applicable), including Contributors. + +"Derivative Works" shall mean any work, whether in Source Code or other +form, that is based on (or derived from) the Program and for which the +editorial revisions, annotations, elaborations, or other modifications +represent, as a whole, an original work of authorship. + +"Modified Works" shall mean any work in Source Code or other form that +results from an addition to, deletion from, or modification of the +contents of the Program, including, for purposes of clarity any new file +in Source Code form that contains any contents of the Program. Modified +Works shall not include works that contain only declarations, +interfaces, types, classes, structures, or files of the Program solely +in each case in order to link to, bind by name, or subclass the Program +or Modified Works thereof. + +"Distribute" means the acts of a) distributing or b) making available +in any manner that enables the transfer of a copy. + +"Source Code" means the form of a Program preferred for making +modifications, including but not limited to software source code, +documentation source, and configuration files. + +"Secondary License" means either the GNU General Public License, +Version 2.0, or any later versions of that license, including any +exceptions or additional permissions as identified by the initial +Contributor. + +2. GRANT OF RIGHTS + + a) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free copyright + license to reproduce, prepare Derivative Works of, publicly display, + publicly perform, Distribute and sublicense the Contribution of such + Contributor, if any, and such Derivative Works. + + b) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free patent + license under Licensed Patents to make, use, sell, offer to sell, + import and otherwise transfer the Contribution of such Contributor, + if any, in Source Code or other form. This patent license shall + apply to the combination of the Contribution and the Program if, at + the time the Contribution is added by the Contributor, such addition + of the Contribution causes such combination to be covered by the + Licensed Patents. The patent license shall not apply to any other + combinations which include the Contribution. No hardware per se is + licensed hereunder. + + c) Recipient understands that although each Contributor grants the + licenses to its Contributions set forth herein, no assurances are + provided by any Contributor that the Program does not infringe the + patent or other intellectual property rights of any other entity. + Each Contributor disclaims any liability to Recipient for claims + brought by any other entity based on infringement of intellectual + property rights or otherwise. As a condition to exercising the + rights and licenses granted hereunder, each Recipient hereby + assumes sole responsibility to secure any other intellectual + property rights needed, if any. For example, if a third party + patent license is required to allow Recipient to Distribute the + Program, it is Recipient's responsibility to acquire that license + before distributing the Program. + + d) Each Contributor represents that to its knowledge it has + sufficient copyright rights in its Contribution, if any, to grant + the copyright license set forth in this Agreement. + + e) Notwithstanding the terms of any Secondary License, no + Contributor makes additional grants to any Recipient (other than + those set forth in this Agreement) as a result of such Recipient's + receipt of the Program under the terms of a Secondary License + (if permitted under the terms of Section 3). + +3. REQUIREMENTS + +3.1 If a Contributor Distributes the Program in any form, then: + + a) the Program must also be made available as Source Code, in + accordance with section 3.2, and the Contributor must accompany + the Program with a statement that the Source Code for the Program + is available under this Agreement, and informs Recipients how to + obtain it in a reasonable manner on or through a medium customarily + used for software exchange; and + + b) the Contributor may Distribute the Program under a license + different than this Agreement, provided that such license: + i) effectively disclaims on behalf of all other Contributors all + warranties and conditions, express and implied, including + warranties or conditions of title and non-infringement, and + implied warranties or conditions of merchantability and fitness + for a particular purpose; + + ii) effectively excludes on behalf of all other Contributors all + liability for damages, including direct, indirect, special, + incidental and consequential damages, such as lost profits; + + iii) does not attempt to limit or alter the recipients' rights + in the Source Code under section 3.2; and + + iv) requires any subsequent distribution of the Program by any + party to be under a license that satisfies the requirements + of this section 3. + +3.2 When the Program is Distributed as Source Code: + + a) it must be made available under this Agreement, or if the + Program (i) is combined with other material in a separate file or + files made available under a Secondary License, and (ii) the initial + Contributor attached to the Source Code the notice described in + Exhibit A of this Agreement, then the Program may be made available + under the terms of such Secondary Licenses, and + + b) a copy of this Agreement must be included with each copy of + the Program. + +3.3 Contributors may not remove or alter any copyright, patent, +trademark, attribution notices, disclaimers of warranty, or limitations +of liability ("notices") contained within the Program from any copy of +the Program which they Distribute, provided that Contributors may add +their own appropriate notices. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities +with respect to end users, business partners and the like. While this +license is intended to facilitate the commercial use of the Program, +the Contributor who includes the Program in a commercial product +offering should do so in a manner which does not create potential +liability for other Contributors. Therefore, if a Contributor includes +the Program in a commercial product offering, such Contributor +("Commercial Contributor") hereby agrees to defend and indemnify every +other Contributor ("Indemnified Contributor") against any losses, +damages and costs (collectively "Losses") arising from claims, lawsuits +and other legal actions brought by a third party against the Indemnified +Contributor to the extent caused by the acts or omissions of such +Commercial Contributor in connection with its distribution of the Program +in a commercial product offering. The obligations in this section do not +apply to any claims or Losses relating to any actual or alleged +intellectual property infringement. In order to qualify, an Indemnified +Contributor must: a) promptly notify the Commercial Contributor in +writing of such claim, and b) allow the Commercial Contributor to control, +and cooperate with the Commercial Contributor in, the defense and any +related settlement negotiations. The Indemnified Contributor may +participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial +product offering, Product X. That Contributor is then a Commercial +Contributor. If that Commercial Contributor then makes performance +claims, or offers warranties related to Product X, those performance +claims and warranties are such Commercial Contributor's responsibility +alone. Under this section, the Commercial Contributor would have to +defend claims against the other Contributors related to those performance +claims and warranties, and if a court requires any other Contributor to +pay any damages as a result, the Commercial Contributor must pay +those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT +PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS" +BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR +IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF +TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR +PURPOSE. Each Recipient is solely responsible for determining the +appropriateness of using and distributing the Program and assumes all +risks associated with its exercise of rights under this Agreement, +including but not limited to the risks and costs of program errors, +compliance with applicable laws, damage to or loss of data, programs +or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT +PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS +SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST +PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE +EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under +applicable law, it shall not affect the validity or enforceability of +the remainder of the terms of this Agreement, and without further +action by the parties hereto, such provision shall be reformed to the +minimum extent necessary to make such provision valid and enforceable. + +If Recipient institutes patent litigation against any entity +(including a cross-claim or counterclaim in a lawsuit) alleging that the +Program itself (excluding combinations of the Program with other software +or hardware) infringes such Recipient's patent(s), then such Recipient's +rights granted under Section 2(b) shall terminate as of the date such +litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it +fails to comply with any of the material terms or conditions of this +Agreement and does not cure such failure in a reasonable period of +time after becoming aware of such noncompliance. If all Recipient's +rights under this Agreement terminate, Recipient agrees to cease use +and distribution of the Program as soon as reasonably practicable. +However, Recipient's obligations under this Agreement and any licenses +granted by Recipient relating to the Program shall continue and survive. + +Everyone is permitted to copy and distribute copies of this Agreement, +but in order to avoid inconsistency the Agreement is copyrighted and +may only be modified in the following manner. The Agreement Steward +reserves the right to publish new versions (including revisions) of +this Agreement from time to time. No one other than the Agreement +Steward has the right to modify this Agreement. The Eclipse Foundation +is the initial Agreement Steward. The Eclipse Foundation may assign the +responsibility to serve as the Agreement Steward to a suitable separate +entity. Each new version of the Agreement will be given a distinguishing +version number. The Program (including Contributions) may always be +Distributed subject to the version of the Agreement under which it was +received. In addition, after a new version of the Agreement is published, +Contributor may elect to Distribute the Program (including its +Contributions) under the new version. + +Except as expressly stated in Sections 2(a) and 2(b) above, Recipient +receives no rights or licenses to the intellectual property of any +Contributor under this Agreement, whether expressly, by implication, +estoppel or otherwise. All rights in the Program not expressly granted +under this Agreement are reserved. Nothing in this Agreement is intended +to be enforceable by any entity that is not a Contributor or Recipient. +No third-party beneficiary rights are created under this Agreement. + +Exhibit A - Form of Secondary Licenses Notice + +"This Source Code may also be made available under the following +Secondary Licenses when the conditions for such availability set forth +in the Eclipse Public License, v. 2.0 are satisfied: {name license(s), +version(s), and exceptions or additional permissions here}." + + Simply including a copy of this Agreement, including this Exhibit A + is not sufficient to license the Source Code under Secondary Licenses. + + If it is not possible or desirable to put the notice in a particular + file, then You may include the notice in a location (such as a LICENSE + file in a relevant directory) where a recipient would be likely to + look for such a notice. + + You may add additional accurate notices of copyright ownership. \ No newline at end of file diff --git a/.tools/apache-maven-3.9.9/lib/plexus-cipher-2.0.jar b/.tools/apache-maven-3.9.9/lib/plexus-cipher-2.0.jar new file mode 100644 index 0000000..e73475d Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/plexus-cipher-2.0.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/plexus-cipher.license b/.tools/apache-maven-3.9.9/lib/plexus-cipher.license new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/.tools/apache-maven-3.9.9/lib/plexus-cipher.license @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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 + + http://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. diff --git a/.tools/apache-maven-3.9.9/lib/plexus-component-annotations-2.1.0.jar b/.tools/apache-maven-3.9.9/lib/plexus-component-annotations-2.1.0.jar new file mode 100644 index 0000000..e3793a2 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/plexus-component-annotations-2.1.0.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/plexus-component-annotations.license b/.tools/apache-maven-3.9.9/lib/plexus-component-annotations.license new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/.tools/apache-maven-3.9.9/lib/plexus-component-annotations.license @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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 + + http://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. diff --git a/.tools/apache-maven-3.9.9/lib/plexus-interpolation-1.27.jar b/.tools/apache-maven-3.9.9/lib/plexus-interpolation-1.27.jar new file mode 100644 index 0000000..494191b Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/plexus-interpolation-1.27.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/plexus-interpolation.license b/.tools/apache-maven-3.9.9/lib/plexus-interpolation.license new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/.tools/apache-maven-3.9.9/lib/plexus-interpolation.license @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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 + + http://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. diff --git a/.tools/apache-maven-3.9.9/lib/plexus-sec-dispatcher-2.0.jar b/.tools/apache-maven-3.9.9/lib/plexus-sec-dispatcher-2.0.jar new file mode 100644 index 0000000..623cc21 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/plexus-sec-dispatcher-2.0.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/plexus-sec-dispatcher.license b/.tools/apache-maven-3.9.9/lib/plexus-sec-dispatcher.license new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/.tools/apache-maven-3.9.9/lib/plexus-sec-dispatcher.license @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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 + + http://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. diff --git a/.tools/apache-maven-3.9.9/lib/plexus-utils-3.5.1.jar b/.tools/apache-maven-3.9.9/lib/plexus-utils-3.5.1.jar new file mode 100644 index 0000000..1873c52 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/plexus-utils-3.5.1.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/plexus-utils.license b/.tools/apache-maven-3.9.9/lib/plexus-utils.license new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/.tools/apache-maven-3.9.9/lib/plexus-utils.license @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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 + + http://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. diff --git a/.tools/apache-maven-3.9.9/lib/plexus-xml-3.0.1.jar b/.tools/apache-maven-3.9.9/lib/plexus-xml-3.0.1.jar new file mode 100644 index 0000000..25527a5 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/plexus-xml-3.0.1.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/plexus-xml.license b/.tools/apache-maven-3.9.9/lib/plexus-xml.license new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/.tools/apache-maven-3.9.9/lib/plexus-xml.license @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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 + + http://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. diff --git a/.tools/apache-maven-3.9.9/lib/slf4j-api-1.7.36.jar b/.tools/apache-maven-3.9.9/lib/slf4j-api-1.7.36.jar new file mode 100644 index 0000000..7d3ce68 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/slf4j-api-1.7.36.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/slf4j-api.license b/.tools/apache-maven-3.9.9/lib/slf4j-api.license new file mode 100644 index 0000000..1a3d053 --- /dev/null +++ b/.tools/apache-maven-3.9.9/lib/slf4j-api.license @@ -0,0 +1,24 @@ +Copyright (c) 2004-2022 QOS.ch Sarl (Switzerland) +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + + diff --git a/.tools/apache-maven-3.9.9/lib/wagon-file-3.5.3.jar b/.tools/apache-maven-3.9.9/lib/wagon-file-3.5.3.jar new file mode 100644 index 0000000..97222d4 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/wagon-file-3.5.3.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/wagon-http-3.5.3.jar b/.tools/apache-maven-3.9.9/lib/wagon-http-3.5.3.jar new file mode 100644 index 0000000..fd1f4a0 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/wagon-http-3.5.3.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/wagon-http-shared-3.5.3.jar b/.tools/apache-maven-3.9.9/lib/wagon-http-shared-3.5.3.jar new file mode 100644 index 0000000..d6f2d75 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/wagon-http-shared-3.5.3.jar differ diff --git a/.tools/apache-maven-3.9.9/lib/wagon-provider-api-3.5.3.jar b/.tools/apache-maven-3.9.9/lib/wagon-provider-api-3.5.3.jar new file mode 100644 index 0000000..ae6f033 Binary files /dev/null and b/.tools/apache-maven-3.9.9/lib/wagon-provider-api-3.5.3.jar differ diff --git a/FastStats/.gitignore b/FastStats/.gitignore new file mode 100644 index 0000000..dd34d15 --- /dev/null +++ b/FastStats/.gitignore @@ -0,0 +1,13 @@ +#IntelliJ +.idea/* +**.iml + +#Maven +target/* + +#Eclipse +**/.settings/* +**/.project +**/.classpath + +/target/ diff --git a/FastStats/README.md b/FastStats/README.md new file mode 100644 index 0000000..a699d7e --- /dev/null +++ b/FastStats/README.md @@ -0,0 +1,5 @@ +This subproject contains sources copied from the [FastStats Java SDK](https://github.com/faststats-dev/faststats-java). +The version of the SDK at the time of copying was 0.21.0. + +Some changes have been made to get rid of annotations library dependencies, and to support Java 8. +This was necessary to make the integration possible for Minecraft 1.8.8 servers. diff --git a/FastStats/pom.xml b/FastStats/pom.xml new file mode 100644 index 0000000..e84807f --- /dev/null +++ b/FastStats/pom.xml @@ -0,0 +1,74 @@ + + + invsee-plus-plus + com.janboerman.invsee + 0.31.11-SNAPSHOT + + 4.0.0 + + faststats + FastStats + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + org.junit.jupiter + junit-jupiter-engine + ${junit.version} + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 8 + + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven-jar-plugin.version} + + + + true + + + + + + + + + + papermc + https://repo.papermc.io/repository/maven-public/ + + + + + + io.papermc.paper + paper-api + 26.1.1.build.15-alpha + provided + + + + com.janboerman.invsee + utils + ${project.version} + provided + + + + \ No newline at end of file diff --git a/FastStats/src/main/java/com/janboerman/invsee/faststats/FastStats.java b/FastStats/src/main/java/com/janboerman/invsee/faststats/FastStats.java new file mode 100644 index 0000000..9af898f --- /dev/null +++ b/FastStats/src/main/java/com/janboerman/invsee/faststats/FastStats.java @@ -0,0 +1,18 @@ +package com.janboerman.invsee.faststats; + +public final class FastStats { + + /** API Token as presented in the 'project settings' on the FastStats website. */ + public static final String API_TOKEN = "3e3ed377fb507fb659ff4b33151e055e"; + + /** Which library are we using to talk to FastStats? */ + // We copied the sources from faststats-java: https://github.com/faststats-dev/faststats-java. + public static final String SDK_NAME = "faststats-java"; + /** And what version of the library are we using? */ + // At the time of copying, version 0.21.0 was the latest released version. + public static final String SDK_VERSION = "0.21.0"; + + private FastStats() { + } + +} diff --git a/FastStats/src/main/java/com/janboerman/invsee/faststats/Java8HttpClient.java b/FastStats/src/main/java/com/janboerman/invsee/faststats/Java8HttpClient.java new file mode 100644 index 0000000..07edbe6 --- /dev/null +++ b/FastStats/src/main/java/com/janboerman/invsee/faststats/Java8HttpClient.java @@ -0,0 +1,177 @@ +package com.janboerman.invsee.faststats; + +import java.io.*; +import java.net.HttpURLConnection; +import java.net.URI; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +public final class Java8HttpClient { + + private final int connectTimeoutMs; + + private Java8HttpClient( + Duration connectTimeout + ) { + this.connectTimeoutMs = (int)Objects.requireNonNull(connectTimeout).toMillis(); + } + + public Response send(Request request) throws IOException { + URL url = request.uri.toURL(); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + + connection.setRequestMethod(request.method); + connection.setConnectTimeout(connectTimeoutMs); + connection.setReadTimeout((int)request.timeout.toMillis()); + for (Map.Entry headerEntry : request.headers.entrySet()) { + connection.setRequestProperty(headerEntry.getKey(), headerEntry.getValue()); + } + + try { + connection.setDoOutput(true); + try (OutputStream outputStream = connection.getOutputStream()) { + byte[] input = request.body; + outputStream.write(input, 0, input.length); + } + + int statusCode = connection.getResponseCode(); + InputStream inputStream = (statusCode < HttpURLConnection.HTTP_BAD_REQUEST) + ? connection.getInputStream() + : connection.getErrorStream(); + + try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) { + StringBuilder response = new StringBuilder(); + String line; + while ((line = br.readLine()) != null) { + response.append(line.trim()); + } + return new Response(statusCode, response.toString()); + } + } finally { + connection.disconnect(); + } + } + + public static final class Response { + private final int statusCode; + private final String body; + + private Response(int statusCode, String body) { + this.statusCode = statusCode; + this.body = body; + } + + public int statusCode() { + return statusCode; + } + + public String body() { + return body; + } + } + + public static final class Request { + private final String method; + private final Map headers; + private final Duration timeout; + private final URI uri; + private final byte[] body; + + private Request( + String method, + Map headers, + Duration timeout, + URI uri, + byte[] body + ) { + this.method = method; + this.headers = headers; + this.timeout = timeout; + this.uri = uri; + this.body = body; + } + + public static Builder newBuilder() { + return new Builder(); + } + + public static final class Builder { + private String method = "GET"; + private Map headers = new HashMap<>(); + private Duration timeout = Duration.ofSeconds(30); + private URI uri; + private byte[] body = {}; + + public Builder method(String method) { + this.method = method; + return this; + } + + public Builder header(String key, String value) { + headers.put(key, value); + return this; + } + + public Builder timeout(Duration duration) { + this.timeout = timeout; + return this; + } + + public Builder uri(URI uri) { + this.uri = uri; + return this; + } + + public Builder body(byte[] body) { + this.body = body; + return this; + } + + public Builder POST(byte[] body) { + method("POST"); + body(body); + return this; + } + + public Builder PUT(byte[] body) { + method("PUT"); + body(body); + return this; + } + + public Request build() { + return new Request( + method, + Collections.unmodifiableMap(headers), + timeout, + uri, + body + ); + } + } + } + + public static Builder newBuilder() { + return new Builder(); + } + + public static final class Builder { + private Duration connectTimeout = Duration.ofSeconds(30); + + public Builder connectTimeout(Duration duration) { + this.connectTimeout = duration; + return this; + } + + public Java8HttpClient build() { + return new Java8HttpClient( + connectTimeout + ); + } + } +} diff --git a/FastStats/src/main/java/dev/faststats/bukkit/BukkitMetrics.java b/FastStats/src/main/java/dev/faststats/bukkit/BukkitMetrics.java new file mode 100644 index 0000000..ca75fc5 --- /dev/null +++ b/FastStats/src/main/java/dev/faststats/bukkit/BukkitMetrics.java @@ -0,0 +1,38 @@ +package dev.faststats.bukkit; + +import dev.faststats.core.Metrics; +import org.bukkit.plugin.IllegalPluginAccessException; +import org.bukkit.plugin.Plugin; + +/** + * Bukkit metrics implementation. + * + * @since 0.1.0 + */ +public interface BukkitMetrics extends Metrics { + /** + * Creates a new metrics factory for Bukkit. + * + * @return the metrics factory + * @since 0.1.0 + */ +// @Contract(pure = true) + static Factory factory() { + return new BukkitMetricsImpl.Factory(); + } + + /** + * Registers additional exception handlers on Paper-based implementations. + * + * @throws IllegalPluginAccessException if the plugin is not yet enabled + * @apiNote This method may only be called {@link Plugin#onEnable() onEnable()}. + * @since 0.14.0 + */ + @Override + void ready() throws IllegalPluginAccessException; + + interface Factory extends Metrics.Factory { + @Override + BukkitMetrics create(Plugin object) throws IllegalStateException; + } +} diff --git a/FastStats/src/main/java/dev/faststats/bukkit/BukkitMetricsImpl.java b/FastStats/src/main/java/dev/faststats/bukkit/BukkitMetricsImpl.java new file mode 100644 index 0000000..152b602 --- /dev/null +++ b/FastStats/src/main/java/dev/faststats/bukkit/BukkitMetricsImpl.java @@ -0,0 +1,132 @@ +package dev.faststats.bukkit; + +import com.google.gson.JsonObject; +import com.janboerman.invsee.utils.Compat; +import dev.faststats.core.SimpleMetrics; +import org.bukkit.Server; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.plugin.Plugin; + +import java.nio.file.Path; +import java.util.Optional; +import java.util.function.Supplier; +import java.util.logging.Level; + +final class BukkitMetricsImpl extends SimpleMetrics implements BukkitMetrics { + private final Plugin plugin; + + private final String pluginVersion; + private final String minecraftVersion; + private final String serverType; + + @SuppressWarnings({"deprecation", "Convert2MethodRef"}) + private BukkitMetricsImpl(final Factory factory, final Plugin plugin, final Path config) throws IllegalStateException { + super(factory, config); + + this.plugin = plugin; + final Server server = plugin.getServer(); + + this.pluginVersion = tryOrEmpty(() -> plugin.getPluginMeta().getVersion()) + .orElseGet(() -> plugin.getDescription().getVersion()); + this.minecraftVersion = Compat.optionalOr(tryOrEmpty(() -> server.getMinecraftVersion()), + () -> tryOrEmpty(() -> server.getBukkitVersion().split("-", 2)[0])) + .orElseGet(() -> server.getVersion().split("\\(MC: |\\)", 3)[1]); + this.serverType = server.getName(); + + startSubmitting(); + } + + Plugin plugin() { + return plugin; + } + + private boolean checkOnlineMode() { + final Server server = plugin.getServer(); + return Compat.optionalOr( + tryOrEmpty(() -> server.getServerConfig().isProxyOnlineMode()), + () -> tryOrEmpty(this::isProxyOnlineMode) + ).orElseGet(server::getOnlineMode); + } + + + @SuppressWarnings("removal") + private boolean isProxyOnlineMode() { + final Server server = plugin.getServer(); + final ConfigurationSection proxies = server.spigot().getPaperConfig().getConfigurationSection("proxies"); + if (proxies == null) return false; + + if (proxies.getBoolean("velocity.enabled") && proxies.getBoolean("velocity.online-mode")) return true; + + final ConfigurationSection settings = server.spigot().getSpigotConfig().getConfigurationSection("settings"); + if (settings == null) return false; + + return settings.getBoolean("bungeecord") && proxies.getBoolean("bungee-cord.online-mode"); + } + + @Override + protected void appendDefaultData(final JsonObject metrics) { + metrics.addProperty("minecraft_version", minecraftVersion); + metrics.addProperty("online_mode", checkOnlineMode()); + metrics.addProperty("player_count", getPlayerCount()); + metrics.addProperty("plugin_version", pluginVersion); + metrics.addProperty("server_type", serverType); + } + + private int getPlayerCount() { + try { + return plugin.getServer().getOnlinePlayers().size(); + } catch (final Throwable t) { + error("Failed to get player count", t); + return 0; + } + } + + @Override + protected void printError(final String message, /*@Nullable*/ final Throwable throwable) { + plugin.getLogger().log(Level.SEVERE, message, throwable); + } + + @Override + protected void printInfo(final String message) { + plugin.getLogger().info(message); + } + + @Override + protected void printWarning(final String message) { + plugin.getLogger().warning(message); + } + + @Override + public void ready() { + if (getErrorTracker().isPresent()) try { + Class.forName("com.destroystokyo.paper.event.server.ServerExceptionEvent"); + plugin.getServer().getPluginManager().registerEvents(new PaperEventListener(this), plugin); + } catch (final ClassNotFoundException ignored) { + } + } + + private Optional tryOrEmpty(final Supplier supplier) { + try { + return Optional.of(supplier.get()); + } catch (final NoSuchMethodError | Exception e) { + return Optional.empty(); + } + } + + static final class Factory extends SimpleMetrics.Factory implements BukkitMetrics.Factory { + @Override + public BukkitMetrics create(final Plugin plugin) throws IllegalStateException { + final Path dataFolder = getPluginsFolder(plugin).resolve("faststats"); + final Path config = dataFolder.resolve("config.properties"); + return new BukkitMetricsImpl(this, plugin, config); + } + + private static Path getPluginsFolder(final Plugin plugin) { + try { + return plugin.getServer().getPluginsFolder().toPath(); + } catch (final NoSuchMethodError e) { + return plugin.getDataFolder().getParentFile().toPath(); + } + } + } +} diff --git a/FastStats/src/main/java/dev/faststats/bukkit/PaperEventListener.java b/FastStats/src/main/java/dev/faststats/bukkit/PaperEventListener.java new file mode 100644 index 0000000..a6a9284 --- /dev/null +++ b/FastStats/src/main/java/dev/faststats/bukkit/PaperEventListener.java @@ -0,0 +1,25 @@ +package dev.faststats.bukkit; + +import com.destroystokyo.paper.event.server.ServerExceptionEvent; +import com.destroystokyo.paper.exception.ServerPluginException; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; + +final class PaperEventListener implements Listener { + + private final BukkitMetricsImpl metrics; + + PaperEventListener(BukkitMetricsImpl metrics) { + this.metrics = metrics; + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onServerException(final ServerExceptionEvent event) { + if (!(event.getException() instanceof ServerPluginException)) return; + ServerPluginException exception = (ServerPluginException) event.getException(); + if (!exception.getResponsiblePlugin().equals(metrics.plugin())) return; + final Throwable report = exception.getCause() != null ? exception.getCause() : exception; + metrics.getErrorTracker().ifPresent(tracker -> tracker.trackError(report, false)); + } +} diff --git a/FastStats/src/main/java/dev/faststats/core/ErrorHelper.java b/FastStats/src/main/java/dev/faststats/core/ErrorHelper.java new file mode 100644 index 0000000..99694f5 --- /dev/null +++ b/FastStats/src/main/java/dev/faststats/core/ErrorHelper.java @@ -0,0 +1,222 @@ +package dev.faststats.core; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; + +import java.util.*; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +final class ErrorHelper { + private static final int MESSAGE_LENGTH = Math.min(1000, Integer.getInteger("faststats.message-length", 500)); + private static final int STACK_TRACE_LENGTH = Math.min(500, Integer.getInteger("faststats.stack-trace-length", 300)); + private static final int STACK_TRACE_LIMIT = Math.min(50, Integer.getInteger("faststats.stack-trace-limit", 15)); + + public static JsonObject compile(final Throwable error, /*@Nullable*/ final List suppress, final boolean handled) { + final JsonObject report = new JsonObject(); + final String message = getAnonymizedMessage(error); + + final JsonArray stacktrace = new JsonArray(); + final String header = message != null + ? error.getClass().getName() + ": " + message + : error.getClass().getName(); + stacktrace.add(header); + + final StackTraceElement[] elements = error.getStackTrace(); + final List stack = collapseStackTrace(elements); + final ArrayList list = new ArrayList<>(stack); + if (suppress != null) list.removeAll(suppress); + final int traces = Math.min(list.size(), STACK_TRACE_LIMIT); + + populateTraces(traces, list, elements, stacktrace); + appendCauseChain(error.getCause(), stack, suppress, stacktrace); + + report.addProperty("error", error.getClass().getName()); + if (message != null) report.addProperty("message", message); + + report.add("stack", stacktrace); + report.addProperty("handled", handled); + + return report; + } + + private static void appendCauseChain(/*@Nullable*/ Throwable cause, final List parentStack, + /*@Nullable*/ final List suppress, final JsonArray stacktrace) { + final ArrayList toSuppress = new ArrayList<>(parentStack); + if (suppress != null) toSuppress.addAll(suppress); + final Set visited = Collections.newSetFromMap(new IdentityHashMap<>()); + while (cause != null && visited.add(cause)) { + final String causeMessage = getAnonymizedMessage(cause); + final String header = causeMessage != null + ? "Caused by: " + cause.getClass().getName() + ": " + causeMessage + : "Caused by: " + cause.getClass().getName(); + stacktrace.add(header); + + final StackTraceElement[] causeElements = cause.getStackTrace(); + final List causeStack = collapseStackTrace(causeElements); + final ArrayList causeList = new ArrayList<>(causeStack); + causeList.removeAll(toSuppress); + final int causeTraces = Math.min(causeList.size(), STACK_TRACE_LIMIT); + populateTraces(causeTraces, causeList, causeElements, stacktrace); + + cause = cause.getCause(); + } + } + + private static void populateTraces(final int traces, final List list, final StackTraceElement[] elements, final JsonArray stacktrace) { + for (int i = 0; i < traces; i++) { + final String string = list.get(i); + if (string.length() <= STACK_TRACE_LENGTH) stacktrace.add(" at " + string); + else stacktrace.add(" at " + string.substring(0, STACK_TRACE_LENGTH) + "..."); + } + if (traces > 0 && traces < list.size()) { + stacktrace.add(" ... " + (list.size() - traces) + " more"); + } else { + final int i = elements.length - list.size(); + if (i > 0) stacktrace.add(" ... " + i + " more"); + } + } + + private static List collapseStackTrace(final StackTraceElement[] trace) { + final List lines = Arrays.stream(trace) + .map(StackTraceElement::toString) + .collect(Collectors.toList()); + + return collapseRepeatingPattern(lines); + } + + private static List collapseRepeatingPattern(final List lines) { + final List deduplicated = collapseConsecutiveDuplicates(lines); + + final int n = deduplicated.size(); + + for (int cycleLen = 1; cycleLen <= n / 2; cycleLen++) { + boolean isPattern = true; + int repetitions = 0; + + for (int i = 0; i < n; i++) { + if (!deduplicated.get(i).equals(deduplicated.get(i % cycleLen))) { + isPattern = false; + break; + } + if (i > 0 && i % cycleLen == 0) repetitions++; + } + + if (isPattern && repetitions >= 2) { + return deduplicated.subList(0, cycleLen); + } + } + + return deduplicated; + } + + private static List collapseConsecutiveDuplicates(final List lines) { + if (lines.isEmpty()) return lines; + + final ArrayList result = new ArrayList(); + String previous = null; + + for (final String line : lines) { + if (line.equals(previous)) continue; + result.add(line); + previous = line; + } + + return result; + } + + public static boolean isSameLoader(final ClassLoader loader, final Throwable error) { + return isSameLoader(loader, error, Collections.newSetFromMap(new IdentityHashMap<>())); + } + + private static boolean isSameLoader(final ClassLoader loader, /*@Nullable*/ final Throwable error, final Set visited) { + if (error == null || !visited.add(error)) return false; + + final StackTraceElement[] stackTrace = error.getStackTrace(); + if (stackTrace == null || stackTrace.length == 0) + return isSameLoader(loader, error.getCause(), visited); + + final int firstNonLibraryIndex = findFirstNonLibraryFrameIndex(stackTrace); + if (firstNonLibraryIndex == -1) return isSameLoader(loader, error.getCause(), visited); + + final int framesToCheck = Math.min(5, stackTrace.length - firstNonLibraryIndex); + + for (int i = 0; i < framesToCheck; i++) { + final StackTraceElement frame = stackTrace[firstNonLibraryIndex + i]; + if (isLibraryClass(frame.getClassName())) continue; + if (!isFromLoader(frame, loader)) return isSameLoader(loader, error.getCause(), visited); + } + + return true; + } + + private static int findFirstNonLibraryFrameIndex(final StackTraceElement[] stackTrace) { + for (int i = 0; i < stackTrace.length; i++) { + if (!isLibraryClass(stackTrace[i].getClassName())) return i; + } + return -1; + } + + private static boolean isLibraryClass(final String className) { + return className.startsWith("java.") + || className.startsWith("javax.") + || className.startsWith("sun.") + || className.startsWith("com.sun.") + || className.startsWith("jdk."); + } + + private static boolean isFromLoader(final StackTraceElement frame, final ClassLoader loader) { + try { + final Class clazz = Class.forName(frame.getClassName(), false, loader); + return isSameClassLoader(clazz.getClassLoader(), loader); + } catch (final Throwable t) { + return false; + } + } + + private static boolean isSameClassLoader(final ClassLoader classLoader, final ClassLoader loader) { + if (classLoader == loader) return true; + ClassLoader current = classLoader; + while (current != null && current != loader) { + current = current.getParent(); + } + return loader == current; + } + + private static final Pattern IPV4_PATTERN = Pattern.compile( + "\\b(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\b"); + private static final Pattern IPV6_PATTERN = Pattern.compile( + "(?i)\\b([0-9a-f]{1,4}:){7}[0-9a-f]{1,4}\\b|" + // Full form + "(?i)\\b([0-9a-f]{1,4}:){1,7}:\\b|" + // Trailing :: + "(?i)\\b([0-9a-f]{1,4}:){1,6}:[0-9a-f]{1,4}\\b|" + // :: in middle (1 group after) + "(?i)\\b([0-9a-f]{1,4}:){1,5}(:[0-9a-f]{1,4}){1,2}\\b|" + // :: in middle (2 groups after) + "(?i)\\b([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,3}\\b|" + // :: in middle (3 groups after) + "(?i)\\b([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,4}\\b|" + // :: in middle (4 groups after) + "(?i)\\b([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,5}\\b|" + // :: in middle (5 groups after) + "(?i)\\b[0-9a-f]{1,4}:(:[0-9a-f]{1,4}){1,6}\\b|" + // :: in middle (6 groups after) + "(?i)\\b:(:[0-9a-f]{1,4}){1,7}\\b|" + // Leading :: + "(?i)\\b::([0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4}\\b|" + // :: at start + "(?i)\\b::\\b"); // Just :: + private static final Pattern USER_HOME_PATH_PATTERN = Pattern.compile( + "(/home/)[^/\\s]+" + // Linux: /home/username + "|(/Users/)[^/\\s]+" + // macOS: /Users/username + "|((?i)[A-Z]:\\\\Users\\\\)[^\\\\\\s]+"); // Windows: A-Z:\\Users\\username + + private static String anonymize(String message) { + message = IPV4_PATTERN.matcher(message).replaceAll("[IP hidden]"); + message = IPV6_PATTERN.matcher(message).replaceAll("[IP hidden]"); + message = USER_HOME_PATH_PATTERN.matcher(message).replaceAll("$1$2$3[username hidden]"); + final String username = System.getProperty("user.name"); + if (username != null) message = message.replace(username, "[username hidden]"); + return message; + } + + private static /*@Nullable*/ String getAnonymizedMessage(final Throwable error) { + final String message = error.getMessage(); + if (message == null) return null; + final String truncated = message.length() > MESSAGE_LENGTH + ? message.substring(0, MESSAGE_LENGTH) + "..." + : message; + return anonymize(truncated); + } +} diff --git a/FastStats/src/main/java/dev/faststats/core/ErrorTracker.java b/FastStats/src/main/java/dev/faststats/core/ErrorTracker.java new file mode 100644 index 0000000..516d3b9 --- /dev/null +++ b/FastStats/src/main/java/dev/faststats/core/ErrorTracker.java @@ -0,0 +1,240 @@ +package dev.faststats.core; + +import java.util.Optional; +import java.util.function.BiConsumer; +import java.util.regex.Pattern; + +/** + * An error tracker. + * + * @since 0.10.0 + */ +public interface ErrorTracker { + /** + * Create and attach a new context-aware error tracker. + *

+ * This tracker will automatically track errors that occur in the same class loader as the tracker itself. + *

+ * You can still manually track errors using {@code #trackError}. + * + * @return the error tracker + * @see #contextUnaware() + * @see #trackError(String, boolean) + * @see #trackError(Throwable, boolean) + * @since 0.10.0 + */ +// @Contract(value = " -> new") + static ErrorTracker contextAware() { + final SimpleErrorTracker tracker = new SimpleErrorTracker(); + tracker.attachErrorContext(ErrorTracker.class.getClassLoader()); + return tracker; + } + + /** + * Create a new context-unaware error tracker. + *

+ * This tracker will not automatically track any errors. + *

+ * You have to manually track errors using {@code #trackError}. + * + * @return the error tracker + * @see #contextAware() + * @see #trackError(String) + * @see #trackError(Throwable) + * @since 0.10.0 + */ +// @Contract(value = " -> new") + static ErrorTracker contextUnaware() { + return new SimpleErrorTracker(); + } + + /** + * Tracks a handled error. + * + * @param message the error message + * @see #trackError(Throwable) + * @see #trackError(String, boolean) + * @since 0.10.0 + */ +// @Contract(mutates = "this") + void trackError(String message); + + /** + * Tracks a handled error. + * + * @param error the error + * @see #trackError(Throwable, boolean) + * @since 0.10.0 + */ +// @Contract(mutates = "this") + void trackError(Throwable error); + + /** + * Tracks an error. + *

+ * A {@code handled=true} error is expected and properly handled. + * + * @param message the error message + * @param handled whether the error was handled + * @see #trackError(Throwable, boolean) + * @since 0.20.0 + */ +// @Contract(mutates = "this") + void trackError(String message, boolean handled); + + /** + * Tracks an error. + *

+ * A {@code handled=true} error is expected and properly handled. + * + * @param error the error + * @param handled whether the error was handled + * @since 0.20.0 + */ +// @Contract(mutates = "this") + void trackError(Throwable error, boolean handled); + + /** + * Adds an error type that will not be reported to FastStats. + *

+ * Matching is done exactly. If, for example {@link LinkageError} was ignored, + * {@link NoClassDefFoundError} would still be reported, even though it extends {@link LinkageError} + * + * @param type the error type + * @return the error tracker + * @since 0.21.0 + */ +// @Contract(value = "_ -> this", mutates = "this") + ErrorTracker ignoreErrorType(Class type); + + /** + * Adds a pattern that will be matched against all error messages. + *

+ * If an error's message matches the given pattern, it will not be reported to FastStats. + *

{@code
+     * // Exact match
+     * tracker.ignoreError(Pattern.compile("No space left on device"));
+     *
+     * // Regex match
+     * tracker.ignoreError(Pattern.compile("No serializer for: class .*"));
+     * }
+ * + * @param pattern the regex pattern to match against error messages + * @return the error tracker + * @since 0.21.0 + */ +// @Contract(value = "_ -> this", mutates = "this") + ErrorTracker ignoreError(Pattern pattern); + + /** + * Adds a pattern that will be matched against all error messages. + *

+ * If an error's message matches the given pattern, it will not be reported to FastStats. + * + * @param pattern the regex pattern string to match against error messages + * @return the error tracker + * @see #ignoreError(Pattern) + * @since 0.21.0 + */ +// @Contract(value = "_ -> this", mutates = "this") + default ErrorTracker ignoreError(/*@RegExp*/ final String pattern) { + return ignoreError(Pattern.compile(pattern)); + } + + /** + * Adds an error type combined with a message pattern that will not be reported to FastStats. + *

+ * An error is ignored only if its class matches the given type exactly and its message matches the given pattern. + *

{@code
+     * tracker.ignoreError(IOException.class, Pattern.compile("No space left on device"));
+     * }
+ * + * @param type the error type + * @param pattern the regex pattern to match against error messages + * @return the error tracker + * @since 0.21.0 + */ +// @Contract(value = "_, _ -> this", mutates = "this") + ErrorTracker ignoreError(Class type, Pattern pattern); + + /** + * Adds an error type combined with a message pattern that will not be reported to FastStats. + *

+ * An error is ignored only if its class matches the given type exactly and its message matches the given pattern. + * + * @param type the error type + * @param pattern the regex pattern string to match against error messages + * @return the error tracker + * @see #ignoreError(Class, Pattern) + * @since 0.21.0 + */ +// @Contract(value = "_, _ -> this", mutates = "this") + default ErrorTracker ignoreError(final Class type, /*@RegExp*/ final String pattern) { + return ignoreError(type, Pattern.compile(pattern)); + } + + /** + * Attaches an error context to the tracker. + *

+ * If the class loader is {@code null}, the tracker will track all errors. + * + * @param loader the class loader + * @throws IllegalStateException if the error context is already attached + * @since 0.10.0 + */ + void attachErrorContext(/*@Nullable*/ ClassLoader loader) throws IllegalStateException; + + /** + * Detaches the error context from the tracker. + *

+ * This restores the original uncaught exception handler that was in place before + * {@link #attachErrorContext(ClassLoader)} was called. + *

+ * This should be called during shutdown to prevent {@link BootstrapMethodError} + * when the provider's JAR file is closed. + * + * @since 0.13.0 + */ + void detachErrorContext(); + + /** + * Returns whether an error context is attached. + * + * @return whether an error context is attached + * @since 0.13.0 + */ + boolean isContextAttached(); + + /** + * Sets the error event handler which will be called when an error is tracked automatically. + *

+ * The purpose of this handler is to allow custom error handling like logging. + * + * @param errorEvent the error event handler + * @since 0.11.0 + */ +// @Contract(mutates = "this") + void setContextErrorHandler(/*@Nullable*/ BiConsumer errorEvent); + + /** + * Returns the error event handler which will be called when an error is tracked automatically. + * + * @return the error event handler + * @since 0.11.0 + */ +// @Contract(pure = true) + Optional> getContextErrorHandler(); + + /** + * Checks if the error occurred in the same class loader as the provided loader. + * + * @param loader the class loader + * @param error the error + * @return whether the error occurred in the same class loader + * @since 0.14.0 + */ +// @Contract(pure = true) + static boolean isSameLoader(final ClassLoader loader, final Throwable error) { + return ErrorHelper.isSameLoader(loader, error); + } +} diff --git a/FastStats/src/main/java/dev/faststats/core/Metrics.java b/FastStats/src/main/java/dev/faststats/core/Metrics.java new file mode 100644 index 0000000..6026c7c --- /dev/null +++ b/FastStats/src/main/java/dev/faststats/core/Metrics.java @@ -0,0 +1,218 @@ +package dev.faststats.core; + +import dev.faststats.core.data.Metric; + +import java.net.URI; +import java.util.Optional; +import java.util.UUID; + +/** + * Metrics interface. + * + * @since 0.1.0 + */ +public interface Metrics { + /** + * Get the token used to authenticate with the metrics server and identify the project. + * + * @return the metrics token + * @since 0.1.0 + */ + @Token +// @Contract(pure = true) + String getToken(); + + /** + * Get the error tracker for this metrics instance. + * + * @return the error tracker + * @since 0.10.0 + */ +// @Contract(pure = true) + Optional getErrorTracker(); + + /** + * Get the metrics configuration. + * + * @return the metrics configuration + * @since 0.1.0 + */ +// @Contract(pure = true) + Config getConfig(); + + /** + * Performs additional post-startup tasks. + *

+ * This method may only be called when the application startup is complete. + *

+ * No-op in most implementations. + * + * @since 0.14.0 + */ + default void ready() { + } + + /** + * Safely shuts down the metrics submission. + *

+ * This method should be called when the application is shutting down. + * + * @since 0.1.0 + */ +// @Contract(mutates = "this") + void shutdown(); + + /** + * A metrics factory. + * + * @since 0.1.0 + */ + interface Factory> { + /** + * Adds a metric to the metrics submission. + *

+ * If {@link Config#additionalMetrics()} is disabled, the metric will not be submitted. + * + * @param metric the metric to add + * @return the metrics factory + * @throws IllegalArgumentException if the metric is already added + * @since 0.16.0 + */ +// @Contract(mutates = "this") + F addMetric(Metric metric) throws IllegalArgumentException; + + /** + * Sets the flush callback for this metrics instance. + *

+ * This callback will be invoked when the metrics have been submitted to, and accepted by, the metrics server. + * + * @param flush the flush callback + * @return the metrics factory + * @since 0.15.0 + */ +// @Contract(mutates = "this") + F onFlush(Runnable flush); + + /** + * Sets the error tracker for this metrics instance. + *

+ * If {@link Config#errorTracking()} is disabled, no errors will be submitted. + * + * @param tracker the error tracker + * @return the metrics factory + * @since 0.10.0 + */ +// @Contract(mutates = "this") + F errorTracker(ErrorTracker tracker); + + /** + * Enables or disabled debug mode for this metrics instance. + *

+ * If {@link Config#debug()} is enabled, debug logging will be enabled for all metrics instances, + * including this one, regardless of this setting. + *

+ * This is only meant for development and testing and should not be enabled in production. + * + * @param enabled whether debug mode is enabled + * @return the metrics factory + * @since 0.1.0 + */ +// @Contract(mutates = "this") + F debug(boolean enabled); + + /** + * Sets the token used to authenticate with the metrics server and identify the project. + *

+ * This token can be found in the settings of your project under "Your API Token". + * + * @param token the metrics token + * @return the metrics factory + * @throws IllegalArgumentException if the token does not match the {@link Token#PATTERN} + * @since 0.1.0 + */ +// @Contract(mutates = "this") + F token(@Token String token) throws IllegalArgumentException; + + /** + * Sets the metrics server URL. + *

+ * This is only required for self-hosted metrics servers. + * + * @param url the metrics server URL + * @return the metrics factory + * @since 0.1.0 + */ +// @Contract(mutates = "this") + F url(URI url); + + /** + * Creates a new metrics instance. + *

+ * Metrics submission will start automatically. + * + * @param object a required object as defined by the implementation + * @return the metrics instance + * @throws IllegalStateException if the token is not specified + * @see #token(String) + * @since 0.1.0 + */ +// @Async.Schedule +// @Contract(value = "_ -> new", mutates = "io") + Metrics create(T object) throws IllegalStateException; + } + + /** + * A representation of the metrics configuration. + * + * @since 0.1.0 + */ + interface Config { + /** + * The server id. + * + * @return the server id + * @since 0.1.0 + */ +// @Contract(pure = true) + UUID serverId(); + + /** + * Whether metrics submission is enabled. + *

+ * Bypassing this setting may get your project banned from FastStats.
+ * Users have to be able to opt out from metrics submission. + * + * @return {@code true} if metrics submission is enabled, {@code false} otherwise + * @since 0.1.0 + */ +// @Contract(pure = true) + boolean enabled(); + + /** + * Whether error tracking is enabled across all metrics instances. + * + * @return {@code true} if error tracking is enabled, {@code false} otherwise + * @since 0.11.0 + */ +// @Contract(pure = true) + boolean errorTracking(); + + /** + * Whether additional metrics are enabled across all metrics instances. + * + * @return {@code true} if additional metrics are enabled, {@code false} otherwise + * @since 0.11.0 + */ +// @Contract(pure = true) + boolean additionalMetrics(); + + /** + * Whether debug logging is enabled across all metrics instances. + * + * @return {@code true} if debug logging is enabled, {@code false} otherwise + * @since 0.1.0 + */ +// @Contract(pure = true) + boolean debug(); + } +} diff --git a/FastStats/src/main/java/dev/faststats/core/MurmurHash3.java b/FastStats/src/main/java/dev/faststats/core/MurmurHash3.java new file mode 100644 index 0000000..fc8a7ba --- /dev/null +++ b/FastStats/src/main/java/dev/faststats/core/MurmurHash3.java @@ -0,0 +1,187 @@ +package dev.faststats.core; + +import com.google.gson.JsonObject; + +import java.nio.charset.StandardCharsets; + +/** + * Implementation of the MurmurHash3 128-bit hash algorithm. + *

+ * MurmurHash is a non-cryptographic hash function suitable for general hash-based lookup. + * It provides excellent distribution and performance while minimizing collisions. + *

+ *

+ * This implementation follows the MurmurHash3_x64_128 variant as described at: + * https://en.wikipedia.org/wiki/MurmurHash + *

+ *

+ * Original algorithm by Austin Appleby. The name comes from the two elementary operations + * it uses: multiply (MU) and rotate (R). + *

+ */ +final class MurmurHash3 { + public static String hash(final JsonObject object) { + final long[] hash = MurmurHash3.hash(object.toString()); + return Long.toHexString(hash[0]) + Long.toHexString(hash[1]); + } + + /** + * Computes the 128-bit MurmurHash3 hash of the input string. + *

+ * The string is encoded to UTF-8 bytes before hashing. The result is returned + * as an array of two long values (64 bits each), combined they form a 128-bit hash. + *

+ * + * @param data the input string to hash + * @return a 2-element array containing the lower 64 bits at index 0 and upper 64 bits at index 1 + * @see MurmurHash on Wikipedia + */ +// @Contract(value = "_ -> new", pure = true) + private static long[] hash(final String data) { + final byte[] bytes = data.getBytes(StandardCharsets.UTF_8); + long h1 = 0L; + long h2 = 0L; + final long c1 = 0x87c37b91114253d5L; + final long c2 = 0x4cf5ad432745937fL; + final int length = bytes.length; + final int blocks = length / 16; + + // Process 128-bit blocks + for (int i = 0; i < blocks; i++) { + int k1 = getInt(bytes, i * 16); + int k2 = getInt(bytes, i * 16 + 4); + final int k3 = getInt(bytes, i * 16 + 8); + final int k4 = getInt(bytes, i * 16 + 12); + + k1 *= (int) c1; + k1 = Integer.rotateLeft(k1, 31); + k1 *= (int) c2; + h1 ^= k1; + + h1 = Long.rotateLeft(h1, 27); + h1 += h2; + h1 = h1 * 5 + 0x52dce729; + + k2 *= (int) c2; + k2 = Integer.rotateLeft(k2, 33); + k2 *= (int) c1; + h2 ^= k2; + + h2 = Long.rotateLeft(h2, 31); + h2 += h1; + h2 = h2 * 5 + 0x38495ab5; + } + + // Tail + int k1 = 0; + int k2 = 0; + int k3 = 0; + int k4 = 0; + final int tail = blocks * 16; + + switch (length & 15) { + case 15: + k4 ^= (bytes[tail + 14] & 0xff) << 16; + case 14: + k4 ^= (bytes[tail + 13] & 0xff) << 8; + case 13: + k4 ^= (bytes[tail + 12] & 0xff); + k4 *= (int) c2; + k4 = Integer.rotateLeft(k4, 33); + k4 *= (int) c1; + h2 ^= k4; + case 12: + k3 ^= (bytes[tail + 11] & 0xff) << 24; + case 11: + k3 ^= (bytes[tail + 10] & 0xff) << 16; + case 10: + k3 ^= (bytes[tail + 9] & 0xff) << 8; + case 9: + k3 ^= (bytes[tail + 8] & 0xff); + k3 *= (int) c1; + k3 = Integer.rotateLeft(k3, 31); + k3 *= (int) c2; + h1 ^= k3; + case 8: + k2 ^= (bytes[tail + 7] & 0xff) << 24; + case 7: + k2 ^= (bytes[tail + 6] & 0xff) << 16; + case 6: + k2 ^= (bytes[tail + 5] & 0xff) << 8; + case 5: + k2 ^= (bytes[tail + 4] & 0xff); + k2 *= (int) c2; + k2 = Integer.rotateLeft(k2, 33); + k2 *= (int) c1; + h2 ^= k2; + case 4: + k1 ^= (bytes[tail + 3] & 0xff) << 24; + case 3: + k1 ^= (bytes[tail + 2] & 0xff) << 16; + case 2: + k1 ^= (bytes[tail + 1] & 0xff) << 8; + case 1: + k1 ^= (bytes[tail] & 0xff); + k1 *= (int) c1; + k1 = Integer.rotateLeft(k1, 31); + k1 *= (int) c2; + h1 ^= k1; + } + + // Finalization + h1 ^= length; + h2 ^= length; + + h1 += h2; + h2 += h1; + + h1 = fmix64(h1); + h2 = fmix64(h2); + + h1 += h2; + h2 += h1; + + return new long[]{h1, h2}; + } + + /** + * Finalization mix function to avalanche the bits in the hash. + *

+ * This function improves the distribution of the hash by XORing and multiplying + * with carefully chosen constants, ensuring that similar inputs produce very + * different outputs (avalanche effect). + *

+ * + * @param k the 64-bit value to mix + * @return the mixed 64-bit value + * @see MurmurHash Algorithm on Wikipedia + */ +// @Contract(pure = true) + private static long fmix64(long k) { + k ^= k >>> 33; + k *= 0xff51afd7ed558ccdL; + k ^= k >>> 33; + k *= 0xc4ceb9fe1a85ec53L; + k ^= k >>> 33; + return k; + } + + /** + * Reads a 32-bit little-endian integer from the byte array at the specified offset. + *

+ * This helper method extracts four consecutive bytes and combines them into a + * single integer using little-endian byte order. + *

+ * + * @param bytes the byte array to read from + * @param offset the starting index in the byte array (must have at least 4 bytes from offset) + * @return the 32-bit integer value read in little-endian order + */ +// @Contract(pure = true) + private static int getInt(final byte[] bytes, final int offset) { + return (bytes[offset] & 0xff) | + ((bytes[offset + 1] & 0xff) << 8) | + ((bytes[offset + 2] & 0xff) << 16) | + ((bytes[offset + 3] & 0xff) << 24); + } +} diff --git a/FastStats/src/main/java/dev/faststats/core/SimpleErrorTracker.java b/FastStats/src/main/java/dev/faststats/core/SimpleErrorTracker.java new file mode 100644 index 0000000..d1ca1c4 --- /dev/null +++ b/FastStats/src/main/java/dev/faststats/core/SimpleErrorTracker.java @@ -0,0 +1,164 @@ +package dev.faststats.core; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; + +import java.lang.Thread.UncaughtExceptionHandler; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArraySet; +import java.util.function.BiConsumer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +final class SimpleErrorTracker implements ErrorTracker { + private final Map collected = new ConcurrentHashMap<>(); + private final Map reports = new ConcurrentHashMap<>(); + + private final Map, Set> ignoredTypedPatterns = new ConcurrentHashMap<>(); + private final Set> ignoredTypes = new CopyOnWriteArraySet<>(); + private final Set ignoredPatterns = new CopyOnWriteArraySet<>(); + + private volatile /*@Nullable*/ BiConsumer errorEvent = null; + private volatile /*@Nullable*/ UncaughtExceptionHandler originalHandler = null; + + @Override + public void trackError(final String message) { + trackError(message, true); + } + + @Override + public void trackError(final Throwable error) { + trackError(error, true); + } + + @Override + public void trackError(final String message, final boolean handled) { + trackError(new RuntimeException(message), handled); + } + + @Override + public void trackError(final Throwable error, final boolean handled) { + try { + if (isIgnored(error, Collections.newSetFromMap(new IdentityHashMap<>()))) return; + final JsonObject compiled = ErrorHelper.compile(error, null, handled); + final String hashed = MurmurHash3.hash(compiled); + if (collected.compute(hashed, (k, v) -> { + return v == null ? 1 : v + 1; + }) > 1) return; + reports.put(hashed, compiled); + } catch (final NoClassDefFoundError ignored) { + } + } + + private boolean isIgnored(/*@Nullable*/ final Throwable error, final Set visited) { + if (error == null || !visited.add(error)) return false; + + if (ignoredTypes.contains(error.getClass())) return true; + + final String message = error.getMessage() != null ? error.getMessage() : ""; + if (ignoredPatterns.stream().map(pattern -> pattern.matcher(message)).anyMatch(Matcher::find)) return true; + + final Set patterns = ignoredTypedPatterns.get(error.getClass()); + if (patterns != null && patterns.stream().map(pattern -> pattern.matcher(message)).anyMatch(Matcher::find)) + return true; + + return isIgnored(error.getCause(), visited); + } + + @Override + public ErrorTracker ignoreErrorType(final Class type) { + ignoredTypes.add(type); + return this; + } + + @Override + public ErrorTracker ignoreError(final Pattern pattern) { + ignoredPatterns.add(pattern); + return this; + } + + @Override + public ErrorTracker ignoreError(final Class type, final Pattern pattern) { + ignoredTypedPatterns.computeIfAbsent(type, k -> new CopyOnWriteArraySet<>()).add(pattern); + return this; + } + + public JsonArray getData(final String buildId) { + final JsonArray report = new JsonArray(reports.size()); + + reports.forEach((hash, object) -> { + final JsonObject copy = object.deepCopy(); + copy.addProperty("hash", hash); + copy.addProperty("buildId", buildId); + final Integer count = collected.getOrDefault(hash, 1); + if (count > 1) copy.addProperty("count", count); + report.add(copy); + }); + + collected.forEach((hash, count) -> { + if (count <= 0 || reports.containsKey(hash)) return; + final JsonObject entry = new JsonObject(); + + entry.addProperty("hash", hash); + if (count > 1) entry.addProperty("count", count); + + report.add(entry); + }); + + return report; + } + + public void clear() { + collected.replaceAll((k, v) -> 0); + reports.clear(); + } + + public boolean needsFlushing() { + if (!reports.isEmpty()) return true; + for (final Integer value : collected.values()) { + if (value > 0) return true; + } + return false; + } + + @Override + public synchronized void attachErrorContext(/*@Nullable*/ final ClassLoader loader) throws IllegalStateException { + if (originalHandler != null) throw new IllegalStateException("Error context already attached"); + originalHandler = Thread.getDefaultUncaughtExceptionHandler(); + Thread.setDefaultUncaughtExceptionHandler((thread, error) -> { + final Thread.UncaughtExceptionHandler handler = originalHandler; + if (handler != null) handler.uncaughtException(thread, error); + try { + if (loader != null && !ErrorTracker.isSameLoader(loader, error)) return; + final BiConsumer event = errorEvent; + if (event != null) event.accept(loader, error); + trackError(error, false); + } catch (final Throwable t) { + trackError(t, false); + } + }); + } + + @Override + public synchronized void detachErrorContext() { + if (originalHandler == null) return; + Thread.setDefaultUncaughtExceptionHandler(originalHandler); + originalHandler = null; + } + + @Override + public synchronized boolean isContextAttached() { + return originalHandler != null; + } + + @Override + public synchronized void setContextErrorHandler(/*@Nullable*/ final BiConsumer errorEvent) { + this.errorEvent = errorEvent; + } + + @Override + public synchronized Optional> getContextErrorHandler() { + return Optional.ofNullable(errorEvent); + } +} diff --git a/FastStats/src/main/java/dev/faststats/core/SimpleMetrics.java b/FastStats/src/main/java/dev/faststats/core/SimpleMetrics.java new file mode 100644 index 0000000..cee5e08 --- /dev/null +++ b/FastStats/src/main/java/dev/faststats/core/SimpleMetrics.java @@ -0,0 +1,509 @@ +package dev.faststats.core; + +import com.google.gson.JsonObject; +import com.janboerman.invsee.faststats.FastStats; +import com.janboerman.invsee.faststats.Java8HttpClient; +import com.janboerman.invsee.utils.Compat; +import dev.faststats.core.data.Metric; + +import java.io.*; +import java.net.ConnectException; +import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.Duration; +import java.util.*; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.BiPredicate; +import java.util.zip.GZIPOutputStream; + +import static java.nio.charset.StandardCharsets.UTF_8; + +public abstract class SimpleMetrics implements Metrics { + private final Java8HttpClient httpClient = Java8HttpClient.newBuilder() + .connectTimeout(Duration.ofSeconds(3)) + .build(); + + private /*@Nullable*/ ScheduledExecutorService executor = null; + + private final Set> metrics; + private final Config config; + private final @Token String token; + private final /*@Nullable*/ ErrorTracker tracker; + private final /*@Nullable*/ Runnable flush; + private final URI url; + private final boolean debug; + + private final String SDK_NAME; + private final String SDK_VERSION; + private final String BUILD_ID; + + { + final Properties properties = new Properties(); + try (final InputStream stream = getClass().getResourceAsStream("/META-INF/faststats.properties")) { + if (stream != null) properties.load(stream); + } catch (final IOException ignored) { + } + this.SDK_NAME = properties.getProperty("name", FastStats.SDK_NAME); + this.SDK_VERSION = properties.getProperty("version", FastStats.SDK_VERSION); + this.BUILD_ID = properties.getProperty("build-id", "unknown"); + } + +// @Contract(mutates = "io") + @SuppressWarnings("PatternValidation") + protected SimpleMetrics(final Factory factory, final Config config) throws IllegalStateException { + if (factory.token == null) throw new IllegalStateException("Token must be specified"); + + this.config = config; + this.metrics = config.additionalMetrics ? Compat.setCopy(factory.metrics) : Compat.emptySet(); + this.debug = factory.debug || Boolean.getBoolean("faststats.debug") || config.debug(); + this.token = factory.token; + this.tracker = config.errorTracking ? factory.tracker : null; + this.flush = factory.flush; + this.url = factory.url; + } + +// @Contract(mutates = "io") + protected SimpleMetrics(final Factory factory, final Path config) throws IllegalStateException { + this(factory, Config.read(config)); + } + +// @VisibleForTesting + protected SimpleMetrics( + final Config config, + final Set> metrics, + @Token final String token, + /*@Nullable*/ final ErrorTracker tracker, + /*@Nullable*/ final Runnable flush, + final URI url, + final boolean debug + ) { + if (!token.matches(Token.PATTERN)) { + throw new IllegalArgumentException("Invalid token '" + token + "', must match '" + Token.PATTERN + "'"); + } + + this.metrics = config.additionalMetrics ? Compat.setCopy(metrics) : Compat.emptySet(); + this.config = config; + this.debug = debug; + this.token = token; + this.tracker = tracker; + this.flush = flush; + this.url = url; + } + + protected String getOnboardingMessage() { + return "This plugin uses FastStats to collect anonymous usage statistics.\n" + + "No personal or identifying information is ever collected.\n" + + "To opt out, set 'enabled=false' in the metrics configuration file.\n" + + "Learn more at: https://faststats.dev/info\n" + + "\n" + + "Since this is your first start with FastStats, metrics submission will not start\n" + + "until you restart the server to allow you to opt out if you prefer."; + } + + protected long getInitialDelay() { + return TimeUnit.SECONDS.toMillis(Long.getLong("faststats.initial-delay", 30)); + } + + protected long getPeriod() { + return TimeUnit.MINUTES.toMillis(30); + } + +// @Async.Schedule +// @MustBeInvokedByOverriders + protected void startSubmitting() { + startSubmitting(getInitialDelay(), getPeriod(), TimeUnit.MILLISECONDS); + } + + private void startSubmitting(final long initialDelay, final long period, final TimeUnit unit) { + if (Boolean.getBoolean("faststats.first-run")) { + info("Skipping metrics submission due to first-run flag"); + return; + } + + if (config.firstRun) { + + int separatorLength = 0; + final String[] split = getOnboardingMessage().split("\n"); + for (final String s : split) if (s.length() > separatorLength) separatorLength = s.length(); + + String separator = Compat.stringRepeat("-", separatorLength); + printInfo(separator); + for (final String s : split) printInfo(s); + printInfo(separator); + + System.setProperty("faststats.first-run", "true"); + if (!config.externallyManaged()) return; + } + + final boolean enabled = Boolean.parseBoolean(System.getProperty("faststats.enabled", "true")); + + if (!config.enabled() || !enabled) { + warn("Metrics disabled, not starting submission"); + return; + } + + if (isSubmitting()) { + warn("Metrics already submitting, not starting again"); + return; + } + + this.executor = Executors.newSingleThreadScheduledExecutor(runnable -> { + final Thread thread = new Thread(runnable, "metrics-submitter"); + thread.setDaemon(true); + return thread; + }); + + info("Starting metrics submission"); + executor.scheduleAtFixedRate(this::submit, Math.max(0, initialDelay), Math.max(1000, period), unit); + } + + protected boolean isSubmitting() { + return executor != null && !executor.isShutdown(); + } + + public boolean submit() { + try { + return submitNow(); + } catch (final Throwable t) { + error("Failed to submit metrics", t); + return false; + } + } + + private boolean submitNow() throws IOException { + final String data = createData().toString(); + final byte[] bytes = data.getBytes(UTF_8); + + info("Uncompressed data: " + data); + + try (final ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(); + final GZIPOutputStream output = new GZIPOutputStream(byteOutput)) { + + output.write(bytes); + output.finish(); + + final byte[] compressed = byteOutput.toByteArray(); + info("Compressed size: " + compressed.length + " bytes"); + + final Java8HttpClient.Request request = Java8HttpClient.Request.newBuilder() + .POST(compressed) + .header("Content-Encoding", "gzip") + .header("Content-Type", "application/octet-stream") + .header("Authorization", "Bearer " + getToken()) + .header("User-Agent", "FastStats Metrics " + SDK_NAME + "/" + SDK_VERSION) + .timeout(Duration.ofSeconds(3)) + .uri(url) + .build(); + + info("Sending metrics to: " + url); + try { + final Java8HttpClient.Response response = httpClient.send(request); + final int statusCode = response.statusCode(); + final String body = response.body(); + + if (statusCode >= 200 && statusCode < 300) { + info("Metrics submitted with status code: " + statusCode + " (" + body + ")"); + getErrorTracker().map(SimpleErrorTracker.class::cast).ifPresent(SimpleErrorTracker::clear); + if (flush != null) flush.run(); + return true; + } else if (statusCode >= 300 && statusCode < 400) { + warn("Received redirect response from metrics server: " + statusCode + " (" + body + ")"); + } else if (statusCode >= 400 && statusCode < 500) { + error("Submitted invalid request to metrics server: " + statusCode + " (" + body + ")", null); + } else if (statusCode >= 500 && statusCode < 600) { + error("Received server error response from metrics server: " + statusCode + " (" + body + ")", null); + } else { + warn("Received unexpected response from metrics server: " + statusCode + " (" + body + ")"); + } + } catch (final ConnectException t) { + error("Failed to connect to metrics server: " + url, null); + } catch (final IOException t) { + error("Metrics submission timed out after 3 seconds: " + url, null); + } catch (final Exception e) { + error("Failed to submit metrics", e); + } + return false; + } + } + + private final String javaVendor = System.getProperty("java.vendor"); + private final String javaVersion = System.getProperty("java.version"); + private final String osArch = System.getProperty("os.arch"); + private final String osName = System.getProperty("os.name"); + private final String osVersion = System.getProperty("os.version"); + private final int coreCount = Runtime.getRuntime().availableProcessors(); + + protected JsonObject createData() { + final JsonObject data = new JsonObject(); + final JsonObject metrics = new JsonObject(); + + metrics.addProperty("core_count", coreCount); + metrics.addProperty("java_vendor", javaVendor); + metrics.addProperty("java_version", javaVersion); + metrics.addProperty("os_arch", osArch); + metrics.addProperty("os_name", osName); + metrics.addProperty("os_version", osVersion); + + try { + appendDefaultData(metrics); + } catch (final Throwable t) { + error("Failed to append default data", t); + getErrorTracker().ifPresent(tracker -> tracker.trackError(t)); + } + + this.metrics.forEach(metric -> { + try { + metric.getData().ifPresent(element -> metrics.add(metric.getId(), element)); + } catch (final Throwable t) { + error("Failed to build metric data: " + metric.getId(), t); + getErrorTracker().ifPresent(tracker -> tracker.trackError(t)); + } + }); + + data.addProperty("identifier", config.serverId().toString()); + data.add("data", metrics); + + getErrorTracker().map(SimpleErrorTracker.class::cast) + .map(tracker -> tracker.getData(BUILD_ID)) + .filter(errors -> !errors.isEmpty()) + .ifPresent(errors -> data.add("errors", errors)); + return data; + } + + @Override + public @Token String getToken() { + return token; + } + + @Override + public Optional getErrorTracker() { + return Optional.ofNullable(tracker); + } + + @Override + public Config getConfig() { + return config; + } + +// @Contract(mutates = "param1") + protected abstract void appendDefaultData(JsonObject metrics); + + protected void error(final String message, /*@Nullable*/ final Throwable throwable) { + if (debug) printError("[" + getClass().getName() + "]: " + message, throwable); + } + + protected void warn(final String message) { + if (debug) printWarning("[" + getClass().getName() + "]: " + message); + } + + protected void info(final String message) { + if (debug) printInfo("[" + getClass().getName() + "]: " + message); + } + + protected abstract void printError(String message, /*(@Nullable*/ Throwable throwable); + + protected abstract void printInfo(String message); + + protected abstract void printWarning(String message); + + @Override + public void shutdown() { + getErrorTracker().ifPresent(ErrorTracker::detachErrorContext); + if (executor != null) try { + info("Shutting down metrics submission"); + executor.shutdown(); + getErrorTracker().map(SimpleErrorTracker.class::cast) + .filter(SimpleErrorTracker::needsFlushing) + .ifPresent(ignored -> submit()); + } catch (final Throwable t) { + error("Failed to submit metrics on shutdown", t); + } finally { + executor = null; + } + } + + public abstract static class Factory> implements Metrics.Factory { + private final Set> metrics = new HashSet<>(0); + private URI url = URI.create("https://metrics.faststats.dev/v1/collect"); + private /*@Nullable*/ ErrorTracker tracker; + private /*@Nullable*/ Runnable flush; + private /*@Nullable*/ String token; + private boolean debug = false; + + @Override + @SuppressWarnings("unchecked") + public F addMetric(final Metric metric) throws IllegalArgumentException { + if (!metrics.add(metric)) throw new IllegalArgumentException("Metric already added: " + metric.getId()); + return (F) this; + } + + @Override + @SuppressWarnings("unchecked") + public F onFlush(final Runnable flush) { + this.flush = flush; + return (F) this; + } + + @Override + @SuppressWarnings("unchecked") + public F errorTracker(final ErrorTracker tracker) { + this.tracker = tracker; + return (F) this; + } + + @Override + @SuppressWarnings("unchecked") + public F debug(final boolean enabled) { + this.debug = enabled; + return (F) this; + } + + @Override + @SuppressWarnings("unchecked") + public F token(@Token final String token) throws IllegalArgumentException { + if (!token.matches(Token.PATTERN)) { + throw new IllegalArgumentException("Invalid token '" + token + "', must match '" + Token.PATTERN + "'"); + } + this.token = token; + return (F) this; + } + + @Override + @SuppressWarnings("unchecked") + public F url(final URI url) { + this.url = url; + return (F) this; + } + } + + public static final class Config implements Metrics.Config { + + private final UUID serverId; + private final boolean additionalMetrics; + private final boolean debug; + private final boolean enabled; + private final boolean errorTracking; + private final boolean firstRun; + private final boolean externallyManaged; + + public Config( + UUID serverId, + boolean additionalMetrics, + boolean debug, + boolean enabled, + boolean errorTracking, + boolean firstRun, + boolean externallyManaged + ) { + this.serverId = serverId; + this.additionalMetrics = additionalMetrics; + this.debug = debug; + this.enabled = enabled; + this.errorTracking = errorTracking; + this.firstRun = firstRun; + this.externallyManaged = externallyManaged; + } + + public UUID serverId() { return serverId; } + public boolean additionalMetrics() { return additionalMetrics; } + public boolean debug() { return debug; } + public boolean enabled() { return enabled; } + public boolean errorTracking() { return errorTracking; } + public boolean firstRun() { return firstRun; } + public boolean externallyManaged() { return externallyManaged; } + + public static final String DEFAULT_COMMENT = + " FastStats (https://faststats.dev) collects anonymous usage statistics for plugin developers.\n" + + "# This helps developers understand how their projects are used in the real world.\n" + + "#\n" + + "# No IP addresses, player data, or personal information is collected.\n" + + "# The server ID below is randomly generated and can be regenerated at any time.\n" + + "#\n" + + "# Enabling metrics has no noticeable performance impact.\n" + + "# Keeping metrics enabled is recommended, but you can opt out by setting\n" + + "# 'enabled=false' in plugins/faststats/config.properties.\n" + + "#\n" + + "# If you suspect a plugin is collecting personal data or bypassing the \"enabled\" option,\n" + + "# please report it at: https://faststats.dev/abuse\n" + + "#\n" + + "# For more information, visit: https://faststats.dev/info\n"; + +// @Contract(mutates = "io") + public static Config read(final Path file) throws RuntimeException { + return read(file, DEFAULT_COMMENT, false, false); + } + +// @Contract(mutates = "io") + public static Config read(final Path file, final String comment, final boolean externallyManaged, final boolean externallyEnabled) throws RuntimeException { + final Optional properties = readOrEmpty(file); + final boolean firstRun = !properties.isPresent(); + final AtomicBoolean saveConfig = new AtomicBoolean(firstRun); + + final UUID serverId = properties.map(object -> object.getProperty("serverId")).map(string -> { + try { + final String trimmed = string.trim(); + final String corrected = trimmed.length() > 36 ? trimmed.substring(0, 36) : trimmed; + if (!corrected.equals(string)) saveConfig.set(true); + return UUID.fromString(corrected); + } catch (final IllegalArgumentException e) { + saveConfig.set(true); + return UUID.randomUUID(); + } + }).orElseGet(() -> { + saveConfig.set(true); + return UUID.randomUUID(); + }); + + final BiPredicate predicate = (key, defaultValue) -> { + return properties.map(object -> object.getProperty(key)).map(Boolean::parseBoolean).orElseGet(() -> { + saveConfig.set(true); + return defaultValue; + }); + }; + + final boolean enabled = externallyManaged ? externallyEnabled : predicate.test("enabled", true); + final boolean errorTracking = predicate.test("submitErrors", false); // InvSee++: changed default from true to false. + final boolean additionalMetrics = predicate.test("submitAdditionalMetrics", true); + final boolean debug = predicate.test("debug", false); + + if (saveConfig.get()) try { + save(file, externallyManaged, comment, serverId, enabled, errorTracking, additionalMetrics, debug); + } catch (final IOException e) { + throw new RuntimeException("Failed to save metrics config", e); + } + + return new Config(serverId, additionalMetrics, debug, enabled, errorTracking, firstRun, externallyManaged); + } + + private static Optional readOrEmpty(final Path file) throws RuntimeException { + if (!Files.isRegularFile(file)) return Optional.empty(); + try (final BufferedReader reader = Files.newBufferedReader(file, UTF_8)) { + final Properties properties = new Properties(); + properties.load(reader); + return Optional.of(properties); + } catch (final IOException e) { + throw new RuntimeException("Failed to read metrics config", e); + } + } + + private static void save(final Path file, final boolean externallyManaged, final String comment, final UUID serverId, final boolean enabled, final boolean errorTracking, final boolean additionalMetrics, final boolean debug) throws IOException { + Files.createDirectories(file.getParent()); + try (final OutputStream out = Files.newOutputStream(file); + final OutputStreamWriter writer = new OutputStreamWriter(out, UTF_8)) { + final Properties properties = new Properties(); + + properties.setProperty("serverId", serverId.toString()); + if (!externallyManaged) properties.setProperty("enabled", Boolean.toString(enabled)); + properties.setProperty("submitErrors", Boolean.toString(errorTracking)); + properties.setProperty("submitAdditionalMetrics", Boolean.toString(additionalMetrics)); + properties.setProperty("debug", Boolean.toString(debug)); + + properties.store(writer, comment); + } + } + } +} diff --git a/FastStats/src/main/java/dev/faststats/core/Token.java b/FastStats/src/main/java/dev/faststats/core/Token.java new file mode 100644 index 0000000..a6d1176 --- /dev/null +++ b/FastStats/src/main/java/dev/faststats/core/Token.java @@ -0,0 +1,23 @@ +package dev.faststats.core; + +import org.intellij.lang.annotations.Pattern; +import org.jetbrains.annotations.NonNls; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; + +/** + * An annotation to mark a token. + * + * @since 0.1.0 + */ +@NonNls +@Pattern(Token.PATTERN) +@Retention(RetentionPolicy.CLASS) +@Target({METHOD, FIELD, PARAMETER, LOCAL_VARIABLE}) +public @interface Token { + String PATTERN = "[a-z0-9]{32}"; +} diff --git a/FastStats/src/main/java/dev/faststats/core/data/ArrayMetric.java b/FastStats/src/main/java/dev/faststats/core/data/ArrayMetric.java new file mode 100644 index 0000000..bfc7c83 --- /dev/null +++ b/FastStats/src/main/java/dev/faststats/core/data/ArrayMetric.java @@ -0,0 +1,26 @@ +package dev.faststats.core.data; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; + +import java.util.Optional; +import java.util.concurrent.Callable; + +final class ArrayMetric extends SimpleMetric { + public ArrayMetric(@SourceId final String id, final Callable callable) throws IllegalArgumentException { + super(id, callable); + } + + @Override + public Optional getData() throws Exception { + return compute().map(data -> { + final JsonArray elements = new JsonArray(data.length); + for (final T d : data) { + if (d instanceof Boolean) elements.add((Boolean) d); + else if (d instanceof Number) elements.add((Number) d); + else elements.add(String.valueOf(d)); + } + return elements; + }); + } +} diff --git a/FastStats/src/main/java/dev/faststats/core/data/Metric.java b/FastStats/src/main/java/dev/faststats/core/data/Metric.java new file mode 100644 index 0000000..6feb20e --- /dev/null +++ b/FastStats/src/main/java/dev/faststats/core/data/Metric.java @@ -0,0 +1,144 @@ +package dev.faststats.core.data; + +import com.google.gson.JsonElement; + +import java.util.Optional; +import java.util.concurrent.Callable; + +/** + * A metric. + * + * @param the metric data type + * @since 0.16.0 + */ +public interface Metric { + /** + * Get the source id. + * + * @return the source id + * @since 0.16.0 + */ + @SourceId +// @Contract(pure = true) + String getId(); + + /** + * Compute the metric data. + * + * @return an optional containing the metric data + * @throws Exception if unable to compute the metric data + * @implSpec The implementation must be thread-safe and pure (i.e. not modify any shared state). + * @since 0.16.0 + */ +// @Contract(pure = true) + Optional compute() throws Exception; + + /** + * Get the metric data as a JSON element. + * + * @return an optional containing the metric data as {@link JsonElement} + * @throws Exception if unable to get the metric data + * @implSpec The implementation must call {@link #compute()} to get the metric data + * and follow the same thread-safety and pureness requirements. + * @see #compute() + * @since 0.16.0 + */ +// @Contract(pure = true) + Optional getData() throws Exception; + + /** + * Create a string array metric. + * + * @param id the source id + * @param callable the metric data callable + * @return the string array metric + * @throws IllegalArgumentException if the source id is invalid + * @apiNote The callable must be thread-safe and pure (i.e. not modify any shared state). + * @see #compute() + * @since 0.16.0 + */ +// @Contract(value = "_, _ -> new", pure = true) + static Metric stringArray(@SourceId final String id, final Callable callable) throws IllegalArgumentException { + return new ArrayMetric<>(id, callable); + } + + /** + * Create a boolean array metric. + * + * @param id the source id + * @param callable the metric data callable + * @return the boolean array metric + * @throws IllegalArgumentException if the source id is invalid + * @apiNote The callable must be thread-safe and pure (i.e. not modify any shared state). + * @see #compute() + * @since 0.16.0 + */ +// @Contract(value = "_, _ -> new", pure = true) + static Metric booleanArray(@SourceId final String id, final Callable callable) throws IllegalArgumentException { + return new ArrayMetric<>(id, callable); + } + + /** + * Create a number array metric. + * + * @param id the source id + * @param callable the metric data callable + * @return the number array metric + * @throws IllegalArgumentException if the source id is invalid + * @apiNote The callable must be thread-safe and pure (i.e. not modify any shared state). + * @see #compute() + * @since 0.16.0 + */ +// @Contract(value = "_, _ -> new", pure = true) + static Metric numberArray(@SourceId final String id, final Callable callable) throws IllegalArgumentException { + return new ArrayMetric<>(id, callable); + } + + /** + * Create a metric for a boolean value. + * + * @param id the source id + * @param callable the metric data callable + * @return the boolean metric + * @throws IllegalArgumentException if the source id is invalid + * @apiNote The callable must be thread-safe and pure (i.e. not modify any shared state). + * @see #compute() + * @since 0.16.0 + */ +// @Contract(value = "_, _ -> new", pure = true) + static Metric bool(@SourceId final String id, final Callable callable) throws IllegalArgumentException { + return new SingleValueMetric<>(id, callable); + } + + /** + * Create a metric for a string value. + * + * @param id the source id + * @param callable the metric data callable + * @return the string metric + * @throws IllegalArgumentException if the source id is invalid + * @apiNote The callable must be thread-safe and pure (i.e. not modify any shared state). + * @see #compute() + * @since 0.16.0 + */ +// @Contract(value = "_, _ -> new", pure = true) + static Metric string(@SourceId final String id, final Callable callable) throws IllegalArgumentException { + return new SingleValueMetric<>(id, callable); + } + + /** + * Create a metric for a number value. + * + * @param id the source id + * @param callable the metric data callable + * @return the number metric + * @throws IllegalArgumentException if the source id is invalid + * @apiNote The callable must be thread-safe and pure (i.e. not modify any shared state). + * @see #compute() + * @since 0.16.0 + */ +// @Contract(value = "_, _ -> new", pure = true) + static Metric number(@SourceId final String id, final Callable callable) throws IllegalArgumentException { + return new SingleValueMetric<>(id, callable); + } +} diff --git a/FastStats/src/main/java/dev/faststats/core/data/SimpleMetric.java b/FastStats/src/main/java/dev/faststats/core/data/SimpleMetric.java new file mode 100644 index 0000000..58981f5 --- /dev/null +++ b/FastStats/src/main/java/dev/faststats/core/data/SimpleMetric.java @@ -0,0 +1,46 @@ +package dev.faststats.core.data; + +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.Callable; + +abstract class SimpleMetric implements Metric { + private final @SourceId String id; + private final Callable callable; + + public SimpleMetric(@SourceId final String id, final Callable callable) throws IllegalArgumentException { + if (!id.matches(SourceId.PATTERN)) { + throw new IllegalArgumentException("Invalid source id '" + id + "', must match '" + SourceId.PATTERN + "'"); + } + this.id = id; + this.callable = callable; + } + + @Override + public final @SourceId String getId() { + return id; + } + + public final Optional compute() throws Exception { + return Optional.ofNullable(callable.call()); + } + + @Override + public boolean equals(final Object o) { + if (o == null || getClass() != o.getClass()) return false; + final SimpleMetric that = (SimpleMetric) o; + return Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return Objects.hashCode(id); + } + + @Override + public String toString() { + return "SimpleMetric{" + + "id='" + id + '\'' + + '}'; + } +} diff --git a/FastStats/src/main/java/dev/faststats/core/data/SingleValueMetric.java b/FastStats/src/main/java/dev/faststats/core/data/SingleValueMetric.java new file mode 100644 index 0000000..db6029e --- /dev/null +++ b/FastStats/src/main/java/dev/faststats/core/data/SingleValueMetric.java @@ -0,0 +1,22 @@ +package dev.faststats.core.data; + +import com.google.gson.JsonElement; +import com.google.gson.JsonPrimitive; + +import java.util.Optional; +import java.util.concurrent.Callable; + +final class SingleValueMetric extends SimpleMetric { + public SingleValueMetric(@SourceId final String id, final Callable callable) throws IllegalArgumentException { + super(id, callable); + } + + @Override + public Optional getData() throws Exception { + return compute().map(data -> { + if (data instanceof Boolean) return new JsonPrimitive((Boolean) data); + if (data instanceof Number) return new JsonPrimitive((Number) data); + return new JsonPrimitive(data.toString()); + }); + } +} diff --git a/FastStats/src/main/java/dev/faststats/core/data/SourceId.java b/FastStats/src/main/java/dev/faststats/core/data/SourceId.java new file mode 100644 index 0000000..1ea4079 --- /dev/null +++ b/FastStats/src/main/java/dev/faststats/core/data/SourceId.java @@ -0,0 +1,20 @@ +package dev.faststats.core.data; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; + +/** + * An annotation to mark a source id. + * + * @since 0.16.0 + */ +//@NonNls +//@Pattern(SourceId.PATTERN) +@Retention(RetentionPolicy.CLASS) +@Target({METHOD, FIELD, PARAMETER, LOCAL_VARIABLE}) +public @interface SourceId { + String PATTERN = "[a-z_]+"; +} diff --git a/InvSee++_Clear_Plugin/.gitignore b/InvSee++_Clear_Plugin/.gitignore new file mode 100644 index 0000000..78355a4 --- /dev/null +++ b/InvSee++_Clear_Plugin/.gitignore @@ -0,0 +1,12 @@ +#IntelliJ +.idea/* +**.iml + +#Maven +target/* + +#Eclipse +**/.settings/* +**/.project +**/.classpath +/target/ diff --git a/InvSee++_Clear_Plugin/pom.xml b/InvSee++_Clear_Plugin/pom.xml new file mode 100644 index 0000000..8264761 --- /dev/null +++ b/InvSee++_Clear_Plugin/pom.xml @@ -0,0 +1,62 @@ + + + invsee-plus-plus + com.janboerman.invsee + 0.31.11-SNAPSHOT + + 4.0.0 + + invsee-plus-plus_clear_plugin + InvSee++ Clear Plugin + + + InvSee++_Clear + + + + src/main/resources + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 8 + + + + + + + + spigot-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + + + + org.spigotmc + spigot-api + 1.20.4-R0.1-SNAPSHOT + provided + + + com.janboerman.invsee + invsee-plus-plus_plugin + ${project.version} + provided + + + com.janboerman.invsee + utils + ${project.version} + provided + + + + \ No newline at end of file diff --git a/InvSee++_Clear_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clear/ClearPlugin.java b/InvSee++_Clear_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clear/ClearPlugin.java new file mode 100644 index 0000000..5f240c1 --- /dev/null +++ b/InvSee++_Clear_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clear/ClearPlugin.java @@ -0,0 +1,98 @@ +package com.janboerman.invsee.spigot.addon.clear; + +import com.janboerman.invsee.spigot.InvseePlusPlus; +import com.janboerman.invsee.spigot.api.Exempt; +import com.janboerman.invsee.spigot.api.InvseeAPI; +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import org.bukkit.command.PluginCommand; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.plugin.java.JavaPlugin; + +public class ClearPlugin extends JavaPlugin { + + private InvseePlusPlus ispp; + private InvseeAPI api; + + @Override + public void onEnable() { + saveDefaultConfig(); + Server server = getServer(); + + ispp = (InvseePlusPlus) server.getPluginManager().getPlugin("InvSeePlusPlus"); + api = ispp.getApi(); + + ClearTabCompleter tabCompleter = new ClearTabCompleter(); + + PluginCommand invClear = server.getPluginCommand("invclear"); + invClear.setExecutor(new InvClearExecutor(this, api)); + invClear.setTabCompleter(tabCompleter); + + PluginCommand enderClear = server.getPluginCommand("enderclear"); + enderClear.setExecutor(new EnderClearExecutor(this, api)); + enderClear.setTabCompleter(tabCompleter); + } + + boolean offlinePlayerSupport() { + FileConfiguration config = getConfig(); + + Object value = config.get("offline-player-support"); + if (value instanceof Boolean) { + return (Boolean) value; + } else if (value instanceof String) { + String s = (String) value; + if ("true".equalsIgnoreCase(s)) { + return true; + } else if ("false".equalsIgnoreCase(s)) { + return false; + } else if ("same_as_Invsee++".equalsIgnoreCase(s)) { + return ispp.offlinePlayerSupport(); + } else if ("same_as_InvseeAPI".equalsIgnoreCase(s)) { + return api.offlinePlayerSupport(); + } + } + + //fallback + return true; + } + + boolean bypassExemptInvsee(CommandSender sender) { + Boolean bypass = bypassExempt(); + if (bypass == null) { + return sender.hasPermission(Exempt.BYPASS_EXEMPT_INVENTORY); + } else { + return bypass; + } + } + + boolean bypassExemptEndersee(CommandSender sender) { + Boolean bypass = bypassExempt(); + if (bypass == null) { + return sender.hasPermission(Exempt.BYPASS_EXEMPT_ENDERCHEST); + } else { + return bypass; + } + } + + private Boolean bypassExempt() { + FileConfiguration config = getConfig(); + + Object value = config.get("bypass-exempt"); + if (value instanceof Boolean) { + return (Boolean) value; + } else if (value instanceof String) { + String s = (String) value; + if ("true".equalsIgnoreCase(s)) { + return true; + } else if ("false".equalsIgnoreCase(s)) { + return false; + } + } + + return null; + } + + //TODO configuration option to also clear out of the queue created by InvSee++_Give ? + //TODO when enabled, the InvSee++_Give queue could also be re-polled after clearing happens. + +} diff --git a/InvSee++_Clear_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clear/ClearTabCompleter.java b/InvSee++_Clear_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clear/ClearTabCompleter.java new file mode 100644 index 0000000..866641d --- /dev/null +++ b/InvSee++_Clear_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clear/ClearTabCompleter.java @@ -0,0 +1,60 @@ +package com.janboerman.invsee.spigot.addon.clear; + +import static com.janboerman.invsee.utils.Compat.emptyList; + +import com.janboerman.invsee.utils.StringHelper; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +class ClearTabCompleter implements TabCompleter { + + ClearTabCompleter() {} + + @Override + public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) { + if (args.length == 0 || args[0].isEmpty()) return null; //tabcomplete players + + else if (args.length == 1) { + final String inputName = args[0]; + Stream targets = sender.getServer().getOnlinePlayers().stream(); + if (sender instanceof Player) { + Player player = (Player) sender; + targets = targets.filter(player::canSee); + } + return targets.map(Player::getName) + .filter(name -> StringHelper.startsWithIgnoreCase(name, inputName)) + .collect(Collectors.toList()); + } + + else if (args.length == 2) { + final String inputMaterial = args[1].toLowerCase(); + Stream materialNames = Arrays.stream(Material.values()).map(material -> material.name().toLowerCase()); + if (!inputMaterial.isEmpty()) { + materialNames = materialNames.filter(name -> name.startsWith(inputMaterial)); + } + return materialNames.collect(Collectors.toList()); + } + + else if (args.length == 3) { + final String inputAmount = args[2]; + Material material = Material.matchMaterial(args[1]); + Stream amounts = IntStream.rangeClosed(1, material != null ? material.getMaxStackSize() : 64) + .mapToObj(Integer::toString); + if (!inputAmount.isEmpty()) { + amounts = amounts.filter(amount -> amount.startsWith(inputAmount)); + } + return amounts.collect(Collectors.toList()); + } + + return emptyList(); + } +} diff --git a/InvSee++_Clear_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clear/Convert.java b/InvSee++_Clear_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clear/Convert.java new file mode 100644 index 0000000..e306967 --- /dev/null +++ b/InvSee++_Clear_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clear/Convert.java @@ -0,0 +1,84 @@ +package com.janboerman.invsee.spigot.addon.clear; + +import com.janboerman.invsee.utils.Either; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.Tag; + +import java.util.UUID; + +class Convert { + + static Either convertPlayer(String input) { + assert input != null; + + try { + UUID uuid = UUID.fromString(input); + return Either.left(uuid); + } catch (IllegalArgumentException e) { + } + + return Either.right(input); + } + + static Either convertItemType(String input) { + assert input != null; + + String materialName; + Byte dataValue; + + final int colonIndex = input.indexOf(':'); + if (colonIndex != -1) { + materialName = input.substring(0, colonIndex); + try { + dataValue = Byte.parseByte(input.substring(colonIndex + 1)); + } catch (NumberFormatException ignored) { + dataValue = null; + } + } else { + materialName = input; + dataValue = null; + } + + Material material = Material.matchMaterial(materialName); + if (material != null) { + if (dataValue != null) { + return Either.right(ItemType.withData(material, dataValue)); + } else { + return Either.right(ItemType.plain(material)); + } + } else { + try { + NamespacedKey tagKey = NamespacedKey.fromString(materialName, null); + Tag tag = Bukkit.getTag(Tag.REGISTRY_ITEMS, tagKey, Material.class); + if (tag != null) { + return Either.right(ItemType.fromTag(tag)); + } + tag = Bukkit.getTag(Tag.REGISTRY_BLOCKS, tagKey, Material.class); + if (tag != null) { + return Either.right(ItemType.fromTag(tag)); + } + } catch (NoClassDefFoundError | NoSuchMethodError legacyServerIgnored) { + } + + return Either.left("Material " + input + " does not exist."); + } + } + + static Either convertAmount(String input) { + assert input != null; + + try { + int value = Integer.parseInt(input); + if (value > 0) { + return Either.right(value); + } else { + return Either.left(input + " is not a positive integer."); + } + } catch (IllegalArgumentException e) { + return Either.left(input + " is not a positive integer."); + } + } + +} diff --git a/InvSee++_Clear_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clear/EnderClearExecutor.java b/InvSee++_Clear_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clear/EnderClearExecutor.java new file mode 100644 index 0000000..f37ca6f --- /dev/null +++ b/InvSee++_Clear_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clear/EnderClearExecutor.java @@ -0,0 +1,137 @@ +package com.janboerman.invsee.spigot.addon.clear; + +import com.janboerman.invsee.spigot.api.CreationOptions; +import com.janboerman.invsee.spigot.api.InvseeAPI; +import com.janboerman.invsee.spigot.api.EnderSpectatorInventory; +import com.janboerman.invsee.spigot.api.response.*; +import com.janboerman.invsee.spigot.api.template.EnderChestSlot; +import com.janboerman.invsee.utils.Either; + +import org.bukkit.ChatColor; +import org.bukkit.command.*; + +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.logging.Level; + +class EnderClearExecutor implements CommandExecutor { + + private final ClearPlugin plugin; + private final InvseeAPI api; + + EnderClearExecutor(ClearPlugin plugin, InvseeAPI api) { + this.plugin = plugin; + this.api = api; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (args.length == 0) return false; + + String inputPlayer = args[0]; + + Either eitherPlayer = Convert.convertPlayer(inputPlayer); + CompletableFuture> uuidFuture; + CompletableFuture> userNameFuture; + if (eitherPlayer.isLeft()) { + UUID uuid = eitherPlayer.getLeft(); + uuidFuture = CompletableFuture.completedFuture(Optional.of(uuid)); + userNameFuture = api.fetchUserName(uuid); + } else { + assert eitherPlayer.isRight(); + String userName = eitherPlayer.getRight(); + userNameFuture = CompletableFuture.completedFuture(Optional.of(userName)); + uuidFuture = api.fetchUniqueId(userName); + } + + ItemType itemType = null; + //TODO nbt tag? + + int maxCount = -1; + + if (args.length >= 2) { + String inputItemType = args[1]; + Either eitherMaterial = Convert.convertItemType(inputItemType); + if (eitherMaterial.isRight()) { + itemType = eitherMaterial.getRight(); + } else { + assert eitherMaterial.isLeft(); + sender.sendMessage(ChatColor.RED + eitherMaterial.getLeft()); + return true; + } + } + + if (args.length >= 3) { + String inputMaxCount = args[2]; + Either eitherMaxCount = Convert.convertAmount(inputMaxCount); + if (eitherMaxCount.isRight()) { + maxCount = eitherMaxCount.getRight(); + } else { + assert eitherMaxCount.isLeft(); + sender.sendMessage(ChatColor.RED + eitherMaxCount.getLeft()); + return true; + } + } + + final ItemType finalItemType = itemType; + final int finalMaxCount = maxCount; + final CreationOptions creationOptions = api.enderInventoryCreationOptions() + .withOfflinePlayerSupport(plugin.offlinePlayerSupport()) + .withBypassExemptedPlayers(plugin.bypassExemptEndersee(sender)); + + uuidFuture., Void>thenCombineAsync(userNameFuture, (optUuid, optName) -> { + if (!optName.isPresent() || !optUuid.isPresent()) { + sender.sendMessage(ChatColor.RED + "Unknown player: " + inputPlayer); + } else { + String userName = optName.get(); + UUID uuid = optUuid.get(); + + CompletableFuture> responseFuture = + api.enderSpectatorInventory(uuid, userName, creationOptions); + responseFuture.thenAcceptAsync(response -> { + if (response.isSuccess()) { + EnderSpectatorInventory inventory = response.getInventory(); + if (finalItemType == null) { + inventory.clear(); + sender.sendMessage(ChatColor.GREEN + "Cleared " + userName + "'s enderchest."); + } else { + if (finalMaxCount == -1) { + finalItemType.removeAllFrom(inventory); + sender.sendMessage(ChatColor.GREEN + "Removed all " + finalItemType + " from " + userName + "'s enderchest."); + } else { + int removed = finalItemType.removeAtMostFrom(inventory, finalMaxCount); + sender.sendMessage( ChatColor.GREEN + "Removed " + removed + " " + finalItemType + " from " + userName + "'s enderchest."); + } + } + api.saveEnderChest(inventory).whenComplete((v, e) -> { + if (e != null) plugin.getLogger().log(Level.SEVERE, "Could not save enderchest", e); + }); + } else { + NotCreatedReason reason = response.getReason(); + if (reason instanceof TargetDoesNotExist) { + TargetDoesNotExist targetDoesNotExist = (TargetDoesNotExist) reason; + sender.sendMessage(ChatColor.RED + "Player " + targetDoesNotExist.getTarget() + " does not exist."); + } else if (reason instanceof UnknownTarget) { + UnknownTarget unknownTarget = (UnknownTarget) reason; + sender.sendMessage(ChatColor.RED + "Player " + unknownTarget.getTarget() + " has not logged onto the server yet."); + } else if (reason instanceof TargetHasExemptPermission) { + TargetHasExemptPermission targetHasExemptPermission = (TargetHasExemptPermission) reason; + sender.sendMessage(ChatColor.RED + "Player " + targetHasExemptPermission.getTarget() + " is exempted from being spectated."); + } else if (reason instanceof ImplementationFault) { + ImplementationFault implementationFault = (ImplementationFault) reason; + sender.sendMessage(ChatColor.RED + "An internal fault occurred when trying to load " + implementationFault.getTarget() + "'s enderchest."); + } else if (reason instanceof OfflineSupportDisabled) { + sender.sendMessage(ChatColor.RED + "Spectating offline players' enderchests is disabled."); + } else { + sender.sendMessage(ChatColor.RED + "Cannot clear from " + inputPlayer + "'s enderchest for an unknown reason."); + } + } + }, runnable -> api.getScheduler().executeSyncPlayer(uuid, runnable, null)); + } + + return null; + }, api.getScheduler()::executeSyncGlobal); + return true; + } + +} diff --git a/InvSee++_Clear_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clear/InvClearExecutor.java b/InvSee++_Clear_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clear/InvClearExecutor.java new file mode 100644 index 0000000..6fdea2b --- /dev/null +++ b/InvSee++_Clear_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clear/InvClearExecutor.java @@ -0,0 +1,139 @@ +package com.janboerman.invsee.spigot.addon.clear; + +import com.janboerman.invsee.spigot.api.CreationOptions; +import com.janboerman.invsee.spigot.api.InvseeAPI; +import com.janboerman.invsee.spigot.api.MainSpectatorInventory; +import com.janboerman.invsee.spigot.api.response.*; +import com.janboerman.invsee.spigot.api.template.PlayerInventorySlot; +import com.janboerman.invsee.utils.Either; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.command.*; + +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.logging.Level; + +class InvClearExecutor implements CommandExecutor { + + private final ClearPlugin plugin; + private final InvseeAPI api; + + InvClearExecutor(ClearPlugin plugin, InvseeAPI api) { + this.plugin = plugin; + this.api = api; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (args.length == 0) return false; + + String inputPlayer = args[0]; + + Either eitherPlayer = Convert.convertPlayer(inputPlayer); + CompletableFuture> uuidFuture; + CompletableFuture> userNameFuture; + if (eitherPlayer.isLeft()) { + UUID uuid = eitherPlayer.getLeft(); + uuidFuture = CompletableFuture.completedFuture(Optional.of(uuid)); + userNameFuture = api.fetchUserName(uuid); + } else { + assert eitherPlayer.isRight(); + String userName = eitherPlayer.getRight(); + userNameFuture = CompletableFuture.completedFuture(Optional.of(userName)); + uuidFuture = api.fetchUniqueId(userName); + } + + ItemType itemType = null; + //TODO nbt tag? + //TODO components? This is actually possible now! + + int maxCount = -1; + + if (args.length >= 2) { + String inputItemType = args[1]; + Either eitherMaterial = Convert.convertItemType(inputItemType); + if (eitherMaterial.isRight()) { + itemType = eitherMaterial.getRight(); + } else { + assert eitherMaterial.isLeft(); + sender.sendMessage(ChatColor.RED + eitherMaterial.getLeft()); + return true; + } + } + + if (args.length >= 3) { + String inputMaxCount = args[2]; + Either eitherMaxCount = Convert.convertAmount(inputMaxCount); + if (eitherMaxCount.isRight()) { + maxCount = eitherMaxCount.getRight(); + } else { + assert eitherMaxCount.isLeft(); + sender.sendMessage(ChatColor.RED + eitherMaxCount.getLeft()); + return true; + } + } + + final ItemType finalItemType = itemType; + final int finalMaxCount = maxCount; + final CreationOptions creationOptions = api.mainInventoryCreationOptions() + .withOfflinePlayerSupport(plugin.offlinePlayerSupport()) + .withBypassExemptedPlayers(plugin.bypassExemptInvsee(sender)); + + uuidFuture., Void>thenCombineAsync(userNameFuture, (optUuid, optName) -> { + if (!optName.isPresent() || !optUuid.isPresent()) { + sender.sendMessage(ChatColor.RED + "Unknown player: " + inputPlayer); + } else { + String userName = optName.get(); + UUID uuid = optUuid.get(); + + CompletableFuture> responseFuture + = api.mainSpectatorInventory(uuid, userName, creationOptions); + responseFuture.thenAcceptAsync(response -> { + if (response.isSuccess()) { + MainSpectatorInventory inventory = response.getInventory(); + if (finalItemType == null) { + inventory.clear(); + sender.sendMessage(ChatColor.GREEN + "Cleared " + userName + "'s inventory."); + } else { + if (finalMaxCount == -1) { + finalItemType.removeAllFrom(inventory); + sender.sendMessage(ChatColor.GREEN + "Removed all " + finalItemType + " from " + userName + "'s inventory."); + } else { + int removed = finalItemType.removeAtMostFrom(inventory, finalMaxCount); + sender.sendMessage( ChatColor.GREEN + "Removed " + removed + " " + finalItemType + " from " + userName + "'s inventory."); + } + } + api.saveInventory(inventory).whenComplete((v, e) -> { + if (e != null) plugin.getLogger().log(Level.SEVERE, "Could not save inventory", e); + }); + } else { + NotCreatedReason reason = response.getReason(); + if (reason instanceof TargetDoesNotExist) { + TargetDoesNotExist targetDoesNotExist = (TargetDoesNotExist) reason; + sender.sendMessage(ChatColor.RED + "Player " + targetDoesNotExist.getTarget() + " does not exist."); + } else if (reason instanceof UnknownTarget) { + UnknownTarget unknownTarget = (UnknownTarget) reason; + sender.sendMessage(ChatColor.RED + "Player " + unknownTarget.getTarget() + " has not logged onto the server yet."); + } else if (reason instanceof TargetHasExemptPermission) { + TargetHasExemptPermission targetHasExemptPermission = (TargetHasExemptPermission) reason; + sender.sendMessage(ChatColor.RED + "Player " + targetHasExemptPermission.getTarget() + " is exempted from being spectated."); + } else if (reason instanceof ImplementationFault) { + ImplementationFault implementationFault = (ImplementationFault) reason; + sender.sendMessage(ChatColor.RED + "An internal fault occurred when trying to load " + implementationFault.getTarget() + "'s inventory."); + } else if (reason instanceof OfflineSupportDisabled) { + sender.sendMessage(ChatColor.RED + "Spectating offline players' inventories is disabled."); + } else { + sender.sendMessage(ChatColor.RED + "Cannot clear from " + inputPlayer + "'s inventory for an unknown reason."); + } + } + }, runnable -> api.getScheduler().executeSyncPlayer(uuid, runnable, null)); + } + + return null; + }, api.getScheduler()::executeSyncGlobal); + return true; + } + +} diff --git a/InvSee++_Clear_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clear/ItemType.java b/InvSee++_Clear_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clear/ItemType.java new file mode 100644 index 0000000..ac61513 --- /dev/null +++ b/InvSee++_Clear_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clear/ItemType.java @@ -0,0 +1,146 @@ +package com.janboerman.invsee.spigot.addon.clear; + +import org.bukkit.Material; +import org.bukkit.Tag; +import org.bukkit.inventory.Inventory; + +import java.util.Objects; + +interface ItemType { + + public static ItemType plain(Material material) { + return new Plain(material); + } + + public static ItemType withData(Material material, byte data) { + return new WithData(material, data); + } + + public static ItemType fromTag(Tag tag) { + return new FromTag(tag); + } + + // + + public void removeAllFrom(Inventory inventory); + + public int removeAtMostFrom(Inventory inventory, int atMost); + + // + + static class Plain implements ItemType { + private final Material material; + + Plain(Material material) { + this.material = Objects.requireNonNull(material); + } + + @Override + public void removeAllFrom(Inventory inventory) { + inventory.remove(material); + } + + @Override + public int removeAtMostFrom(Inventory inventory, int atMost) { + return RemoveUtil.removeAtMost(inventory, material, atMost); + } + + @Override + public String toString() { + return material.toString(); + } + + @Override + public boolean equals(Object o) { + if (o == this) return true; + if (!(o instanceof Plain)) return false; + + Plain that = (Plain) o; + return this.material == that.material; + } + + @Override + public int hashCode() { + return Objects.hashCode(material); + } + } + + static class WithData implements ItemType { + private final Material material; + private final byte data; + + WithData(Material material, byte data) { + this.material = Objects.requireNonNull(material); + this.data = data; + } + + @Override + public void removeAllFrom(Inventory inventory) { + RemoveUtil.removeIf(inventory, stack -> stack.getType() == material && stack.getDurability() == (short) data); + } + + @Override + public int removeAtMostFrom(Inventory inventory, int atMost) { + return RemoveUtil.removeIfAtMost(inventory, stack -> stack.getType() == material && stack.getDurability() == (short) data, atMost); + } + + @Override + public String toString() { + return material.toString() + ":" + data; + } + + @Override + public boolean equals(Object o) { + if (o == this) return true; + if (!(o instanceof WithData)) return false; + + WithData that = (WithData) o; + return this.material == that.material && this.data == that.data; + } + + @Override + public int hashCode() { + return Objects.hash(material, data); + } + } + + static class FromTag implements ItemType { + private final Tag tag; + + FromTag(Tag tag) { + this.tag = tag; + } + + + @Override + public void removeAllFrom(Inventory inventory) { + RemoveUtil.removeIf(inventory, stack -> tag.isTagged(stack.getType())); + } + + @Override + public int removeAtMostFrom(Inventory inventory, int atMost) { + return RemoveUtil.removeIfAtMost(inventory, stack -> tag.isTagged(stack.getType()), atMost); + } + + @Override + public String toString() { + //call tag.getKey() first (instead of tag.toString() directly), because CraftTag does not override toString(), NamespacedKey does. + return tag.getKey().toString(); + } + + @Override + public boolean equals(Object o) { + if (o == this) return true; + if (!(o instanceof FromTag)) return false; + + FromTag that = (FromTag) o; + return Objects.equals(this.tag, that.tag); + } + + @Override + public int hashCode() { + return Objects.hashCode(tag); + } + } + +} diff --git a/InvSee++_Clear_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clear/RemoveUtil.java b/InvSee++_Clear_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clear/RemoveUtil.java new file mode 100644 index 0000000..e0718e7 --- /dev/null +++ b/InvSee++_Clear_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clear/RemoveUtil.java @@ -0,0 +1,62 @@ +package com.janboerman.invsee.spigot.addon.clear; + +import org.bukkit.Material; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import java.util.function.Predicate; + +class RemoveUtil { + + private RemoveUtil() {} + + static int removeAtMost(Inventory inventory, Material material, int atMost) { + int removed = 0; + + for (int i = 0; i < inventory.getSize() && atMost > 0; i++) { + ItemStack itemStack = inventory.getItem(i); + if (itemStack != null && itemStack.getType() == material) { + final int stackAmount = itemStack.getAmount(); + final int subtractAmount = Math.min(stackAmount, atMost); + + itemStack.setAmount(stackAmount - subtractAmount); + inventory.setItem(i, itemStack); + + atMost -= subtractAmount; + removed += subtractAmount; + } + } + + return removed; + } + + static int removeIfAtMost(Inventory inventory, Predicate predicate, int atMost) { + int removed = 0; + + for (int i = 0; i < inventory.getSize() && atMost > 0; i++) { + ItemStack itemStack = inventory.getItem(i); + if (itemStack != null && predicate.test(itemStack)) { + final int stackAmount = itemStack.getAmount(); + final int subtractAmount = Math.min(stackAmount, atMost); + + itemStack.setAmount(stackAmount - subtractAmount); + inventory.setItem(i, itemStack); + + atMost -= subtractAmount; + removed += subtractAmount; + } + } + + return removed; + } + + static void removeIf(Inventory inventory, Predicate predicate) { + for (int slot = 0; slot < inventory.getSize(); slot++) { + final ItemStack existingStack = inventory.getItem(slot); + if (existingStack != null && predicate.test(existingStack)) { + inventory.clear(slot); + } + } + } + +} diff --git a/InvSee++_Clear_Plugin/src/main/resources/config.yml b/InvSee++_Clear_Plugin/src/main/resources/config.yml new file mode 100644 index 0000000..1c864bc --- /dev/null +++ b/InvSee++_Clear_Plugin/src/main/resources/config.yml @@ -0,0 +1,7 @@ +# Whether InvSee++_Clear can remove items from offline players. +# Possible values: [false, true, same_as_InvSee++, same_as_InvseeAPI] +offline-player-support: true + +# Whether InvSee++_Clear respects the target player's exemption status. +# Possible values: [false, true, permission] +bypass-exempt: permission \ No newline at end of file diff --git a/InvSee++_Clear_Plugin/src/main/resources/plugin.yml b/InvSee++_Clear_Plugin/src/main/resources/plugin.yml new file mode 100644 index 0000000..3dfb473 --- /dev/null +++ b/InvSee++_Clear_Plugin/src/main/resources/plugin.yml @@ -0,0 +1,34 @@ +name: InvSeePlusPlus_Clear +version: ${project.version} +main: com.janboerman.invsee.spigot.addon.clear.ClearPlugin +depend: [InvSeePlusPlus] +api-version: 1.13 +prefix: "InvSee++_Clear" +description: Remove items from (offline) players. +folia-supported: true + +permissions: + invseeplusplus.clear.*: + description: Grants all permissions for the InvSee++ Clear addon + children: + - invseeplusplus.clear.inventory + - invseeplusplus.clear.enderchest + default: false + invseeplusplus.clear.inventory: + description: "Allows you to use /invclear" + default: op + invseeplusplus.clear.enderchest: + description: "Allows you to use /enderclear" + default: op + +commands: + invclear: + description: "Clear a(n) (offline) player's inventory" + usage: / ? ? + permission: invseeplusplus.clear.inventory + aliases: [inventoryclear, iclear] + enderclear: + description: "Clear a(n) (offline) player's enderchest" + usage: / ? ? + permission: invseeplusplus.clear.enderchest + aliases: [enderchestclear, eclear] diff --git a/InvSee++_Clone_Plugin/.gitignore b/InvSee++_Clone_Plugin/.gitignore new file mode 100644 index 0000000..78355a4 --- /dev/null +++ b/InvSee++_Clone_Plugin/.gitignore @@ -0,0 +1,12 @@ +#IntelliJ +.idea/* +**.iml + +#Maven +target/* + +#Eclipse +**/.settings/* +**/.project +**/.classpath +/target/ diff --git a/InvSee++_Clone_Plugin/pom.xml b/InvSee++_Clone_Plugin/pom.xml new file mode 100644 index 0000000..a2cc250 --- /dev/null +++ b/InvSee++_Clone_Plugin/pom.xml @@ -0,0 +1,56 @@ + + + invsee-plus-plus + com.janboerman.invsee + 0.31.11-SNAPSHOT + + 4.0.0 + + invsee-plus-plus_clone_plugin + InvSee++ Clone Plugin + + + InvSee++_Clone + + + + src/main/resources + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 8 + + + + + + + + spigot-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + + + + org.spigotmc + spigot-api + 1.20.4-R0.1-SNAPSHOT + provided + + + com.janboerman.invsee + invsee-plus-plus_plugin + ${project.version} + provided + + + + \ No newline at end of file diff --git a/InvSee++_Clone_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clone/ClonePlugin.java b/InvSee++_Clone_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clone/ClonePlugin.java new file mode 100644 index 0000000..a452eef --- /dev/null +++ b/InvSee++_Clone_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clone/ClonePlugin.java @@ -0,0 +1,33 @@ +package com.janboerman.invsee.spigot.addon.clone; + +import java.util.UUID; + +import com.janboerman.invsee.spigot.api.InvseeAPI; +import com.janboerman.invsee.spigot.api.InvseePlusPlus; +import com.janboerman.invsee.spigot.api.target.Target; + +import org.bukkit.Server; +import org.bukkit.command.PluginCommand; +import org.bukkit.plugin.java.JavaPlugin; + +public final class ClonePlugin extends JavaPlugin { + + private InvseeAPI api; + + @Override + public void onEnable() { + Server server = getServer(); + InvseePlusPlus ispp = (InvseePlusPlus) server.getPluginManager().getPlugin("InvSeePlusPlus"); + this.api = ispp.getApi(); + + PluginCommand invClone = server.getPluginCommand("invclone"); + invClone.setExecutor(new InvCloneExecutor(this)); + + PluginCommand enderClone = server.getPluginCommand("enderclone"); + enderClone.setExecutor(new EnderCloneExecutor(this)); + } + + InvseeAPI getApi() { + return api; + } +} diff --git a/InvSee++_Clone_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clone/EnderCloneExecutor.java b/InvSee++_Clone_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clone/EnderCloneExecutor.java new file mode 100644 index 0000000..531237f --- /dev/null +++ b/InvSee++_Clone_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clone/EnderCloneExecutor.java @@ -0,0 +1,78 @@ +package com.janboerman.invsee.spigot.addon.clone; + +import static com.janboerman.invsee.spigot.addon.clone.TargetUtil.asPlayerExecutor; +import static com.janboerman.invsee.spigot.addon.clone.TargetUtil.asTarget; +import static com.janboerman.invsee.spigot.addon.clone.TargetUtil.getEnderChest; +import static com.janboerman.invsee.spigot.addon.clone.TargetUtil.getTarget; +import static com.janboerman.invsee.spigot.addon.clone.TargetUtil.isOnline; + +import java.util.Objects; +import java.util.concurrent.CompletableFuture; +import java.util.logging.Level; + +import com.janboerman.invsee.spigot.api.EnderSpectatorInventory; +import com.janboerman.invsee.spigot.api.InvseeAPI; +import com.janboerman.invsee.spigot.api.response.SpectateResponse; +import com.janboerman.invsee.spigot.api.target.Target; + +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +final class EnderCloneExecutor implements CommandExecutor { + + private final ClonePlugin plugin; + + EnderCloneExecutor(ClonePlugin plugin) { + this.plugin = Objects.requireNonNull(plugin); + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (args.length == 0) return false; + + Target sourceTarget = getTarget(args[0]); + Target targetTarget = args.length > 1 ? getTarget(args[1]) : asTarget(sender); + if (targetTarget == null) { + sender.sendMessage(ChatColor.RED + "Either execute this command as a player, or provide a target player."); + return true; + } + + InvseeAPI api = plugin.getApi(); + CompletableFuture> + sourceFuture = getEnderChest(api, sourceTarget, asPlayerExecutor(sender)), + targetFuture = getEnderChest(api, targetTarget, asPlayerExecutor(sender)); + + CompletableFuture.allOf(sourceFuture, targetFuture) + .whenCompleteAsync((__, throwable) -> { + if (throwable != null) { + plugin.getLogger().log(Level.SEVERE, "Error while trying to clone enderchest.", throwable); + sender.sendMessage(ChatColor.RED + "Could not clone enderchest for an unknown reason."); + return; + } + SpectateResponse + sourceResponse = sourceFuture.join(), + targetResponse = targetFuture.join(); + if (!sourceResponse.isSuccess()) { + Responses.sendEnderChestError(sender, sourceTarget, sourceResponse.getReason()); + } else if (!targetResponse.isSuccess()) { + Responses.sendEnderChestError(sender, targetTarget, targetResponse.getReason()); + } else { + EnderSpectatorInventory source = sourceResponse.getInventory(); + EnderSpectatorInventory target = targetResponse.getInventory(); + target.setContents(source); + if (!isOnline(plugin.getServer(), targetTarget)) { + api.saveEnderChest(target) + .whenComplete((___, ex) -> { + plugin.getLogger().log(Level.SEVERE, "Error while trying to clone enderchest.", ex); + sender.sendMessage(ChatColor.RED + "Could not save contents of target enderchest."); + }); + } + sender.sendMessage(ChatColor.GREEN + "Cloned " + sourceTarget + "'s enderchest to " + targetTarget + "."); + } + }, api.getScheduler()::executeSyncGlobal); + + return true; + } +} diff --git a/InvSee++_Clone_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clone/InvCloneExecutor.java b/InvSee++_Clone_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clone/InvCloneExecutor.java new file mode 100644 index 0000000..4caa00c --- /dev/null +++ b/InvSee++_Clone_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clone/InvCloneExecutor.java @@ -0,0 +1,78 @@ +package com.janboerman.invsee.spigot.addon.clone; + +import static com.janboerman.invsee.spigot.addon.clone.TargetUtil.asPlayerExecutor; +import static com.janboerman.invsee.spigot.addon.clone.TargetUtil.asTarget; +import static com.janboerman.invsee.spigot.addon.clone.TargetUtil.getInventory; +import static com.janboerman.invsee.spigot.addon.clone.TargetUtil.getTarget; +import static com.janboerman.invsee.spigot.addon.clone.TargetUtil.isOnline; + +import java.util.Objects; +import java.util.concurrent.CompletableFuture; +import java.util.logging.Level; + +import com.janboerman.invsee.spigot.api.InvseeAPI; +import com.janboerman.invsee.spigot.api.MainSpectatorInventory; +import com.janboerman.invsee.spigot.api.response.SpectateResponse; +import com.janboerman.invsee.spigot.api.target.Target; + +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +final class InvCloneExecutor implements CommandExecutor { + + private final ClonePlugin plugin; + + InvCloneExecutor(ClonePlugin plugin) { + this.plugin = Objects.requireNonNull(plugin); + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (args.length == 0) return false; + + Target sourceTarget = getTarget(args[0]); + Target targetTarget = args.length > 1 ? getTarget(args[1]) : asTarget(sender); + if (targetTarget == null) { + sender.sendMessage(ChatColor.RED + "Either execute this command as a player, or provide a target player."); + return true; + } + + InvseeAPI api = plugin.getApi(); + CompletableFuture> + sourceFuture = getInventory(api, sourceTarget, asPlayerExecutor(sender)), + targetFuture = getInventory(api, targetTarget, asPlayerExecutor(sender)); + + CompletableFuture.allOf(sourceFuture, targetFuture) + .whenCompleteAsync((__, throwable) -> { + if (throwable != null) { + plugin.getLogger().log(Level.SEVERE, "Error while trying to clone inventory.", throwable); + sender.sendMessage(ChatColor.RED + "Could not clone inventory for an unknown reason."); + return; + } + SpectateResponse + sourceResponse = sourceFuture.join(), + targetResponse = targetFuture.join(); + if (!sourceResponse.isSuccess()) { + Responses.sendInventoryError(sender, sourceTarget, sourceResponse.getReason()); + } else if (!targetResponse.isSuccess()) { + Responses.sendInventoryError(sender, targetTarget, targetResponse.getReason()); + } else { + MainSpectatorInventory source = sourceResponse.getInventory(); + MainSpectatorInventory target = targetResponse.getInventory(); + target.setContents(source); + if (!isOnline(plugin.getServer(), targetTarget)) { + api.saveInventory(target) + .whenComplete((___, ex) -> { + plugin.getLogger().log(Level.SEVERE, "Error while trying to clone inventory.", ex); + sender.sendMessage(ChatColor.RED + "Could not save contents of target inventory."); + }); + } + sender.sendMessage(ChatColor.GREEN + "Cloned " + sourceTarget + "'s inventory to " + targetTarget + "."); + } + }, api.getScheduler()::executeSyncGlobal); + + return true; + } +} diff --git a/InvSee++_Clone_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clone/Responses.java b/InvSee++_Clone_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clone/Responses.java new file mode 100644 index 0000000..5858532 --- /dev/null +++ b/InvSee++_Clone_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clone/Responses.java @@ -0,0 +1,50 @@ +package com.janboerman.invsee.spigot.addon.clone; + +import com.janboerman.invsee.spigot.api.response.ImplementationFault; +import com.janboerman.invsee.spigot.api.response.NotCreatedReason; +import com.janboerman.invsee.spigot.api.response.OfflineSupportDisabled; +import com.janboerman.invsee.spigot.api.response.TargetDoesNotExist; +import com.janboerman.invsee.spigot.api.response.TargetHasExemptPermission; +import com.janboerman.invsee.spigot.api.response.UnknownTarget; +import com.janboerman.invsee.spigot.api.target.Target; + +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +final class Responses { + + private Responses() { + } + + static void sendInventoryError(CommandSender to, Target target, NotCreatedReason reason) { + if (reason instanceof TargetDoesNotExist) { + to.sendMessage(ChatColor.RED + "Player " + target + " does not exist."); + } else if (reason instanceof UnknownTarget) { + to.sendMessage(ChatColor.RED + "Player " + target + " has not logged onto the server yet."); + } else if (reason instanceof TargetHasExemptPermission) { + to.sendMessage(ChatColor.RED + "Player " + target + " is exempted from being spectated."); + } else if (reason instanceof ImplementationFault) { + to.sendMessage(ChatColor.RED + "An internal fault occurred when trying to load " + target + "'s inventory."); + } else if (reason instanceof OfflineSupportDisabled) { + to.sendMessage(ChatColor.RED + "Spectating offline players' inventories is disabled."); + } else { + to.sendMessage(ChatColor.RED + "Could not create " + target + "'s inventory for an unknown reason."); + } + } + + static void sendEnderChestError(CommandSender to, Target target, NotCreatedReason reason) { + if (reason instanceof TargetDoesNotExist) { + to.sendMessage(ChatColor.RED + "Player " + target + " does not exist."); + } else if (reason instanceof UnknownTarget) { + to.sendMessage(ChatColor.RED + "Player " + target + " has not logged onto the server yet."); + } else if (reason instanceof TargetHasExemptPermission) { + to.sendMessage(ChatColor.RED + "Player " + target + " is exempted from being spectated."); + } else if (reason instanceof ImplementationFault) { + to.sendMessage(ChatColor.RED + "An internal fault occurred when trying to load " + target + "'s enderchest."); + } else if (reason instanceof OfflineSupportDisabled) { + to.sendMessage(ChatColor.RED + "Spectating offline players' enderchests is disabled."); + } else { + to.sendMessage(ChatColor.RED + "Could not create " + target + "'s enderchest for an unknown reason."); + } + } +} diff --git a/InvSee++_Clone_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clone/TargetUtil.java b/InvSee++_Clone_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clone/TargetUtil.java new file mode 100644 index 0000000..9996ae0 --- /dev/null +++ b/InvSee++_Clone_Plugin/src/main/java/com/janboerman/invsee/spigot/addon/clone/TargetUtil.java @@ -0,0 +1,97 @@ +package com.janboerman.invsee.spigot.addon.clone; + +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +import com.janboerman.invsee.spigot.api.CreationOptions; +import com.janboerman.invsee.spigot.api.EnderSpectatorInventory; +import com.janboerman.invsee.spigot.api.InvseeAPI; +import com.janboerman.invsee.spigot.api.MainSpectatorInventory; +import com.janboerman.invsee.spigot.api.response.NotCreatedReason; +import com.janboerman.invsee.spigot.api.response.SpectateResponse; +import com.janboerman.invsee.spigot.api.target.PlayerTarget; +import com.janboerman.invsee.spigot.api.target.Target; +import com.janboerman.invsee.spigot.api.target.UniqueIdTarget; +import com.janboerman.invsee.spigot.api.target.UsernameTarget; +import com.janboerman.invsee.spigot.api.template.EnderChestSlot; +import com.janboerman.invsee.spigot.api.template.PlayerInventorySlot; + +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +final class TargetUtil { + + private TargetUtil() { + } + + static Target getTarget(String targetPlayer) { + try { + UUID uuid = UUID.fromString(targetPlayer); + return Target.byUniqueId(uuid); + } catch (IllegalArgumentException e) { + return Target.byUsername(targetPlayer); + } + } + + static Target asTarget(CommandSender sender) { + if (sender instanceof Player) { + return Target.byPlayer((Player) sender); + } else { + return null; + } + } + + static Optional asPlayerExecutor(CommandSender sender) { + if (sender instanceof Player) { + return Optional.of((Player) sender); + } else { + return Optional.empty(); + } + } + + static boolean isOnline(Server server, Target target) { + if (target instanceof PlayerTarget) { + return server.getPlayer(((PlayerTarget) target).getPlayer().getUniqueId()) != null; + } else if (target instanceof UniqueIdTarget) { + return server.getPlayer(((UniqueIdTarget) target).getUniqueId()) != null; + } else if (target instanceof UsernameTarget) { + return server.getPlayerExact(((UsernameTarget) target).getUsername()) != null; + } else { + return false; + } + } + + static CompletableFuture> getInventory(InvseeAPI api, Target target, Optional executor) { + final CreationOptions creationOptions = executor.map(player -> api.mainInventoryCreationOptions(player)).orElseGet(() -> api.mainInventoryCreationOptions()); + if (target instanceof PlayerTarget) { + return CompletableFuture.completedFuture(api.mainSpectatorInventory(((PlayerTarget) target).getPlayer(), creationOptions)); + } else if (target instanceof UniqueIdTarget) { + UniqueIdTarget uuidTarget = (UniqueIdTarget) target; + UUID uuid = uuidTarget.getUniqueId(); + CompletableFuture username = api.fetchUserName(uuid).thenApply(o -> o.orElse("InvSee++ Player")).exceptionally(t -> "InvSee++ Player"); + return username.thenCompose(name -> api.mainSpectatorInventory(uuid, name, creationOptions)); + } else if (target instanceof UsernameTarget) { + return api.mainSpectatorInventory(((UsernameTarget) target).getUsername(), creationOptions); + } else { + return CompletableFuture.completedFuture(SpectateResponse.fail(NotCreatedReason.unknownTarget(target))); + } + } + + static CompletableFuture> getEnderChest(InvseeAPI api, Target target, Optional executor) { + final CreationOptions creationOptions = executor.map(player -> api.enderInventoryCreationOptions(player)).orElseGet(() -> api.enderInventoryCreationOptions()); + if (target instanceof PlayerTarget) { + return CompletableFuture.completedFuture(api.enderSpectatorInventory(((PlayerTarget) target).getPlayer(), creationOptions)); + } else if (target instanceof UniqueIdTarget) { + UniqueIdTarget uuidTarget = (UniqueIdTarget) target; + UUID uuid = uuidTarget.getUniqueId(); + CompletableFuture username = api.fetchUserName(uuid).thenApply(o -> o.orElse("InvSee++ Player")).exceptionally(t -> "InvSee++ Player"); + return username.thenCompose(name -> api.enderSpectatorInventory(uuid, name, creationOptions)); + } else if (target instanceof UsernameTarget) { + return api.enderSpectatorInventory(((UsernameTarget) target).getUsername(), creationOptions); + } else { + return CompletableFuture.completedFuture(SpectateResponse.fail(NotCreatedReason.unknownTarget(target))); + } + } +} diff --git a/InvSee++_Clone_Plugin/src/main/resources/plugin.yml b/InvSee++_Clone_Plugin/src/main/resources/plugin.yml new file mode 100644 index 0000000..4bf476b --- /dev/null +++ b/InvSee++_Clone_Plugin/src/main/resources/plugin.yml @@ -0,0 +1,34 @@ +name: InvSeePlusPlus_Clone +version: ${project.version} +main: com.janboerman.invsee.spigot.addon.clone.ClonePlugin +depend: [InvSeePlusPlus] +api-version: 1.13 +prefix: "InvSee++_Clone" +description: Clone player's inventories and enderchests. +folia-supported: false + +permissions: + invseeplusplus.clone.*: + description: Grants all permissions for the InvSee++ Clone addon + children: + - invseeplusplus.clone.inventory + - invseeplusplus.clone.enderchest + default: false + invseeplusplus.clone.inventory: + description: "Allows you to use /invclone" + default: op + invseeplusplus.clone.enderchest: + description: "Allows you to use /enderclone" + default: op + +commands: + invclone: + description: "Clone a(n) (offline) player's inventory to yourself or another player" + usage: / [] + permission: invseeplusplus.clone.inventory + aliases: [inventoryclone, iclone] + enderclone: + description: "Clone a(n) (offline) player's enderchest to yourself or another player" + usage: / [] + permission: invseeplusplus.clone.enderchest + aliases: [enderchestclone, eclone] diff --git a/InvSee++_Common/.gitignore b/InvSee++_Common/.gitignore new file mode 100644 index 0000000..dd34d15 --- /dev/null +++ b/InvSee++_Common/.gitignore @@ -0,0 +1,13 @@ +#IntelliJ +.idea/* +**.iml + +#Maven +target/* + +#Eclipse +**/.settings/* +**/.project +**/.classpath + +/target/ diff --git a/InvSee++_Common/pom.xml b/InvSee++_Common/pom.xml new file mode 100644 index 0000000..75529fb --- /dev/null +++ b/InvSee++_Common/pom.xml @@ -0,0 +1,149 @@ + + + invsee-plus-plus + com.janboerman.invsee + 0.31.11-SNAPSHOT + + 4.0.0 + + invsee-plus-plus_common + InvSee++ Common + + + clean package + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 8 + 17 + true + + + + + org.apache.maven.plugins + maven-shade-plugin + ${maven-shade-plugin.version} + + + package + + shade + + + false + + + + junit:junit + org.hamcrest:hamcrest-core + com.googlecode.json-simple:json-simple + + + + + + + + + + + + + + papermc + https://repo.papermc.io/repository/maven-public/ + + + jitpack.io + https://jitpack.io + + + bungeeperms-repo + https://repo.wea-ondara.net/repository/public/ + + + techscode + https://repo.techscode.com/repository/techscode-apis/ + + + + + + io.papermc.paper + paper-api + 1.21-R0.1-SNAPSHOT + provided + + + com.janboerman.invsee + mojang-api + ${project.version} + provided + + + com.janboerman.invsee + utils + ${project.version} + provided + + + com.github.MilkBowl + VaultAPI + 1.7 + provided + + + + + net.luckperms + api + 5.4 + provided + + + com.github.ElgarL + groupmanager + 2.9 + provided + + + + + + + + + net.alpenblock + BungeePerms + 3.0-dev-80 + system + ${basedir}/../.libs/BungeePerms-3.0-dev-80.jar + + + + + + + + + me.TechsCode + UltraPermissionsAPI + 5.5.2 + system + ${basedir}/../.libs/UltraPermissionsAPI-5.5.2.jar + + + + + org.junit.jupiter + junit-jupiter-api + ${junit.version} + test + + + + \ No newline at end of file diff --git a/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/CreationOptions.java b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/CreationOptions.java new file mode 100644 index 0000000..a79294c --- /dev/null +++ b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/CreationOptions.java @@ -0,0 +1,286 @@ +package com.janboerman.invsee.spigot.api; + +import com.janboerman.invsee.spigot.api.logging.LogGranularity; +import com.janboerman.invsee.spigot.api.logging.LogOptions; +import com.janboerman.invsee.spigot.api.placeholder.PlaceholderPalette; +import com.janboerman.invsee.spigot.api.template.EnderChestSlot; +import com.janboerman.invsee.spigot.api.template.Mirror; +import com.janboerman.invsee.spigot.api.template.PlayerInventorySlot; + +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.Objects; + +/** + * Options used to customise how {@link SpectatorInventory}s are opened. + * @param the spectator inventory slot type. Usually {@link PlayerInventorySlot} or {@link EnderChestSlot}. + */ +//TODO Multi-Release this file such that Deprecated(forRemoval = true) can be used. +public class CreationOptions implements Cloneable { + + private Plugin plugin; + private Title title; + private boolean offlinePlayerSupport = true; + private Mirror mirror; + private boolean unknownPlayerSupport = true; + private boolean bypassExempt = false; //should this be a Predicate? maybe. + private LogOptions logOptions = new LogOptions(); + private PlaceholderPalette placeholderPalette = PlaceholderPalette.empty(); + + //TODO should have a builder api, because api consumers can't keep on using legacy constructors. + + CreationOptions(Plugin plugin, Title title, boolean offlinePlayerSupport, Mirror mirror, boolean unknownPlayerSupport, boolean bypassExempt, LogOptions logOptions, PlaceholderPalette palette) { + this.plugin = plugin; + this.title = Objects.requireNonNull(title); + this.offlinePlayerSupport = offlinePlayerSupport; + this.mirror = Objects.requireNonNull(mirror); + this.unknownPlayerSupport = unknownPlayerSupport; + this.bypassExempt = bypassExempt; + this.logOptions = Objects.requireNonNull(logOptions); + this.placeholderPalette = palette; + } + + /** + * Create new CreationOptions. + * @param plugin the plugin which wants to create the {@linkplain SpectatorInventory} + * @param title the title of the {@linkplain SpectatorInventory} + * @param offlinePlayerSupport whether offline players can be spectated + * @param mirror the mirror which to view items through + * @param unknownPlayerSupport whether unknown players can be spectated + * @param bypassExempt whether exempted players can be spectated + * @param logOptions the logging options used by the created {@link SpectatorInventoryView}. + * @param placeholderPalette the placeholder palette + * @return new creation options + * @param the slot type + */ + public static CreationOptions of(Plugin plugin, Title title, boolean offlinePlayerSupport, Mirror mirror, boolean unknownPlayerSupport, boolean bypassExempt, LogOptions logOptions, PlaceholderPalette placeholderPalette) { + return new CreationOptions<>(plugin, title, offlinePlayerSupport, mirror, unknownPlayerSupport, bypassExempt, logOptions, placeholderPalette); + } + + @Deprecated//(forRemoval = true, since = "0.19.6") + public static CreationOptions of(Title title, boolean offlinePlayerSupport, Mirror mirror, boolean unknownPlayerSupport) throws Exception { + Plugin plugin = JavaPlugin.getPlugin((Class) Class.forName("com.janboerman.invsee.spigot.InvseePlusPlus")); + return new CreationOptions<>(plugin, title, offlinePlayerSupport, mirror, unknownPlayerSupport, false, new LogOptions().withGranularity(LogGranularity.LOG_NEVER), PlaceholderPalette.empty()); + } + + @Deprecated//(forRemoval = true, since = "0.19.6") + public static CreationOptions of(Title title, boolean offlinePlayerSupport, Mirror mirror, boolean unknownPlayerSupport, boolean bypassExempt) throws Exception { + Plugin plugin = JavaPlugin.getPlugin((Class) Class.forName("com.janboerman.invsee.spigot.InvseePlusPlus")); + return new CreationOptions<>(plugin, title, offlinePlayerSupport, mirror, unknownPlayerSupport, bypassExempt, new LogOptions().withGranularity(LogGranularity.LOG_NEVER), PlaceholderPalette.empty()); + } + + @Deprecated//(forRemoval = true, since = "0.22.11") + public static CreationOptions of(Plugin plugin, Title title, boolean offlinePlayerSupport, Mirror mirror, boolean unknownPlayerSupport, boolean bypassExempt, LogOptions logOptions) { + return new CreationOptions<>(plugin, title, offlinePlayerSupport, mirror, unknownPlayerSupport, bypassExempt, logOptions, PlaceholderPalette.empty()); + } + + @Deprecated//(forRemoval = true, since = "0.20.0") + public static CreationOptions defaultMainInventory() { + return defaultMainInventory(Bukkit.getPluginManager().getPlugin("InvseePlusPlus")); + } + + /** + * Get default creation options + * @param plugin the plugin which wants to create {@linkplain MainSpectatorInventory}s. + * @return new creation options + */ + public static CreationOptions defaultMainInventory(Plugin plugin) { + return new CreationOptions<>(plugin, Title.defaultMainInventory(), true, Mirror.defaultPlayerInventory(), true, false, new LogOptions(), PlaceholderPalette.empty()); + } + + @Deprecated//(forRemoval = true, since = "0.20.0") + public static CreationOptions defaultEnderInventory() { + return defaultEnderInventory(Bukkit.getPluginManager().getPlugin("InvseePlusPlus")); + } + + /** + * Get default creation options + * @param plugin the plugin which wants to create {@linkplain EnderSpectatorInventory}s. + * @return new creation options + */ + public static CreationOptions defaultEnderInventory(Plugin plugin) { + return new CreationOptions<>(plugin, Title.defaultEnderInventory(), true, Mirror.defaultEnderChest(), true, false, new LogOptions(), PlaceholderPalette.empty()); + } + + /** + * Creates a deep copy of these creation options. + * @return new creation options with the same configured values as this one + */ + @Override + public CreationOptions clone() { + return new CreationOptions<>(getPlugin(), getTitle(), isOfflinePlayerSupported(), getMirror(), isUnknownPlayerSupported(), canBypassExemptedPlayers(), getLogOptions().clone(), getPlaceholderPalette()); + } + + /** + * Set the plugin. + * @param plugin the plugin + * @return this + */ + public CreationOptions withPlugin(Plugin plugin) { + this.plugin = Objects.requireNonNull(plugin, "plugin cannot be null"); + return this; + } + + /** + * Set the title. + * @param title the title + * @return this + */ + public CreationOptions withTitle(Title title) { + this.title = Objects.requireNonNull(title, "title cannot be null"); + return this; + } + + /** + * Set the title. + * @param title the title + * @return this + */ + public CreationOptions withTitle(String title) { + return withTitle(Title.of(title)); + } + + /** + * Set offline player support. + * @param offlinePlayerSupport true if offline players must be able to be spectated, otherwise false + * @return this + */ + public CreationOptions withOfflinePlayerSupport(boolean offlinePlayerSupport) { + this.offlinePlayerSupport = offlinePlayerSupport; + return this; + } + + /** + * Set the mirror. + * @param mirror the mirror + * @return this + */ + public CreationOptions withMirror(Mirror mirror) { + this.mirror = Objects.requireNonNull(mirror, "mirror cannot be null"); + return this; + } + + /** + * Set unknown player support. + * @param unknownPlayerSupport true if players who have not played on the server before must be able to be spectated, otherwise false + * @return this + */ + public CreationOptions withUnknownPlayerSupport(boolean unknownPlayerSupport) { + this.unknownPlayerSupport = unknownPlayerSupport; + return this; + } + + /** + * Set exemption bypass. + * @param bypassExemptedPlayers true if exempted players can still be spectated, false if exempted players cannot be spectated + * @return this + */ + public CreationOptions withBypassExemptedPlayers(boolean bypassExemptedPlayers) { + this.bypassExempt = bypassExemptedPlayers; + return this; + } + + /** + * Set the logging options. + * @param logOptions the logging options + * @return this + */ + public CreationOptions withLogOptions(LogOptions logOptions) { + this.logOptions = Objects.requireNonNull(logOptions, "logOptions cannot be null"); + return this; + } + + /** + * Set the placeholder palette. + * @param placeholderPalette the placeholder palette + * @return this + */ + public CreationOptions withPlaceholderPalette(PlaceholderPalette placeholderPalette) { + this.placeholderPalette = placeholderPalette; + return this; + } + + @Override + public boolean equals(Object o) { + if (o == this) return true; + if (!(o instanceof CreationOptions)) return false; + + CreationOptions that = (CreationOptions) o; + return this.getPlugin().equals(that.getPlugin()) + && this.getTitle().equals(that.getTitle()) + && this.isOfflinePlayerSupported() == that.isOfflinePlayerSupported() + && this.getMirror() == that.getMirror() + && this.isUnknownPlayerSupported() == that.isUnknownPlayerSupported() + && this.canBypassExemptedPlayers() == that.canBypassExemptedPlayers() + && Objects.equals(this.getLogOptions(), that.getLogOptions()) + && Objects.equals(this.getPlaceholderPalette(), that.getPlaceholderPalette()); + } + + @Override + public int hashCode() { + return Objects.hash(getPlugin(), getTitle(), isOfflinePlayerSupported(), getMirror(), isUnknownPlayerSupported(), getLogOptions(), getPlaceholderPalette()); + } + + @Override + public String toString() { + return "CreationOptions" + + "{plugin=" + getPlugin() + + ",title=" + getTitle() + + ",offlinePlayerSupport=" + isOfflinePlayerSupported() + + ",mirror=" + getMirror() + + ",unknownPlayerSupport=" + isUnknownPlayerSupported() + + ",bypassExempt=" + canBypassExemptedPlayers() + + ",logOptions=" + getLogOptions() + + ",placeholderPalette=" + getPlaceholderPalette() + + "}"; + } + + /** Get the configured plugin. */ + public Plugin getPlugin() { + if (plugin == null) { + try { + plugin = JavaPlugin.getPlugin((Class) Class.forName("com.janboerman.invsee.spigot.InvseePlusPlus")); + } catch (ClassNotFoundException e) { + throw new RuntimeException("Woops, I screwed up severely. Please report this issue (including stack trace) at https://github.com/Jannyboy11/InvSee-plus-plus", e); + } + } + return plugin; + } + + /** Get the configured title. */ + public Title getTitle() { + return title; + } + + /** Get the configured support for offline players. */ + public boolean isOfflinePlayerSupported() { + return offlinePlayerSupport; + } + + /** Get the configured mirror. */ + public Mirror getMirror() { + return mirror; + } + + /** Get the configured support for unknown players. */ + public boolean isUnknownPlayerSupported() { + return unknownPlayerSupport; + } + + /** Get whether exempted players can still be spectated. */ + public boolean canBypassExemptedPlayers() { + return bypassExempt; + } + + /** Get the logging options */ + public LogOptions getLogOptions() { + return logOptions; + } + + /** Get the placeholder palette */ + public PlaceholderPalette getPlaceholderPalette() { + return placeholderPalette; + } +} diff --git a/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/EnderSpectatorInventory.java b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/EnderSpectatorInventory.java new file mode 100644 index 0000000..572d11c --- /dev/null +++ b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/EnderSpectatorInventory.java @@ -0,0 +1,33 @@ +package com.janboerman.invsee.spigot.api; + +import com.janboerman.invsee.spigot.api.template.EnderChestSlot; +import com.janboerman.invsee.spigot.api.template.Mirror; +import org.bukkit.inventory.ItemStack; + +/** + * The spectator inventory that contains all enderchest items + */ +public interface EnderSpectatorInventory extends SpectatorInventory { + + /** Get the mirror this inventory is viewed through. */ + @Override + public default Mirror getMirror() { + return getCreationOptions().getMirror(); + } + + /** Set the contents of this inventory based on the contents from the provided inventory. */ + public default void setContents(EnderSpectatorInventory newContents) { + setContents(newContents.getContents()); + } + + @Override + public default void setStorageContents(ItemStack[] newContents) { + setContents(newContents); + } + + @Override + public default ItemStack[] getStorageContents() { + return getContents(); + } + +} diff --git a/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/EnderSpectatorInventoryView.java b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/EnderSpectatorInventoryView.java new file mode 100644 index 0000000..96da8e3 --- /dev/null +++ b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/EnderSpectatorInventoryView.java @@ -0,0 +1,24 @@ +package com.janboerman.invsee.spigot.api; + +import com.janboerman.invsee.spigot.api.template.EnderChestSlot; + +import org.bukkit.event.inventory.InventoryType; + +/** + * Represents an open window for an {@link EnderSpectatorInventory}. + */ +public interface EnderSpectatorInventoryView extends SpectatorInventoryView { + + /** {@inheritDoc} */ + @Override + public EnderSpectatorInventory getTopInventory(); + + /** + * Get the inventory type. + * @return the inventory type + */ + public default InventoryType getType() { + return InventoryType.CHEST; + } + +} diff --git a/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/Exempt.java b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/Exempt.java new file mode 100644 index 0000000..3afc88f --- /dev/null +++ b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/Exempt.java @@ -0,0 +1,108 @@ +package com.janboerman.invsee.spigot.api; + +import com.janboerman.invsee.spigot.api.target.PlayerTarget; +import com.janboerman.invsee.spigot.api.target.Target; +import com.janboerman.invsee.spigot.api.target.UniqueIdTarget; +import com.janboerman.invsee.spigot.api.target.UsernameTarget; +import net.milkbowl.vault.permission.Permission; +import org.bukkit.Server; +import org.bukkit.plugin.RegisteredServiceProvider; +import org.bukkit.plugin.ServicesManager; + +import java.util.Objects; +import java.util.UUID; + +public class Exempt { + + private static final String EXEMPT_INVENTORY = "invseeplusplus.exempt.invsee"; + private static final String EXEMPT_ENDERCHEST = "invseeplusplus.exempt.endersee"; + public static final String BYPASS_EXEMPT_INVENTORY = "invseeplusplus.bypass-exempt.invsee"; + public static final String BYPASS_EXEMPT_ENDERCHEST = "invseeplusplus.bypass-exempt.endersee"; + + private Server server; + + private Permission permission; + + Exempt(Server server) { + this.server = Objects.requireNonNull(server); + + if (server.getPluginManager().isPluginEnabled("Vault")) { + ServicesManager servicesManager = server.getServicesManager(); + RegisteredServiceProvider provider = servicesManager.getRegistration(Permission.class); + if (provider != null) { + permission = provider.getProvider(); + } + } + } + + private boolean vaultPermissionEnabled() { + return permission != null && permission.isEnabled(); + } + + public boolean isExemptedFromHavingMainInventorySpectated(Target target) { + return isExempted(target, EXEMPT_INVENTORY); + } + + public boolean isExemptedFromHavingEnderchestSpectated(Target target) { + return isExempted(target, EXEMPT_ENDERCHEST); + } + + private boolean isExempted(Target target, String permission) { + if (target instanceof PlayerTarget) { + return ((PlayerTarget) target).getPlayer().hasPermission(permission); + } + + if (vaultPermissionEnabled()) { + if (target instanceof UniqueIdTarget) { + return vaultHasPermission(((UniqueIdTarget) target).getUniqueId(), permission); + } else if (target instanceof UsernameTarget) { + return vaultHasPermission(((UsernameTarget) target).getUsername(), permission); + } + } + + return false; + } + + private boolean vaultHasPermission(UUID uniqueId, String permission) { + return this.permission.playerHas(server.getWorlds().get(0).getName(), server.getOfflinePlayer(uniqueId), permission); + } + + @Deprecated + private boolean vaultHasPermission(String username, String permission) { + return this.permission.playerHas(server.getWorlds().get(0).getName(), username, permission); + } + + private boolean vaultHasPermission(UUID uniqueId, String world, String permission) { + return this.permission.playerHas(world, server.getOfflinePlayer(uniqueId), permission); + } + + @Deprecated + private boolean vaultHasPermission(String username, String world, String permission) { + return this.permission.playerHas(world, username, permission); + } + + public boolean isExemptedFromHavingMainInventorySpectated(Target target, String world) { + return isExempted(target, world, EXEMPT_INVENTORY); + } + + public boolean isExemptedFromHavingEnderchestSpectated(Target target, String world) { + return isExempted(target, world, EXEMPT_ENDERCHEST); + } + + private boolean isExempted(Target target, String world, String permission) { + if (target instanceof PlayerTarget) { + return ((PlayerTarget) target).getPlayer().hasPermission(permission); + } + + if (vaultPermissionEnabled()) { + if (target instanceof UniqueIdTarget) { + return vaultHasPermission(((UniqueIdTarget) target).getUniqueId(), world, permission); + } else if (target instanceof UsernameTarget) { + return vaultHasPermission(((UsernameTarget) target).getUsername(), world, permission); + } + } + + return false; + } + +} diff --git a/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/InvseeAPI.java b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/InvseeAPI.java new file mode 100644 index 0000000..597e61c --- /dev/null +++ b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/InvseeAPI.java @@ -0,0 +1,1282 @@ +package com.janboerman.invsee.spigot.api; + +import java.util.*; +import java.util.concurrent.*; +import java.util.function.*; +import java.util.logging.Level; + +import com.janboerman.invsee.spigot.api.logging.*; +import com.janboerman.invsee.spigot.api.placeholder.PlaceholderPalette; +import com.janboerman.invsee.spigot.api.response.*; +import com.janboerman.invsee.spigot.api.target.Target; +import com.janboerman.invsee.spigot.api.template.*; +import com.janboerman.invsee.spigot.internal.InvseePlatform; +import com.janboerman.invsee.spigot.internal.NamesAndUUIDs; +import com.janboerman.invsee.spigot.internal.OpenSpectatorsCache; +import com.janboerman.invsee.spigot.internal.inventory.ShallowCopy; +import com.janboerman.invsee.spigot.internal.inventory.Personal; +import com.janboerman.invsee.utils.*; +import org.bukkit.*; +import org.bukkit.entity.*; +import org.bukkit.event.*; +import org.bukkit.event.inventory.*; +import org.bukkit.event.player.*; +import org.bukkit.inventory.*; +import org.bukkit.plugin.*; + +/** + * InvSee++'s api main entrypoint. Instance can be obtained via: + *
+ * 
+ * InvseePlusPlus plugin = (InvseePlusPlus) Bukkit.getPluginManager().getPlugin("InvSeePlusPlus");
+ * InvseeAPI api = plugin.getApi();
+ * 
+ * 
+ */ +public class InvseeAPI { + + /* + * TODO later, we could also return an InvseeAPI instance PER PLUGIN. <-- That is going to be annoying with event listeners though. + * TODO this is useful for logging, now that we have the PLUGIN_LOG_FILE. + * TODO so, maybe the InvSeePlusPlus plugin does the event stuff, that way we can create multiple api instances (with shared NamesAndUUIDs as well as the Scheduler) + */ + + protected final Plugin plugin; + protected final InvseePlatform platform; + protected final NamesAndUUIDs lookup; + protected final OpenSpectatorsCache openSpectatorsCache; + protected final Exempt exempt; + + private Title mainInventoryTitle = target -> target.toString() + "'s inventory"; + private Title enderInventoryTitle = target -> target.toString() + "'s enderchest"; + + private boolean offlinePlayerSupport = true; + private boolean unknownPlayerSupport = true; + + protected Mirror inventoryMirror = Mirror.defaultPlayerInventory(); + protected Mirror enderchestMirror = Mirror.defaultEnderChest(); + + private LogOptions logOptions = new LogOptions(); + private PlaceholderPalette placeholderPalette = PlaceholderPalette.empty(); + + private final Map>> pendingInventoriesByName = Collections.synchronizedMap(new CaseInsensitiveMap<>()); + private final Map>> pendingInventoriesByUuid = new ConcurrentHashMap<>(); + + private final Map>> pendingEnderChestsByName = Collections.synchronizedMap(new CaseInsensitiveMap<>()); + private final Map>> pendingEnderChestsByUuid = new ConcurrentHashMap<>(); + + //TODO I don't like the design of this. This looks like a hack purely introduced for PerWorldInventory integration + //TODO maybe we can create a proper abstraction and use that for Multiverse-Inventories / MyWorlds? + //TODO See https://github.com/Jannyboy11/InvSee-plus-plus/issues/71 + private BiPredicate transferInvToLivePlayer = (spectatorInv, player) -> true; + private BiPredicate transferEnderToLivePlayer = (spectatorInv, player) -> true; + + private final Scheduler scheduler; + /** @deprecated use {@link #getScheduler()} instead */ + @Deprecated/*(forRemoval = true, since = "0.20.0")*/ public final Executor serverThreadExecutor; + /** @deprecated use {@link #getScheduler()} instead */ + @Deprecated/*(forRemoval = true, since = "0.20.0")*/ public final Executor asyncExecutor; + + protected final PlayerListener playerListener = new PlayerListener(); + protected final InventoryListener inventoryListener = new InventoryListener(); + + /** @deprecated internal api */ + public InvseeAPI(Plugin plugin, InvseePlatform platform, NamesAndUUIDs lookup, Scheduler scheduler, OpenSpectatorsCache openSpectatorsCache) { + this.plugin = Objects.requireNonNull(plugin); + + this.lookup = Objects.requireNonNull(lookup); + this.platform = Objects.requireNonNull(platform == null ? getPlatform() : platform); + this.scheduler = Objects.requireNonNull(scheduler); + this.openSpectatorsCache = Objects.requireNonNull(openSpectatorsCache); + this.exempt = new Exempt(plugin.getServer()); + + registerListeners(); + + this.serverThreadExecutor = scheduler::executeSyncGlobal; + this.asyncExecutor = scheduler::executeAsync; + } + + /** @apiNote unstable api */ + public Scheduler getScheduler() { + return scheduler; + } + + @Deprecated //TODO refactor/remove this. + protected InvseePlatform getPlatform() { + return platform; + } + + /** Called when InvSee++ disables. DO NOT CALL! */ + public void shutDown() { + //complete futures. needed to ensure changes are saved. + for (CompletableFuture> future : pendingInventoriesByUuid.values()) + try { future.join(); } catch (Throwable e) { e.printStackTrace(); } + for (CompletableFuture> future : pendingEnderChestsByUuid.values()) + try { future.join(); } catch (Throwable e) { e.printStackTrace(); } + + //clean up logger resources + LogOutput.closeGlobal(); + } + + /** Get the known mappings from players' usernames to unique IDs. */ + public Map getUuidCache() { + return lookup.getUuidCache(); + } + + /** Get the known mappings from players' unique IDs to usernames. */ + public Map getUserNameCache() { + return lookup.getUserNameCache(); + } + + /** @deprecated Unstable api*/ + @Deprecated + public final NamesAndUUIDs namesAndUuidsLookup() { + return lookup; + } + + //TODO un-hack this registerListeners thing. + //TODO should I make a protected constructor that takes a delegate InvseeAPI as a parameter? + + /** @deprecated internal api, subject to change */ + public void registerListeners() { + PluginManager pluginManager = plugin.getServer().getPluginManager(); + pluginManager.registerEvents(playerListener, plugin); + pluginManager.registerEvents(inventoryListener, plugin); + } + + /** @deprecated internal api, subject to change */ + public void unregisterListeners() { + HandlerList.unregisterAll(playerListener); + HandlerList.unregisterAll(inventoryListener); + } + + + // ========= creation options ========= + + /** Set the offline player support status for {@link #mainInventoryCreationOptions()} and {@link #enderInventoryCreationOptions()}. */ + public final void setOfflinePlayerSupport(boolean offlinePlayerSupport) { + this.offlinePlayerSupport = offlinePlayerSupport; + } + + /** Set the unknown player support status for {@link #mainInventoryCreationOptions()} and {@link #enderInventoryCreationOptions()}. */ + public final void setUnknownPlayerSupport(boolean unknownPlayerSupport) { + this.unknownPlayerSupport = unknownPlayerSupport; + } + + /** Get whether the CreationOptions returned by {@link #mainInventoryCreationOptions()} and {@link #enderInventoryCreationOptions()} + * will support spectating offline players. */ + public final boolean offlinePlayerSupport() { + return this.offlinePlayerSupport; + } + /** Get whether the CreationOptions returned by {@link #mainInventoryCreationOptions()} and {@link #enderInventoryCreationOptions()} + * will support spectating unknown players. */ + public final boolean unknownPlayerSupport() { + return this.unknownPlayerSupport; + } + + /** Set the {@link Title} to be used by {@link #mainInventoryCreationOptions()}. */ + public final void setMainInventoryTitle(Title title) { + Objects.requireNonNull(title); + this.mainInventoryTitle = title; + } + + /** Set the {@link Title} to be used by {@link #enderInventoryCreationOptions()}. */ + public final void setEnderInventoryTitle(Title title) { + Objects.requireNonNull(title); + this.enderInventoryTitle = title; + } + + /** Set the {@link Mirror} to be used by {@link #mainInventoryCreationOptions()}. */ + public final void setMainInventoryMirror(Mirror mirror) { + Objects.requireNonNull(mirror); + this.inventoryMirror = mirror; + } + + /** Set the {@link Mirror} to be used by {@link #enderInventoryCreationOptions()}. */ + public final void setEnderInventoryMirror(Mirror mirror) { + Objects.requireNonNull(mirror); + this.enderchestMirror = mirror; + } + + /** Set the {@link LogOptions} to be used by {@link #mainInventoryCreationOptions()} and {@link #enderInventoryCreationOptions()}. */ + public final void setLogOptions(LogOptions options) { + Objects.requireNonNull(options); + this.logOptions = options.clone(); + } + + /** Set the {@link PlaceholderPalette} that will be used for placeholders for absent items in non-container slots. */ + public final void setPlaceholderPalette(PlaceholderPalette palette) { + Objects.requireNonNull(palette); + this.placeholderPalette = palette; + } + + /** + * Get the configured CreationOptions for {@link MainSpectatorInventory}s. + * @param spectator the spectating player + * @return the creation options + */ + public CreationOptions mainInventoryCreationOptions(Player spectator) { + final boolean bypassExempt = spectator.hasPermission(Exempt.BYPASS_EXEMPT_INVENTORY); + return new CreationOptions<>(plugin, mainInventoryTitle, offlinePlayerSupport, inventoryMirror, unknownPlayerSupport, bypassExempt, logOptions.clone(), placeholderPalette); + } + + /** + * Get the configured CreationOptions for {@link EnderSpectatorInventory}s. + * @param spectator the spectating player + * @return the creation options + */ + public CreationOptions enderInventoryCreationOptions(Player spectator) { + final boolean bypassExempt = spectator.hasPermission(Exempt.BYPASS_EXEMPT_ENDERCHEST); + return new CreationOptions<>(plugin, enderInventoryTitle, offlinePlayerSupport, enderchestMirror, unknownPlayerSupport, bypassExempt, logOptions.clone(), placeholderPalette); + } + + /** + * Get the configured CreationOptions for {@link MainSpectatorInventory}s. + * These creation options will always bypass the target's exemption status. + * @return the creation options + */ + public CreationOptions mainInventoryCreationOptions() { + return new CreationOptions<>(plugin, mainInventoryTitle, offlinePlayerSupport, inventoryMirror, unknownPlayerSupport, false, logOptions.clone(), placeholderPalette); + } + + /** + * Get the configured CreationOptions for {@link EnderSpectatorInventory}s. + * These creation options will always bypass the target's exemption status. + * @return the creation options + */ + public CreationOptions enderInventoryCreationOptions() { + return new CreationOptions<>(plugin, enderInventoryTitle, offlinePlayerSupport, enderchestMirror, unknownPlayerSupport, false, logOptions.clone(), placeholderPalette); + } + + // ========= end of creation options ========= + + + // ============== internal apis ============== + + /** @deprecated internal api */ + //TODO I don't like the design of this. + public final void setMainInventoryTransferPredicate(BiPredicate bip) { + Objects.requireNonNull(bip); + this.transferInvToLivePlayer = bip; + } + + /** @deprecated internal api */ + //TODO I don't like the design of this. + public final void setEnderChestTransferPredicate(BiPredicate bip) { + Objects.requireNonNull(bip); + this.transferEnderToLivePlayer = bip; + } + + /** Get a cached {@link MainSpectatorInventory} for the target player. + * @deprecated internal api */ + @Deprecated + public Optional getOpenMainSpectatorInventory(UUID player) { + return Optional.ofNullable(openSpectatorsCache.getMainSpectatorInventory(player)); + } + + /** Get a cached {@link EnderSpectatorInventory} for the target player. + * @deprecated internal api */ + @Deprecated + public Optional getOpenEnderSpectatorInventory(UUID player) { + return Optional.ofNullable(openSpectatorsCache.getEnderSpectatorInventory(player)); + } + + /** Fetches the unique ID of the player with the provided username. + * @see NamesAndUUIDs */ + public final CompletableFuture> fetchUniqueId(String userName) { + return lookup.resolveUUID(userName).thenApplyAsync(Function.identity(), scheduler::executeSyncGlobal); + } + + /** Fetches the username of the player with the provided unique ID. + * @see NamesAndUUIDs */ + public final CompletableFuture> fetchUserName(UUID uniqueId) { + return lookup.resolveUserName(uniqueId).thenApplyAsync(Function.identity(), scheduler::executeSyncGlobal); + } + + /** @deprecated internal api */ + @Deprecated//(forRemoval = true, since = "0.25.2") + protected void cache(MainSpectatorInventory spectatorInventory) { + openSpectatorsCache.cache(spectatorInventory, false); + } + + /** @deprecated internal api */ + @Deprecated//(forRemoval = true, since = "0.25.2") + protected void cache(MainSpectatorInventory spectatorInventory, boolean force) { + openSpectatorsCache.cache(spectatorInventory, force); + } + + /** @deprecated internal api */ + @Deprecated//(forRemoval = true, since = "0.25.2") + protected void cache(EnderSpectatorInventory spectatorInventory) { + openSpectatorsCache.cache(spectatorInventory); + } + + /** @deprecated internal api */ + @Deprecated//(forRemoval = true, since = "0.25.2") + protected void cache(EnderSpectatorInventory spectatorInventory, boolean force) { + openSpectatorsCache.cache(spectatorInventory, force); + } + + // =========== end of internal apis =========== + + + // ================================== API methods: Main Inventory ================================== + + /** + * Save the target player's inventory contents to his/her player data file. + * @param inventory the inventory contents + * @return a future which completes once the contents is saved + */ + //TODO make this final. + public CompletableFuture saveInventory(MainSpectatorInventory inventory) { + return platform.saveInventory(inventory); + } + + // HumanEntity + + /** + * Opens a {@link MainSpectatorInventory} for a player. + * @param spectator the spectating player + * @param target the target player + * @param options the creation options + * @return an {@link OpenResponse} which, if successful, gives access to an {@link MainSpectatorInventoryView} which represents the open window + */ + public final OpenResponse spectateInventory(Player spectator, HumanEntity target, CreationOptions options) { + SpectateResponse response = mainSpectatorInventory(target, options); + if (response.isSuccess()) { + return platform.openMainSpectatorInventory(spectator, response.getInventory(), options); + } else { + return OpenResponse.closed(NotOpenedReason.notCreated(response.getReason())); + } + } + + /** + * Create a {@link MainSpectatorInventory} which will provide access to the inventory contents of a target player. + * @param target the target player + * @return a {@link SpectateResponse} which, if successful, will give access to the {@link MainSpectatorInventory} + */ + public final SpectateResponse mainSpectatorInventory(HumanEntity target) { + return mainSpectatorInventory(target, mainInventoryCreationOptions()); + } + + /** + * Create a {@link MainSpectatorInventory} which will provide access to the inventory contents of a target player. + * @param target the target player + * @param options the creation options + * @return a {@link SpectateResponse} which, if successful, will give access to the {@link MainSpectatorInventory} + */ + public final SpectateResponse mainSpectatorInventory(HumanEntity target, CreationOptions options) { + Target theTarget = Target.byPlayer(target); + if (!options.canBypassExemptedPlayers() && exempt.isExemptedFromHavingMainInventorySpectated(theTarget)) { + return SpectateResponse.fail(NotCreatedReason.targetHasExemptPermission(theTarget)); + } else { + MainSpectatorInventory inv = platform.spectateInventory(target, options); + openSpectatorsCache.cache(inv); + return SpectateResponse.succeed(inv); + } + } + + // UserName + + /** + * Opens a {@link MainSpectatorInventory} for a player. + * @param spectator the spectating player + * @param targetName the name of the target player + * @param options the creation options + * @return a future which will complete with an {@link OpenResponse} which, if successful, gives access to an {@link MainSpectatorInventoryView} which represents the open window + */ + public final CompletableFuture> spectateInventory(Player spectator, String targetName, CreationOptions options) { + return spectateInventory(spectator, mainSpectatorInventory(targetName, options), options); + } + + /** + * Create a {@link MainSpectatorInventory} which will provide access to the inventory contents of a target player. + * @param targetName the username of the target player + * @return a future which will complete with a {@link SpectateResponse} which, if successful, will give access to the {@link MainSpectatorInventory} + */ + public final CompletableFuture> mainSpectatorInventory(String targetName) { + return mainSpectatorInventory(targetName, mainInventoryCreationOptions()); + } + + /** + * Create a {@link MainSpectatorInventory} which will provide access to the inventory contents of a target player. + * @param targetName the username of the target player + * @param options the creation options + * @return a future which will complete with a {@link SpectateResponse} which, if successful, will give access to the {@link MainSpectatorInventory} + */ + public final CompletableFuture> mainSpectatorInventory(String targetName, CreationOptions options) { + Objects.requireNonNull(targetName, "targetName cannot be null!"); + Objects.requireNonNull(options, "options cannot be null!"); + + //try online + final Player targetPlayer = plugin.getServer().getPlayerExact(targetName); + Target target; + if (targetPlayer != null) { + target = Target.byPlayer(targetPlayer); + if (!options.canBypassExemptedPlayers() && exempt.isExemptedFromHavingMainInventorySpectated(target)) + return CompletableFuture.completedFuture(SpectateResponse.fail(NotCreatedReason.targetHasExemptPermission(target))); + + MainSpectatorInventory spectatorInventory = platform.spectateInventory(targetPlayer, options); + UUID uuid = targetPlayer.getUniqueId(); + lookup.cacheNameAndUniqueId(uuid, targetName); + openSpectatorsCache.cache(spectatorInventory); + return CompletableFuture.completedFuture(SpectateResponse.succeed(spectatorInventory)); + } else if (!options.isOfflinePlayerSupported()) { + return CompletableFuture.completedFuture(SpectateResponse.fail(NotCreatedReason.offlineSupportDisabled())); + } + + target = Target.byUsername(targetName); + + final CompletableFuture isExemptedFuture; + if (options.canBypassExemptedPlayers()) { + isExemptedFuture = CompletableFuture.completedFuture(false); + } else if (plugin.getServer().getPluginManager().isPluginEnabled("LuckPerms")) { + // Work around a LuckPerms bug where it can't perform a permission check for players who haven't logged into the server yet, + // because it tries to find the player's UUID in its database. How silly - it could just return whether the default group has that permission or not. + // See: https://www.spigotmc.org/threads/invsee.456148/page-5#post-4371623 + isExemptedFuture = CompletableFuture.completedFuture(false); + } else { + isExemptedFuture = CompletableFuture.supplyAsync(() -> exempt.isExemptedFromHavingMainInventorySpectated(target), scheduler::executeAsync); + } + + final CompletableFuture> uuidFuture = fetchUniqueId(targetName); + + final CompletableFuture> combinedFuture = isExemptedFuture.thenCompose(isExempted -> { + if (isExempted) { + return CompletableFuture.completedFuture(Either.left(NotCreatedReason.targetHasExemptPermission(target))); + } else { + return uuidFuture.thenApply(optionalUuid -> { + if (optionalUuid.isPresent()) { + return Either.right(optionalUuid.get()); + } else { + return Either.left(NotCreatedReason.targetDoesNotExists(target)); + } + }); + } + }); + + //map to SpectateResponse + final CompletableFuture> future = combinedFuture.thenCompose(eitherReasonOrUuid -> { + if (eitherReasonOrUuid.isRight()) { + UUID uuid = eitherReasonOrUuid.getRight(); + return mainSpectatorInventory(uuid, targetName, options); + } else { + NotCreatedReason reason = eitherReasonOrUuid.getLeft(); + return CompletableFuture.completedFuture(SpectateResponse.fail(reason)); + } + }); + pendingInventoriesByName.put(targetName, future); + future.whenComplete((result, error) -> pendingInventoriesByName.remove(targetName)); + return future; + } + + // UUID + + /** + * Opens a {@link MainSpectatorInventory} for a player. + * @param spectator the spectating player + * @param targetId the unique ID of the target player + * @param targetName the name of the target player + * @param options the creation options + * @return a future which will complete with an {@link OpenResponse} which, if successful, gives access to an {@link MainSpectatorInventoryView} which represents the open window + */ + public final CompletableFuture> spectateInventory(Player spectator, UUID targetId, String targetName, CreationOptions options) { + return spectateInventory(spectator, mainSpectatorInventory(targetId, targetName, options), options); + } + + /** + * Create a {@link MainSpectatorInventory} which will provide access to the inventory contents of a target player. + * @param playerId the unique ID of the target player + * @param playerName the username of the target player + * @return a future which will complete with a {@link SpectateResponse} which, if successful, will give access to the {@link MainSpectatorInventory} + */ + public final CompletableFuture> mainSpectatorInventory(UUID playerId, String playerName) { + return mainSpectatorInventory(playerId, playerName, mainInventoryCreationOptions()); + } + + /** + * Create a {@link MainSpectatorInventory} which will provide access to the inventory contents of a target player. + * @param playerId the unique ID of the target player + * @param playerName the username of the target player + * @param options the creation options + * @return a future which will complete with a {@link SpectateResponse} which, if successful, will give access to the {@link MainSpectatorInventory} + */ + public final CompletableFuture> mainSpectatorInventory(UUID playerId, String playerName, CreationOptions options) { + Objects.requireNonNull(playerId, "player UUID cannot be null!"); + Objects.requireNonNull(playerName, "player name cannot be null!"); + Objects.requireNonNull(options, "creation options cannot be null!"); + + final Target gameProfileTarget = Target.byGameProfile(playerId, playerName); + final String title = options.getTitle().titleFor(gameProfileTarget); + final Mirror mirror = options.getMirror(); + final boolean offlineSupport = options.isOfflinePlayerSupported(); + + //try online + Player targetPlayer = plugin.getServer().getPlayer(playerId); + Target target; + if (targetPlayer != null) { + target = Target.byPlayer(targetPlayer); + if (!options.canBypassExemptedPlayers() && exempt.isExemptedFromHavingMainInventorySpectated(target)) + return CompletableFuture.completedFuture(SpectateResponse.fail(NotCreatedReason.targetHasExemptPermission(target))); + + MainSpectatorInventory spectatorInventory = spectateInventory(targetPlayer, title, mirror); + lookup.cacheNameAndUniqueId(playerId, playerName); + openSpectatorsCache.cache(spectatorInventory); + return CompletableFuture.completedFuture(SpectateResponse.succeed(spectatorInventory)); + } else if (!offlineSupport) { + return CompletableFuture.completedFuture(SpectateResponse.fail(NotCreatedReason.offlineSupportDisabled())); + } + + target = gameProfileTarget; + final CompletableFuture isExemptedFuture; + if (options.canBypassExemptedPlayers()) { + isExemptedFuture = CompletableFuture.completedFuture(false); + } else { + //make LuckPerms happy by doing the permission lookup async. I am not sure how well other permission plugins handle this, but everybody uses LuckPerms nowadays so... + isExemptedFuture = CompletableFuture.supplyAsync(() -> exempt.isExemptedFromHavingMainInventorySpectated(target), scheduler::executeAsync); + } + + final CompletableFuture> reasonFuture = isExemptedFuture.thenApply(isExempted -> { + if (isExempted) { + return Optional.of(NotCreatedReason.targetHasExemptPermission(target)); + } else { + return Optional.empty(); + } + }); + + //I really need monad transformers to make this cleaner. + final CompletableFuture> combinedFuture = reasonFuture.thenCompose(maybeReason -> { + if (maybeReason.isPresent()) { + return CompletableFuture.completedFuture(SpectateResponse.fail(maybeReason.get())); + } else { + //try cache + MainSpectatorInventory alreadyOpen = openSpectatorsCache.getMainSpectatorInventory(playerId); + if (alreadyOpen != null) { + return CompletableFuture.completedFuture(SpectateResponse.succeed(alreadyOpen)); + } + + //not in cache: create offline inventory + return platform.createOfflineInventory(playerId, playerName, options); + } + }); + + //map to SpectateResponse and cache if success + CompletableFuture> future = combinedFuture.>thenApply(eitherReasonOrInventory -> { + eitherReasonOrInventory.ifSuccess(openSpectatorsCache::cache); + return eitherReasonOrInventory; + }).handleAsync((success, error) -> { + if (error == null) return success; + return Rethrow.unchecked(error); + }, runnable -> scheduler.executeSyncPlayer(playerId, runnable, null)); + pendingInventoriesByUuid.put(playerId, future); + future.whenComplete((result, error) -> pendingInventoriesByUuid.remove(playerId)); + return future; + } + + // ================================== API methods: Enderchest ================================== + + /** + * Save the target player's ender chest contents to his/her player data file. + * @param enderChest the ender chest contents + * @return a future which completes once the contents is saved + */ + //TODO make this final (requires restructure: composition over inheritance)... + public CompletableFuture saveEnderChest(EnderSpectatorInventory enderChest) { + return platform.saveEnderChest(enderChest); + } + + // HumanEntity + + /** + * Opens an {@link EnderSpectatorInventory} for a player. + * @param spectator the spectating player + * @param target the target player + * @param options the creation options + * @return an {@link OpenResponse} which, if successful, gives access to an {@link EnderSpectatorInventoryView} which represents the open window + */ + public final OpenResponse spectateEnderChest(Player spectator, HumanEntity target, CreationOptions options) { + SpectateResponse response = enderSpectatorInventory(target, options); + if (response.isSuccess()) { + return platform.openEnderSpectatorInventory(spectator, response.getInventory(), options); + } else { + return OpenResponse.closed(NotOpenedReason.notCreated(response.getReason())); + } + } + + /** + * Create an {@link EnderSpectatorInventory} which will provide access to the ender chest contents of a target player. + * @param target the target player + * @return a {@link SpectateResponse} which, if successful, will give access to the {@link EnderSpectatorInventory} + */ + public final SpectateResponse enderSpectatorInventory(HumanEntity target) { + return enderSpectatorInventory(target, enderInventoryCreationOptions()); + } + + /** + * Create an {@link EnderSpectatorInventory} which will provide access to the ender chest contents of a target player. + * @param target the target player + * @param options the creation options + * @return a {@link SpectateResponse} which, if successful, will give access to the {@link EnderSpectatorInventory} + */ + public final SpectateResponse enderSpectatorInventory(HumanEntity target, CreationOptions options) { + Target theTarget = Target.byPlayer(target); + if (!options.canBypassExemptedPlayers() && exempt.isExemptedFromHavingEnderchestSpectated(theTarget)) { + return SpectateResponse.fail(NotCreatedReason.targetHasExemptPermission(theTarget)); + } else { + EnderSpectatorInventory inv = platform.spectateEnderChest(target, options); + openSpectatorsCache.cache(inv); + return SpectateResponse.succeed(inv); + } + } + + // UserName + + /** + * Opens an {@link EnderSpectatorInventory} for a player. + * @param spectator the spectating player + * @param targetName the name of the target player + * @param options the creation options + * @return a future which will complete with an {@link OpenResponse} which, if successful, gives access to an {@link EnderSpectatorInventoryView} which represents the open window + */ + public final CompletableFuture> spectateEnderChest(Player spectator, String targetName, CreationOptions options) { + return spectateEnderChest(spectator, enderSpectatorInventory(targetName, options), options); + } + + /** + * Create an {@link EnderSpectatorInventory} which will provide access to the ender chest contents of a target player. + * @param targetName the username of the target player + * @return a future which will complete with a {@link SpectateResponse} which, if successful, will give access to the {@link EnderSpectatorInventory} + */ + public final CompletableFuture> enderSpectatorInventory(String targetName) { + return enderSpectatorInventory(targetName, enderInventoryCreationOptions()); + } + + /** + * Create an {@link EnderSpectatorInventory} which will provide access to the ender chest contents of a target player. + * @param targetName the username of the target player + * @param options the creation options + * @return a future which will complete with a {@link SpectateResponse} which, if successful, will give access to the {@link EnderSpectatorInventory} + */ + public final CompletableFuture> enderSpectatorInventory(String targetName, CreationOptions options) { + Objects.requireNonNull(targetName, "targetName cannot be null!"); + Objects.requireNonNull(options, "options cannot be null!"); + + //try online + Player targetPlayer = plugin.getServer().getPlayerExact(targetName); + Target target; + if (targetPlayer != null) { + target = Target.byPlayer(targetPlayer); + if (!options.canBypassExemptedPlayers() && exempt.isExemptedFromHavingEnderchestSpectated(target)) + return CompletableFuture.completedFuture(SpectateResponse.fail(NotCreatedReason.targetHasExemptPermission(target))); + + EnderSpectatorInventory spectatorInventory = platform.spectateEnderChest(targetPlayer, options); + UUID uuid = targetPlayer.getUniqueId(); + lookup.cacheNameAndUniqueId(uuid, targetName); + openSpectatorsCache.cache(spectatorInventory); + return CompletableFuture.completedFuture(SpectateResponse.succeed(spectatorInventory)); + } else if (!options.isOfflinePlayerSupported()) { + return CompletableFuture.completedFuture(SpectateResponse.fail(NotCreatedReason.offlineSupportDisabled())); + } + + target = Target.byUsername(targetName); + + final CompletableFuture isExemptedFuture; + if (options.canBypassExemptedPlayers()) { + isExemptedFuture = CompletableFuture.completedFuture(false); + } else if (plugin.getServer().getPluginManager().isPluginEnabled("LuckPerms")) { + // Work around a LuckPerms bug where it can't perform a permission check for players who haven't logged into the server yet, + // because it tries to find the player's UUID in its database. How silly - it could just return whether the default group has that permission or not. + // See: https://www.spigotmc.org/threads/invsee.456148/page-5#post-4371623 + isExemptedFuture = CompletableFuture.completedFuture(false); + } else { + isExemptedFuture = CompletableFuture.supplyAsync(() -> exempt.isExemptedFromHavingEnderchestSpectated(target), scheduler::executeAsync); + } + + final CompletableFuture> uuidFuture = fetchUniqueId(targetName); + + final CompletableFuture> combinedFuture = isExemptedFuture.thenCompose(isExempted -> { + if (isExempted) { + return CompletableFuture.completedFuture(Either.left(NotCreatedReason.targetHasExemptPermission(target))); + } else { + return uuidFuture.thenApply(optionalUuid -> { + if (optionalUuid.isPresent()) { + return Either.right(optionalUuid.get()); + } else { + return Either.left(NotCreatedReason.targetDoesNotExists(target)); + } + }); + } + }); + + //map to SpectateResponse and cache if success + CompletableFuture> future = combinedFuture.thenCompose(eitherReasonOrUuid -> { + if (eitherReasonOrUuid.isRight()) { + UUID uuid = eitherReasonOrUuid.getRight(); + return enderSpectatorInventory(uuid, targetName, options); + } else { + NotCreatedReason reason = eitherReasonOrUuid.getLeft(); + return CompletableFuture.completedFuture(SpectateResponse.fail(reason)); + } + }); + pendingEnderChestsByName.put(targetName, future); + future.whenComplete((result, error) -> pendingEnderChestsByName.remove(targetName)); + return future; + } + + // UUID + + /** + * Opens an {@link EnderSpectatorInventory} for a player. + * @param spectator the spectating player + * @param targetId the unique ID of the target player + * @param targetName the name of the target player + * @param options the creation options + * @return a future which will complete with an {@link OpenResponse} which, if successful, gives access to an {@link EnderSpectatorInventoryView} which represents the open window + */ + public final CompletableFuture> spectateEnderChest(Player spectator, UUID targetId, String targetName, CreationOptions options) { + return spectateEnderChest(spectator, enderSpectatorInventory(targetId, targetName, options), options); + } + + /** + * Create an {@link EnderSpectatorInventory} which will provide access to the ender chest contents of a target player. + * @param playerId the unique ID of the target player + * @param playerName the username of the target player + * @return a future which will complete with a {@link SpectateResponse} which, if successful, will give access to the {@link EnderSpectatorInventory} + */ + public final CompletableFuture> enderSpectatorInventory(UUID playerId, String playerName) { + return enderSpectatorInventory(playerId, playerName, enderInventoryCreationOptions()); + } + + /** + * Create an {@link EnderSpectatorInventory} which will provide access to the ender chest contents of a target player. + * @param playerId the unique ID of the target player + * @param playerName the username of the target player + * @param options the creation options + * @return a future which will complete with a {@link SpectateResponse} which, if successful, will give access to the {@link EnderSpectatorInventory} + */ + public final CompletableFuture> enderSpectatorInventory(UUID playerId, String playerName, CreationOptions options) { + Objects.requireNonNull(playerId, "player UUID cannot be null!"); + Objects.requireNonNull(playerName, "player name cannot be null!"); + Objects.requireNonNull(options, "options cannot be null!"); + + //try online + Player targetPlayer = plugin.getServer().getPlayer(playerId); + Target target; + if (targetPlayer != null) { + target = Target.byPlayer(targetPlayer); + if (!options.canBypassExemptedPlayers() && exempt.isExemptedFromHavingEnderchestSpectated(target)) + return CompletableFuture.completedFuture(SpectateResponse.fail(NotCreatedReason.targetHasExemptPermission(target))); + + EnderSpectatorInventory spectatorInventory = platform.spectateEnderChest(targetPlayer, options); + lookup.cacheNameAndUniqueId(playerId, playerName); + openSpectatorsCache.cache(spectatorInventory); + return CompletableFuture.completedFuture(SpectateResponse.succeed(spectatorInventory)); + } else if (!options.isOfflinePlayerSupported()) { + return CompletableFuture.completedFuture(SpectateResponse.fail(NotCreatedReason.offlineSupportDisabled())); + } + + target = Target.byGameProfile(playerId, playerName); + + final CompletableFuture isExemptedFuture; + if (options.canBypassExemptedPlayers()) { + isExemptedFuture = CompletableFuture.completedFuture(false); + } else { + //make LuckPerms happy by doing the permission lookup async. I am not sure how well other permission plugins handle this, but everybody uses LuckPerms nowadays so... + isExemptedFuture = CompletableFuture.supplyAsync(() -> exempt.isExemptedFromHavingEnderchestSpectated(target), scheduler::executeAsync); + } + + final CompletableFuture> reasonFuture = isExemptedFuture.thenApply(isExempted -> { + if (isExempted) { + return Optional.of(NotCreatedReason.targetHasExemptPermission(target)); + } else { + return Optional.empty(); + } + }); + + //I really need monad transformers to make this cleaner. + final CompletableFuture> combinedFuture = reasonFuture.thenCompose(maybeReason -> { + if (maybeReason.isPresent()) { + return CompletableFuture.completedFuture(SpectateResponse.fail(maybeReason.get())); + } else { + //try cache + EnderSpectatorInventory alreadyOpen = openSpectatorsCache.getEnderSpectatorInventory(playerId); + if (alreadyOpen != null) { + return CompletableFuture.completedFuture(SpectateResponse.succeed(alreadyOpen)); + } + + //not in cache: create offline inventory + return platform.createOfflineEnderChest(playerId, playerName, options); + } + }); + + //map to SpectateResult and cache if success + CompletableFuture> future = combinedFuture.>thenApply(eitherReasonOrInventory -> { + eitherReasonOrInventory.ifSuccess(openSpectatorsCache::cache); + return eitherReasonOrInventory; + }).handleAsync((success, error) -> { + if (error == null) return success; + return Rethrow.unchecked(error); + }, runnable -> scheduler.executeSyncPlayer(playerId, runnable, null)); + pendingEnderChestsByUuid.put(playerId, future); + future.whenComplete((result, error) -> pendingEnderChestsByUuid.remove(playerId)); + return future; + } + + // ================================== Open Main/Ender Inventory ================================== + + private final CompletableFuture> spectateInventory(Player spectator, CompletableFuture> future, CreationOptions options) { + final CompletableFuture> result = new CompletableFuture<>(); + future.whenComplete((SpectateResponse response, Throwable throwable) -> { + if (throwable == null) { + if (response.isSuccess()) { + try { + OpenResponse openResponse = platform.openMainSpectatorInventory(spectator, response.getInventory(), options); + result.complete(openResponse); + } catch (Throwable ex) { + result.completeExceptionally(ex); + } + } else { + result.complete(OpenResponse.closed(NotOpenedReason.notCreated(response.getReason()))); + } + } else { + result.completeExceptionally(throwable); + } + }); + return result; + } + + private final CompletableFuture> spectateEnderChest(Player spectator, CompletableFuture> future, CreationOptions options) { + final CompletableFuture> result = new CompletableFuture<>(); + future.whenComplete((SpectateResponse response, Throwable throwable) -> { + if (throwable == null) { + if (response.isSuccess()) { + try { + OpenResponse openResponse = platform.openEnderSpectatorInventory(spectator, response.getInventory(), options); + result.complete(openResponse); + } catch (Throwable ex) { + result.completeExceptionally(ex); + } + } else { + result.complete(OpenResponse.closed(NotOpenedReason.notCreated(response.getReason()))); + } + } else { + result.completeExceptionally(throwable); + } + }); + return result; + } + + // ================================== Event Stuff ================================== + + private final class PlayerListener implements Listener { + + @EventHandler(priority = EventPriority.LOW) + public void onJoin(PlayerJoinEvent event) { + Player player = event.getPlayer(); + UUID uuid = player.getUniqueId(); + String userName = player.getName(); + + MainSpectatorInventory newInventorySpectator = null; + EnderSpectatorInventory newEnderSpectator = null; + + //check if somebody was looking up the player and make sure they get the player's live inventory + CompletableFuture> mainInvNameFuture = pendingInventoriesByName.remove(userName); + if (mainInvNameFuture != null) mainInvNameFuture.complete(SpectateResponse.succeed(newInventorySpectator = platform.spectateInventory(player, mainInventoryCreationOptions()))); + CompletableFuture> mainInvUuidFuture = pendingInventoriesByUuid.remove(uuid); + if (mainInvUuidFuture != null) mainInvUuidFuture.complete(SpectateResponse.succeed(newInventorySpectator != null ? newInventorySpectator : (newInventorySpectator = platform.spectateInventory(player, mainInventoryCreationOptions())))); + CompletableFuture> enderNameFuture = pendingEnderChestsByName.remove(userName); + if (enderNameFuture != null) enderNameFuture.complete(SpectateResponse.succeed(newEnderSpectator = platform.spectateEnderChest(player, enderInventoryCreationOptions()))); + CompletableFuture> enderUuidFuture = pendingEnderChestsByUuid.remove(uuid); + if (enderUuidFuture != null) enderUuidFuture.complete(SpectateResponse.succeed(newEnderSpectator != null ? newEnderSpectator : (newEnderSpectator = platform.spectateEnderChest(player, enderInventoryCreationOptions())))); + + + //check if somebody was looking in the offline inventory and update player's inventory. + //idem for ender. + + final MainSpectatorInventory oldMainSpectator = openSpectatorsCache.getMainSpectatorInventory(uuid); + final EnderSpectatorInventory oldEnderSpectator = openSpectatorsCache.getEnderSpectatorInventory(uuid); + + if (oldMainSpectator != null && transferInvToLivePlayer.test(oldMainSpectator, player)) { + if (newInventorySpectator == null) { + newInventorySpectator = platform.spectateInventory(player, mainInventoryCreationOptions()); + newInventorySpectator.setContents(oldMainSpectator); //set the contents of the player's inventory to the contents that the spectators have. + } + + if (oldMainSpectator instanceof ShallowCopy) { + //shallow-copy the live itemstack lists into the open spectator inventory. + ((ShallowCopy) oldMainSpectator).shallowCopyFrom(newInventorySpectator); + //no need to update the cache because oldMainSpectator already came from the cache! + } else { + //does not support shallow copying, just close and re-open, and update the cache! + for (HumanEntity viewer : Compat.listCopy(oldMainSpectator.getViewers())) { + viewer.closeInventory(); + viewer.openInventory(newInventorySpectator); + } + openSpectatorsCache.cache(newInventorySpectator, true); + } + } + + if (oldEnderSpectator != null && transferEnderToLivePlayer.test(oldEnderSpectator, player)) { + if (newEnderSpectator == null) { + newEnderSpectator = platform.spectateEnderChest(player, enderInventoryCreationOptions()); + newEnderSpectator.setContents(oldEnderSpectator); //set the contents of the player's enderchest to the contents that the spectators have. + } + + if (oldEnderSpectator instanceof ShallowCopy) { + //shallow-copy the live itemstack list into the open spectator inventory. + ((ShallowCopy) oldEnderSpectator).shallowCopyFrom(newEnderSpectator); + //no need to update the cache because oldEnderSpectator already came from the cache! + } else { + //does not support shallow copying, just close and re-open, and update the cache! + for (HumanEntity viewer : Compat.listCopy(oldEnderSpectator.getViewers())) { + viewer.closeInventory(); + viewer.openInventory(newEnderSpectator); + } + openSpectatorsCache.cache(newEnderSpectator, true); + } + } + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onQuit(PlayerQuitEvent event) { + Player player = event.getPlayer(); + UUID uuid = player.getUniqueId(); + lookup.cacheNameAndUniqueId(uuid, player.getName()); + + //no need to remove open inventories (and enderchests) from the openInventories cache, since we're using a weak reference to the UUID of the target inventory as the map key. + //As soon as no player is spectating that inventory anymore and the JVM garbage collects the SpectatorInventory, the entry will be evicted from the openInventories cache automatically. + //This *REQUIRES* that the UUIDs used by SpectatorInventories are copies of the UUIDs of the Players. See UUIDHelper#copy(UUID). + } + + //TODO as Paper may introduce creating multiple nms ServerPlayer objects for the same CraftPlayer, + //TODO we need to track this properly and *reset* the nms inventory contents to that of the new (live) player, + //TODO whenever the player changes worlds. + //TODO see: https://github.com/orgs/PaperMC/projects/6/views/1?pane=issue&itemId=16746355 + //TODO another option could be that we keep the CraftPlayer in our SpectatorInventory? Perhaps this could be a paper-specific module. + } + + private final class InventoryListener implements Listener { + + @EventHandler(priority = EventPriority.MONITOR) + public void onSpectatorClose(InventoryCloseEvent event) { + Inventory inventory = event.getInventory(); + if (inventory instanceof MainSpectatorInventory) { + MainSpectatorInventory spectatorInventory = (MainSpectatorInventory) inventory; + if (event.getPlayer().getServer().getPlayer(spectatorInventory.getSpectatedPlayerId()) == null) { + //spectated player is no longer online + saveInventory(spectatorInventory).whenComplete((voidResult, throwable) -> { + if (throwable != null) { + plugin.getLogger().log(Level.SEVERE, "Error while saving offline inventory", throwable); + event.getPlayer().sendMessage(ChatColor.RED + "Something went wrong when trying to save the inventory."); + } + }); //idem: don't remove from cache. + } + } else if (inventory instanceof EnderSpectatorInventory) { + EnderSpectatorInventory spectatorInventory = (EnderSpectatorInventory) inventory; + if (event.getPlayer().getServer().getPlayer(spectatorInventory.getSpectatedPlayerId()) == null) { + //spectated player is no longer online + saveEnderChest(spectatorInventory).whenComplete((voidResult, throwable) -> { + if (throwable != null) { + plugin.getLogger().log(Level.SEVERE, "Error while saving offline enderchest", throwable); + event.getPlayer().sendMessage(ChatColor.RED + "Something went wrong when trying to save the enderchest."); + } + }); //idem: don't remove from cache. + } + } + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onTargetOpen(InventoryOpenEvent event) { + HumanEntity target = event.getPlayer(); + MainSpectatorInventory spectatorInventory = openSpectatorsCache.getMainSpectatorInventory(target.getUniqueId()); + if (spectatorInventory instanceof Personal) { + //instanceof evaluates to 'false' for null values, so we can be sure that spectatorInventory is not null. + //set the cursor reference and crafting inventory + ((Personal) spectatorInventory).watch(event.getView()); + } + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onTargetClose(InventoryCloseEvent event) { + HumanEntity target = event.getPlayer(); + MainSpectatorInventory spectatorInventory = openSpectatorsCache.getMainSpectatorInventory(target.getUniqueId()); + if (spectatorInventory instanceof Personal) { + //instanceof evaluates to 'false' for null values, so we can be sure that spectatorInventory is not null. + //reset personal contents to the player's own crafting contents + ((Personal) spectatorInventory).unwatch(); + } + } + + } + + + // + // =================================== REALM OF THE DEPRECATED =================================== + // + // + + // =================================== deprecated public apis ==================================== + + /** @deprecated use {@link #setMainInventoryTitle(Title)} */ + @Deprecated public final void setMainInventoryTitleFactory(Function titleFactory) { + setMainInventoryTitle(Title.of(titleFactory)); + } + + /** @deprecated use {@link #setEnderInventoryTitle(Title)} */ + @Deprecated public final void setEnderInventoryTitleFactory(Function titleFactory) { + setEnderInventoryTitle(Title.of(titleFactory)); + } + + // + + /** @deprecated use {@link #spectateInventory(Player, String, CreationOptions)} */ + @Deprecated public final CompletableFuture spectateInventory(Player spectator, String targetName, String title, boolean offlineSupport, Mirror mirror) { + return spectateInventory(spectator, targetName, mainInventoryCreationOptions(spectator).withTitle(title).withOfflinePlayerSupport(offlineSupport).withMirror(mirror)) + .whenComplete((either, throwable) -> handleMainInventoryExceptionsAndNotCreatedReasons(plugin, spectator, either, throwable, targetName)) + .thenApply(__ -> null); + } + + /** @deprecated use {@link #spectateInventory(Player, UUID, String, CreationOptions)} */ + @Deprecated public final CompletableFuture spectateInventory(Player spectator, UUID targetId, String targetName, String title, boolean offlineSupport, Mirror mirror) { + return spectateInventory(spectator, targetId, targetName, mainInventoryCreationOptions(spectator).withTitle(title).withOfflinePlayerSupport(offlineSupport).withMirror(mirror)) + .whenComplete((either, throwable) -> handleMainInventoryExceptionsAndNotCreatedReasons(plugin, spectator, either, throwable, targetId.toString())) + .thenApply(__ -> null); + } + + private static > void handleMainInventoryExceptionsAndNotCreatedReasons(Plugin plugin, Player spectator, OpenResponse openResponse, Throwable throwable, String targetNameOrUuid) { + if (throwable == null) { + if (!openResponse.isOpen()) { + NotOpenedReason notOpenedReason = openResponse.getReason(); + if (notOpenedReason instanceof InventoryOpenEventCancelled) { + spectator.sendMessage(ChatColor.RED + "Another plugin prevented you from spectating " + targetNameOrUuid + "'s inventory"); + } else if (notOpenedReason instanceof InventoryNotCreated) { + NotCreatedReason notCreatedReason = ((InventoryNotCreated) notOpenedReason).getNotCreatedReason(); + if (notCreatedReason instanceof TargetDoesNotExist) { + spectator.sendMessage(ChatColor.RED + "Player " + targetNameOrUuid + " does not exist."); + } else if (notCreatedReason instanceof UnknownTarget) { + spectator.sendMessage(ChatColor.RED + "Player " + targetNameOrUuid + " has not logged onto the server yet."); + } else if (notCreatedReason instanceof TargetHasExemptPermission) { + spectator.sendMessage(ChatColor.RED + "Player " + targetNameOrUuid + " is exempted from being spectated."); + } else if (notCreatedReason instanceof ImplementationFault) { + spectator.sendMessage(ChatColor.RED + "An internal fault occurred when trying to load " + targetNameOrUuid + "'s inventory."); + } else if (notCreatedReason instanceof OfflineSupportDisabled) { + spectator.sendMessage(ChatColor.RED + "Spectating offline players' inventories is disabled."); + } else { + spectator.sendMessage(ChatColor.RED + "Could not create " + targetNameOrUuid + "'s inventory for an unknown reason."); + } + } else { + spectator.sendMessage(ChatColor.RED + "Could not open " + targetNameOrUuid + "'s inventory for an unknown reason."); + } + } + } else { + spectator.sendMessage(ChatColor.RED + "An error occurred while trying to open " + targetNameOrUuid + "'s inventory."); + plugin.getLogger().log(Level.SEVERE, "Error while trying to create main-inventory spectator inventory", throwable); + } + } + + /** @deprecated use {@link #spectateEnderChest(Player, String, CreationOptions)} */ + @Deprecated public final CompletableFuture spectateEnderChest(Player spectator, String targetName, String title, boolean offlineSupport, Mirror mirror) { + return spectateEnderChest(spectator, targetName, enderInventoryCreationOptions(spectator).withTitle(title).withOfflinePlayerSupport(offlineSupport).withMirror(mirror)) + .whenComplete((either, throwable) -> handleEnderInventoryExceptionsAndNotCreatedReasons(plugin, spectator, either, throwable, targetName)) + .thenApply(__ -> null); + } + + /** @deprecated use {@link #spectateEnderChest(Player, UUID, String, CreationOptions)} */ + @Deprecated public final CompletableFuture spectateEnderChest(Player spectator, UUID targetId, String targetName, String title, boolean offlineSupport, Mirror mirror) { + return spectateEnderChest(spectator, targetId, targetName, enderInventoryCreationOptions(spectator).withTitle(title).withOfflinePlayerSupport(offlineSupport).withMirror(mirror)) + .whenComplete((either, throwable) -> handleEnderInventoryExceptionsAndNotCreatedReasons(plugin, spectator, either, throwable, targetId.toString())) + .thenApply(__ -> null); + } + + private static > void handleEnderInventoryExceptionsAndNotCreatedReasons(Plugin plugin, Player spectator, OpenResponse openResponse, Throwable throwable, String targetNameOrUuid) { + if (throwable == null) { + if (!openResponse.isOpen()) { + NotOpenedReason notOpenedReason = openResponse.getReason(); + if (notOpenedReason instanceof InventoryOpenEventCancelled) { + spectator.sendMessage(ChatColor.RED + "Another plugin prevented you from spectating " + targetNameOrUuid + "'s ender chest."); + } else if (notOpenedReason instanceof InventoryNotCreated) { + NotCreatedReason reason = ((InventoryNotCreated) notOpenedReason).getNotCreatedReason(); + if (reason instanceof TargetDoesNotExist) { + spectator.sendMessage(ChatColor.RED + "Player " + targetNameOrUuid + " does not exist."); + } else if (reason instanceof UnknownTarget) { + spectator.sendMessage(ChatColor.RED + "Player " + targetNameOrUuid + " has not logged onto the server yet."); + } else if (reason instanceof TargetHasExemptPermission) { + spectator.sendMessage(ChatColor.RED + "Player " + targetNameOrUuid + " is exempted from being spectated."); + } else if (reason instanceof ImplementationFault) { + spectator.sendMessage(ChatColor.RED + "An internal fault occurred when trying to load " + targetNameOrUuid + "'s enderchest."); + } else if (reason instanceof OfflineSupportDisabled) { + spectator.sendMessage(ChatColor.RED + "Spectating offline players' enderchests is disabled."); + } else { + spectator.sendMessage(ChatColor.RED + "Could not create " + targetNameOrUuid + "'s enderchest for an unknown reason."); + } + } else { + spectator.sendMessage(ChatColor.RED + "Could not open " + targetNameOrUuid + "'s enderchest for an unknown reason."); + } + } + } else { + spectator.sendMessage(ChatColor.RED + "An error occurred while trying to open " + targetNameOrUuid + "'s enderchest."); + plugin.getLogger().log(Level.SEVERE, "Error while trying to create ender-chest spectator inventory", throwable); + } + } + + // open main spectator inventory using parameters + + // HumanEntity target + + /** @deprecated use {@link #mainSpectatorInventory(HumanEntity, CreationOptions)} */ + @Deprecated public final SpectateResponse mainSpectatorInventory(HumanEntity target, String title) { + return mainSpectatorInventory(target, mainInventoryCreationOptions().withTitle(title)); + } + + /** @deprecated use {@link #mainSpectatorInventory(HumanEntity, CreationOptions)} */ + @Deprecated public final SpectateResponse mainSpectatorInventory(HumanEntity target, String title, Mirror mirror) { + return mainSpectatorInventory(target, mainInventoryCreationOptions().withTitle(title).withMirror(mirror)); + } + + // UserName target + + /** @deprecated use {@link #mainSpectatorInventory(String, CreationOptions)} */ + @Deprecated public final CompletableFuture> mainSpectatorInventory(String targetName, String title) { + return mainSpectatorInventory(targetName, title, offlinePlayerSupport); + } + + /** @deprecated use {@link #mainSpectatorInventory(String, CreationOptions)} */ + @Deprecated public final CompletableFuture> mainSpectatorInventory(String targetName, String title, boolean offlineSupport) { + return mainSpectatorInventory(targetName, title, offlineSupport, inventoryMirror); + } + + /** @deprecated use {@link #mainSpectatorInventory(String, CreationOptions)} */ + @Deprecated public final CompletableFuture> mainSpectatorInventory(String targetName, String title, boolean offlineSupport, Mirror mirror) { + return mainSpectatorInventory(targetName, mainInventoryCreationOptions().withTitle(title).withOfflinePlayerSupport(offlineSupport).withMirror(mirror)); + } + + // UUID target + + /** @deprecated use {@link #mainSpectatorInventory(UUID, String, CreationOptions)} */ + @Deprecated public final CompletableFuture> mainSpectatorInventory(UUID playerId, String playerName, String title) { + return mainSpectatorInventory(playerId, playerName, title, offlinePlayerSupport); + } + + /** @deprecated use {@link #mainSpectatorInventory(UUID, String, CreationOptions)} */ + @Deprecated public final CompletableFuture> mainSpectatorInventory(UUID playerId, String playerName, String title, boolean offlineSupport) { + return mainSpectatorInventory(playerId, playerName, title, offlineSupport, inventoryMirror); + } + + /** @deprecated use {@link #mainSpectatorInventory(UUID, String, CreationOptions)} */ + @Deprecated public final CompletableFuture> mainSpectatorInventory(UUID playerId, String playerName, String title, boolean offlineSupport, Mirror mirror) { + return mainSpectatorInventory(playerId, playerName, CreationOptions.of(plugin, Title.of(title), offlineSupport, mirror, unknownPlayerSupport, false, LogOptions.empty())); + } + + // open ender spectator inventory using parameters + + // HumanEntity target + + /** @deprecated use {@link #enderSpectatorInventory(HumanEntity, CreationOptions)} */ + @Deprecated public final SpectateResponse enderSpectatorInventory(HumanEntity target, String title) { + return enderSpectatorInventory(target, enderInventoryCreationOptions().withTitle(title)); + } + + /** @deprecated use {@link #enderSpectatorInventory(HumanEntity, CreationOptions)} */ + @Deprecated public final SpectateResponse enderSpectatorInventory(HumanEntity target, String title, Mirror mirror) { + return enderSpectatorInventory(target, enderInventoryCreationOptions().withTitle(title).withMirror(mirror)); + } + + // UserName target: + + /** @deprecated use {@link #enderSpectatorInventory(String, CreationOptions)} */ + @Deprecated public final CompletableFuture> enderSpectatorInventory(String targetName, String title) { + return enderSpectatorInventory(targetName, title, offlinePlayerSupport); + } + + /** @deprecated use {@link #enderSpectatorInventory(String, CreationOptions)} */ + @Deprecated public final CompletableFuture> enderSpectatorInventory(String targetName, String title, boolean offlineSupport) { + return enderSpectatorInventory(targetName, title, offlineSupport, enderchestMirror); + } + + /** @deprecated use {@link #enderSpectatorInventory(String, CreationOptions)} */ + @Deprecated public final CompletableFuture> enderSpectatorInventory(String targetName, String title, boolean offlineSupport, Mirror mirror) { + return enderSpectatorInventory(targetName, enderInventoryCreationOptions().withTitle(title).withOfflinePlayerSupport(offlineSupport).withMirror(mirror)); + } + + // UUID target + + /** @deprecated use {@link #enderSpectatorInventory(UUID, String, CreationOptions)} */ + @Deprecated public final CompletableFuture> enderSpectatorInventory(UUID playerId, String playerName, String title) { + return enderSpectatorInventory(playerId, playerName, title, offlinePlayerSupport); + } + + /** @deprecated use {@link #enderSpectatorInventory(UUID, String, CreationOptions)} */ + @Deprecated public final CompletableFuture> enderSpectatorInventory(UUID playerId, String playerName, String title, boolean offlineSupport) { + return enderSpectatorInventory(playerId, playerName, title, offlineSupport, enderchestMirror); + } + + /** @deprecated use {@link #enderSpectatorInventory(UUID, String, CreationOptions)} */ + @Deprecated public final CompletableFuture> enderSpectatorInventory(UUID playerId, String playerName, String title, boolean offlineSupport, Mirror mirror) { + return enderSpectatorInventory(playerId, playerName, enderInventoryCreationOptions().withTitle(title).withOfflinePlayerSupport(offlineSupport).withMirror(mirror)); + } + + // apis that open immideately: + + /** @deprecated use {@link #spectateInventory(Player, HumanEntity, CreationOptions)} or {@link #spectateInventory(Player, UUID, String, CreationOptions)} */ + @Deprecated public final void openMainSpectatorInventory(Player spectator, MainSpectatorInventory spectatorInventory, String title, Mirror mirror) { + platform.openMainSpectatorInventory(spectator, spectatorInventory, mainInventoryCreationOptions().withTitle(title).withMirror(mirror)); + } + + /** @deprecated use {@link #spectateEnderChest(Player, HumanEntity, CreationOptions)} or {@link #spectateEnderChest(Player, UUID, String, CreationOptions)} */ + @Deprecated public final void openEnderSpectatorInventory(Player spectator, EnderSpectatorInventory spectatorInventory, String title, Mirror mirror) { + platform.openEnderSpectatorInventory(spectator, spectatorInventory, enderInventoryCreationOptions().withTitle(title).withMirror(mirror)); + } + + // =================================== deprecated private apis =================================== + + // implementation methods: + + /** @deprecated use {@link #enderSpectatorInventory(UUID, String, CreationOptions)} */ + @Deprecated//(forRemoval = true, since = "0.19.6") + public final CompletableFuture> createOfflineEnderChest(UUID playerId, String playerName, String title, Mirror mirror) { + return platform.createOfflineEnderChest(playerId, playerName, enderInventoryCreationOptions().withTitle(title).withMirror(mirror)) + .thenApply(response -> response.isSuccess() ? Optional.of(response.getInventory()) : Optional.empty()); + } + /** @deprecated use {@link #enderSpectatorInventory(UUID, String, CreationOptions)} */ + @Deprecated//(forRemoval = true, since = "0.19.6") + public final CompletableFuture> createOfflineEnderChest(UUID playerId, String playerName, String title) { + return platform.createOfflineEnderChest(playerId, playerName, enderInventoryCreationOptions().withTitle(title)) + .thenApply(response -> response.isSuccess() ? Optional.of(response.getInventory()) : Optional.empty()); + } + + /** @deprecated use {@link #enderSpectatorInventory(HumanEntity, CreationOptions)} */ + @Deprecated//(forRemoval = true, since = "0.19.6") + public final EnderSpectatorInventory spectateEnderChest(HumanEntity player, String title, Mirror mirror) { + return platform.spectateEnderChest(player, enderInventoryCreationOptions().withTitle(title).withMirror(mirror)); + } + /** @deprecated use {@link #enderSpectatorInventory(HumanEntity, CreationOptions)} */ + @Deprecated//(forRemoval = true, since = "0.19.6") + public final EnderSpectatorInventory spectateEnderChest(HumanEntity player, String title) { + return platform.spectateEnderChest(player, enderInventoryCreationOptions().withTitle(title)); + } + + /** @deprecated use {@link #mainSpectatorInventory(UUID, String, CreationOptions)} */ + @Deprecated//(forRemoval = true, since = "0.19.6") + public final CompletableFuture> createOfflineInventory(UUID playerId, String playerName, String title, Mirror mirror) { + return platform.createOfflineInventory(playerId, playerName, mainInventoryCreationOptions().withTitle(title).withMirror(mirror)) + .thenApply(response -> response.isSuccess() ? Optional.of(response.getInventory()) : Optional.empty()); + } + /** @deprecated use {@link #mainSpectatorInventory(UUID, String, CreationOptions)} */ + @Deprecated//(forRemoval = true, since = "0.19.6") + public final CompletableFuture> createOfflineInventory(UUID playerId, String playerName, String title) { + return platform.createOfflineInventory(playerId, playerName, mainInventoryCreationOptions().withTitle(title)) + .thenApply(response -> response.isSuccess() ? Optional.of(response.getInventory()) : Optional.empty()); + } + + /** @deprecated use {@link #mainSpectatorInventory(HumanEntity, CreationOptions)} */ + @Deprecated//(forRemoval = true, since = "0.19.6") + public final MainSpectatorInventory spectateInventory(HumanEntity player, String title, Mirror mirror) { + return platform.spectateInventory(player, mainInventoryCreationOptions().withTitle(title).withMirror(mirror)); + } + /** @deprecated use {@link #mainSpectatorInventory(HumanEntity, CreationOptions)} */ + @Deprecated//(forRemoval = true, since = "0.19.6") + public final MainSpectatorInventory spectateInventory(HumanEntity player, String title) { + return platform.spectateInventory(player, mainInventoryCreationOptions().withTitle(title)); + } + +} diff --git a/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/InvseePlusPlus.java b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/InvseePlusPlus.java new file mode 100644 index 0000000..ea8f10e --- /dev/null +++ b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/InvseePlusPlus.java @@ -0,0 +1,8 @@ +package com.janboerman.invsee.spigot.api; + +/** Api representation of the InvSee++ plugin. */ +public interface InvseePlusPlus { + + public InvseeAPI getApi(); + +} diff --git a/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/MainSpectatorInventory.java b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/MainSpectatorInventory.java new file mode 100644 index 0000000..f8a1635 --- /dev/null +++ b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/MainSpectatorInventory.java @@ -0,0 +1,65 @@ +package com.janboerman.invsee.spigot.api; + +import com.janboerman.invsee.spigot.api.template.Mirror; +import com.janboerman.invsee.spigot.api.template.PlayerInventorySlot; +import org.bukkit.inventory.ItemStack; + +/** + * A spectator inventory that contains all the items of the target player's 'normal' inventory. + * This includes the player's armour, items in his crafting grid, and even the item on his cursor! + */ +public interface MainSpectatorInventory extends SpectatorInventory { + + /** Get the items in the player's storage slots. */ + ItemStack[] getStorageContents(); + + /** Set the items in the player's storage slots. */ + void setStorageContents(ItemStack[] storageContents); + + /** Get the items in the player's armour slots. */ + ItemStack[] getArmourContents(); + + /** Change the items in the player's armour slots. */ + void setArmourContents(ItemStack[] armourContents); + + /** Get the items in the player's offhand. As per MC 1.21.6, this array includes the player's BODY and SADDLE items.*/ + ItemStack[] getOffHandContents(); + + /** Set the items in the player's offhand. The length of this array must be equal to {@code getOffHandContents().length}. */ + void setOffHandContents(ItemStack[] offHand); + + /** Set the item that is on the player's cursor. */ + void setCursorContents(ItemStack cursor); + + /** Get the item that is on the player's cursor. */ + ItemStack getCursorContents(); + + /** Set the items that are in the player's crafting slots. + * If the target player has an anvil/crafting table/enchanting table/villager workstation opened, + * then the contents of that temporary container will be updated instead. */ + void setPersonalContents(ItemStack[] craftingContents); + + /** Get the items that are in the player's crafting slots. + * If the target player has an anvil/crafting/table/enchanting table/villager workstation opened, + * then the contents of that temporary container will be retrieved instead. + */ + ItemStack[] getPersonalContents(); + + /** Get the length of the {@link #getPersonalContents()} array. */ + int getPersonalContentsSize(); + + /** Get the mirror this inventory is viewed through. */ + public default Mirror getMirror() { + return getCreationOptions().getMirror(); + } + + /** Set the contents of this inventory based on the contents from the provided inventory. */ + public default void setContents(MainSpectatorInventory newContents) { + setStorageContents(newContents.getStorageContents()); + setArmourContents(newContents.getArmourContents()); + setOffHandContents(newContents.getOffHandContents()); + setCursorContents(newContents.getCursorContents()); + setPersonalContents(newContents.getPersonalContents()); + } + +} diff --git a/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/MainSpectatorInventoryView.java b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/MainSpectatorInventoryView.java new file mode 100644 index 0000000..585877f --- /dev/null +++ b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/MainSpectatorInventoryView.java @@ -0,0 +1,21 @@ +package com.janboerman.invsee.spigot.api; + +import com.janboerman.invsee.spigot.api.template.PlayerInventorySlot; + +import org.bukkit.event.inventory.InventoryType; + +public interface MainSpectatorInventoryView extends SpectatorInventoryView { + + /** {@inheritDoc} */ + @Override + public MainSpectatorInventory getTopInventory(); + + /** + * Get the inventory type. + * @return the inventory type + */ + public default InventoryType getType() { + return InventoryType.CHEST; + } + +} diff --git a/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/OfflinePlayerProvider.java b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/OfflinePlayerProvider.java new file mode 100644 index 0000000..8ec6dd4 --- /dev/null +++ b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/OfflinePlayerProvider.java @@ -0,0 +1,56 @@ +package com.janboerman.invsee.spigot.api; + +import java.util.Collections; +import java.util.Set; +import java.util.concurrent.ConcurrentSkipListSet; +import java.util.function.Consumer; + +public interface OfflinePlayerProvider { + + /** Gets all usernames of players that are known to the server. Usernames will be passed to the consumer as they are discovered. */ + public void getAll(Consumer consumer); + + @Deprecated//(forRemoval = true, since = "0.20.0") //TODO delete in 1.0 + public default Set getAll() { + Set result = new ConcurrentSkipListSet<>(String.CASE_INSENSITIVE_ORDER); + getAll(result::add); + return result; + } + + /** Gets all usernames that starts with the specified prefix of players that are known to the server. Usernames will be passed to the consumer as they are discovered. */ + public void getWithPrefix(String prefix, Consumer consumer); + + @Deprecated//(forRemoval = true, since = "0.20.0") //TODO delete in 1.0 + public default Set getWithPrefix(String prefix) { + Set result = new ConcurrentSkipListSet<>(String.CASE_INSENSITIVE_ORDER); + getWithPrefix(prefix, result::add); + return result; + } + + public static class Dummy implements OfflinePlayerProvider { + + public static final Dummy INSTANCE = new Dummy(); + + private Dummy() { + } + + @Override + public void getAll(Consumer consumer) { + } + + @Override + public void getWithPrefix(String prefix, Consumer consumer) { + } + + @Override + public Set getAll() { + return Collections.emptySet(); + } + + @Override + public Set getWithPrefix(String prefix) { + return Collections.emptySet(); + } + } + +} diff --git a/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/Scheduler.java b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/Scheduler.java new file mode 100644 index 0000000..e86d43c --- /dev/null +++ b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/Scheduler.java @@ -0,0 +1,28 @@ +package com.janboerman.invsee.spigot.api; + +import java.util.UUID; + +/** + * Scheduler abstraction for scheduling tasks. + * + * @see Folia support + */ +public interface Scheduler { + + //TODO on places where this is called, the argument provided to the 'retired' parameter + //TODO should actually be a value: Usually we want to: + //TODO - load the 'offline' player data, + //TODO - apply the changes to the player's inventory + //TODO - save the player data again. + public void executeSyncPlayer(UUID playerId, Runnable task, Runnable retired); + + public void executeSyncGlobal(Runnable task); + + public void executeSyncGlobalRepeatedly(Runnable task, long ticksInitialDelay, long ticksPeriod); + + public void executeAsync(Runnable task); + + public void executeLaterGlobal(Runnable task, long delayTicks); + + void executeLaterAsync(Runnable task, long delayTicks); +} diff --git a/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/SpectatorInventory.java b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/SpectatorInventory.java new file mode 100644 index 0000000..8f32596 --- /dev/null +++ b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/SpectatorInventory.java @@ -0,0 +1,28 @@ +package com.janboerman.invsee.spigot.api; + +import com.janboerman.invsee.spigot.api.template.Mirror; +import org.bukkit.inventory.Inventory; + +import java.util.UUID; + +/** + * Represents a spectator-inventory, i.e. the inventory that an admin player sees when editing a player's inventory or enderchest content. + */ +public interface SpectatorInventory extends Inventory { + + /** get the username of the spectated player */ + public String getSpectatedPlayerName(); + + /** get the unique id of the spectated player */ + public UUID getSpectatedPlayerId(); + + /** get the title of this inventory */ + public String getTitle(); + + /** get the default Mirror this inventory is viewed through */ + public Mirror getMirror(); + + /** get the options this inventory was created with */ + public CreationOptions getCreationOptions(); + +} diff --git a/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/SpectatorInventoryView.java b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/SpectatorInventoryView.java new file mode 100644 index 0000000..6b0ebf4 --- /dev/null +++ b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/SpectatorInventoryView.java @@ -0,0 +1,53 @@ +package com.janboerman.invsee.spigot.api; + +import javax.annotation.Nullable; + +import com.janboerman.invsee.spigot.api.logging.Difference; +import com.janboerman.invsee.spigot.api.target.Target; +import com.janboerman.invsee.spigot.api.template.Mirror; + +/** + * Represents an open window for a {@link SpectatorInventory}. + * @param the inventory's slot type. + */ +// cannot extend InventoryView, because this class was not an interface before Bukkit 1.21. +public interface SpectatorInventoryView { + + /** + * Get the top inventory of this view. + * @return the top inventory + */ + public SpectatorInventory getTopInventory(); + + /** + * Get the difference tracked by this window. + * @return the difference + */ + public @Nullable Difference getTrackedDifference(); + + /** + * Get the options this window was created with. + * @return a copy of the creation options + */ + public CreationOptions getCreationOptions(); + + /** + * Get the title of this InventoryView. + * @return the title + */ + public String getTitle(); + + /** + * Get the mirror the {@link SpectatorInventory} is viewed through. + * @return the mirror + * @see Mirror explanation in the InvSee++ wiki + */ + public Mirror getMirror(); + + /** + * Get the target of the {@link SpectatorInventory}. + * @return the target + */ + public Target getTarget(); + +} diff --git a/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/Title.java b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/Title.java new file mode 100644 index 0000000..cf27d3f --- /dev/null +++ b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/Title.java @@ -0,0 +1,57 @@ +package com.janboerman.invsee.spigot.api; + +import com.janboerman.invsee.spigot.api.target.Target; +import com.janboerman.invsee.spigot.internal.ConstantTitle; + +import java.util.function.Function; + +/** + * Represents the title of a {@link SpectatorInventoryView}. + * The title string is computed from a {@link Target}. + */ +@FunctionalInterface +public interface Title { + + /** + * Get the title string for a given {@linkplain Target}. + * @param target the target + * @return the title string + */ + public String titleFor(Target target); + + /** + * Create a title with a constant tile string. + * @param title the constant title string + * @return the Title + */ + public static Title of(String title) { + if (title == null) return null; + return new ConstantTitle(title); + } + + /** Convert a Function into a Title. */ + public static Title of(Function function) { + if (function == null) return null; + return function::apply; + } + + /** Get the default main spectator inventory title: {@code "'s inventory"} */ + public static Title defaultMainInventory() { + return DefaultTitles.DEFAULT_MAIN_INVENTORY; + } + + /** Get the default ender chest spectator inventory title: {@code "'s enderchest"} */ + public static Title defaultEnderInventory() { + return DefaultTitles.DEFAULT_ENDER_INVENTORY; + } + +} + +class DefaultTitles { + + private DefaultTitles() {} + + static final Title DEFAULT_MAIN_INVENTORY = target -> target.toString() + "'s inventory"; + static final Title DEFAULT_ENDER_INVENTORY = target -> target.toString() + "'s enderchest"; + +} \ No newline at end of file diff --git a/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/event/SpectatorInventoryOfflineCreatedEvent.java b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/event/SpectatorInventoryOfflineCreatedEvent.java new file mode 100644 index 0000000..4613ae7 --- /dev/null +++ b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/event/SpectatorInventoryOfflineCreatedEvent.java @@ -0,0 +1,32 @@ +package com.janboerman.invsee.spigot.api.event; + +import com.janboerman.invsee.spigot.api.SpectatorInventory; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** Called when a {@link SpectatorInventory} is created whose target player is offline. */ +public class SpectatorInventoryOfflineCreatedEvent extends Event { + + private static final HandlerList handlers = new HandlerList(); + + private final SpectatorInventory spectatorInventory; + + public SpectatorInventoryOfflineCreatedEvent(SpectatorInventory spectatorInventory) { + this.spectatorInventory = spectatorInventory; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + /** Get the spectator inventory. */ + public SpectatorInventory getInventory() { + return spectatorInventory; + } + +} diff --git a/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/event/SpectatorInventorySaveEvent.java b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/event/SpectatorInventorySaveEvent.java new file mode 100644 index 0000000..ec6c894 --- /dev/null +++ b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/event/SpectatorInventorySaveEvent.java @@ -0,0 +1,48 @@ +package com.janboerman.invsee.spigot.api.event; + +import com.janboerman.invsee.spigot.api.SpectatorInventory; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * Called when the contents of a {@link SpectatorInventory} is saved to the target's player data file. + *
+ * Cancelling this event has the effect of the inventory data not getting saved. + */ +public class SpectatorInventorySaveEvent extends Event implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + private boolean cancel; + private final SpectatorInventory spectatorInventory; + + public SpectatorInventorySaveEvent(SpectatorInventory spectatorInventory) { + this.spectatorInventory = spectatorInventory; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + /** Get the spectator inventory. */ + public SpectatorInventory getInventory() { + return spectatorInventory; + } + + /** Check whether saving is disabled. */ + @Override + public boolean isCancelled() { + return cancel; + } + + /** Set whether saving should be disabled. */ + @Override + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } +} diff --git a/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/logging/Difference.java b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/logging/Difference.java new file mode 100644 index 0000000..24775a3 --- /dev/null +++ b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/logging/Difference.java @@ -0,0 +1,108 @@ +package com.janboerman.invsee.spigot.api.logging; + +import org.bukkit.inventory.ItemStack; + +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import com.janboerman.invsee.spigot.api.SpectatorInventoryView; + +/** + * The Difference of a {@link SpectatorInventoryView} is the set of items that were added and removed the {@link com.janboerman.invsee.spigot.api.SpectatorInventory}. + */ +public class Difference { + + //positive values: items were ADDED to the spectator inventory. + //negative values: items were REMOVED from the spectator inventory. + private Map diffs; + + public Difference() { + this.diffs = new LinkedHashMap<>(); + } + + /** + * Get the difference map. Keys represent items, values represent how many items were added to the {@Linkplain SpectatorInventory}. Negative values represent removed items. + * @return the difference map + */ + public Map getDifference() { + return Collections.unmodifiableMap(diffs); + } + + /** + * Get whether the difference is zero (no items added or removed). + * @return true if the difference is zero + */ + public boolean isEmpty() { + return diffs == null || diffs.isEmpty() || diffs.values().stream().allMatch(Objects::isNull); + } + + /** + * Merge this difference with another: add all differences from the other Difference to this Difference. + * @param other the other difference + */ + public void merge(Difference other) { + for (Map.Entry entry : other.diffs.entrySet()) { + accumulate(entry.getKey(), entry.getValue()); + } + } + + /** + * Add an item to this difference. + * @param stack the item + */ + public void accumulate(ItemStack stack) { + if (stack == null) return; + + accumulate(ItemType.of(stack), stack.getAmount()); + } + + /** + * Add an item to this Difference. + * @param itemType the item + * @param amount how many of the item + */ + public void accumulate(ItemType itemType, int amount) { + if (itemType == null || amount == 0) return; + + diffs.merge(itemType, amount, (x, y) -> { + int sum = x + y; + return sum == 0 ? null : sum; + }); + } + + /** + * Calculate the Difference from a 'before' and 'after' view of a list of items. + * @param before the 'before' view + * @param after the 'after' view + * @return the difference + */ + public static Difference calculate(List before, List after) { + if (before.size() != after.size()) + throw new IllegalArgumentException("'before' and 'after' lists must have the same sizes"); + + final Difference res = new Difference(); + + final Iterator one = before.iterator(); + final Iterator two = after.iterator(); + + while (one.hasNext()) { + assert two.hasNext(); + + final ItemStack oldStack = one.next(); + final ItemStack newStack = two.next(); + + if (!Objects.equals(oldStack, newStack)) { + res.accumulate(ItemType.of(newStack), newStack.getAmount()); + res.accumulate(ItemType.of(oldStack), -oldStack.getAmount()); + } + } + + return res; + } + + +} diff --git a/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/logging/DifferenceTracker.java b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/logging/DifferenceTracker.java new file mode 100644 index 0000000..d23f255 --- /dev/null +++ b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/logging/DifferenceTracker.java @@ -0,0 +1,42 @@ +package com.janboerman.invsee.spigot.api.logging; + +import org.bukkit.inventory.ItemStack; + +import java.util.List; + +public class DifferenceTracker { + + private final LogOutput output; + private final LogGranularity granularity; + + private Difference difference; + + public DifferenceTracker(LogOutput output, LogGranularity granularity) { + assert granularity != LogGranularity.LOG_NEVER : "Should not be instantiated with " + LogGranularity.class.getSimpleName() + "." + LogGranularity.LOG_NEVER.name(); + this.output = output; + this.granularity = granularity; + } + + public void onOpen() { + difference = new Difference(); + } + + public void onClick(List oldItems, List newItems) { + Difference diff = Difference.calculate(oldItems, newItems); + if (granularity == LogGranularity.LOG_EVERY_CHANGE && !diff.isEmpty()) { + output.log(diff); + } + difference.merge(diff); + } + + public void onClose() { + if (granularity == LogGranularity.LOG_ON_CLOSE && !difference.isEmpty()) { + output.log(difference); + } + output.close(); + } + + public Difference getDifference() { + return difference; + } +} diff --git a/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/logging/ItemType.java b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/logging/ItemType.java new file mode 100644 index 0000000..a25ee91 --- /dev/null +++ b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/logging/ItemType.java @@ -0,0 +1,78 @@ +package com.janboerman.invsee.spigot.api.logging; + +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.Objects; + +/** + * An item type is a product of {@link Material} and {@link ItemMeta}. + */ +public class ItemType { + + private final Material material; + private final ItemMeta meta; + + /** + * Construct the ItemType + * @param material the material + * @param meta the item meta + */ + public ItemType(Material material, ItemMeta meta) { + this.material = material; + this.meta = meta; + } + + /** + * Construct the ItemType + * @param stack the stack to obtain the Material and ItemMeta from. + * @return a new ItemType, or null if the item stack is empty + */ + public static ItemType of(ItemStack stack) { + if (isEmptyStack(stack)) return null; + + return new ItemType(stack.getType(), stack.hasItemMeta() ? stack.getItemMeta() : null); + } + + /** + * Get the material of this item type. + * @return the material + */ + public Material getMaterial() { + return material; + } + + /** + * Get the item meta of this item type. + * @return the item meta + */ + public ItemMeta getItemMeta() { + return meta; + } + + @Override + public String toString() { + return "ItemType(material=" + getMaterial() + ",meta=" + getItemMeta() + ")"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ItemType)) return false; + + ItemType that = (ItemType) o; + return this.getMaterial() == that.getMaterial() + && Objects.equals(this.getItemMeta(), that.getItemMeta()); + } + + @Override + public int hashCode() { + return Objects.hash(getMaterial(), getItemMeta()); + } + + private static boolean isEmptyStack(ItemStack stack) { + return stack == null || stack.getType() == Material.AIR || stack.getAmount() == 0; + } + +} diff --git a/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/logging/LogGranularity.java b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/logging/LogGranularity.java new file mode 100644 index 0000000..b72d45b --- /dev/null +++ b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/logging/LogGranularity.java @@ -0,0 +1,17 @@ +package com.janboerman.invsee.spigot.api.logging; + +import com.janboerman.invsee.spigot.api.SpectatorInventoryView; + +/** + * Granularity for logging. + */ +public enum LogGranularity { + + /** Log never. */ + LOG_NEVER, + /** Log when the {@link SpectatorInventoryView} closes. */ + LOG_ON_CLOSE, + /** Log changes after every change to the {@link com.janboerman.invsee.spigot.api.SpectatorInventory}. */ + LOG_EVERY_CHANGE, + +} diff --git a/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/logging/LogOptions.java b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/logging/LogOptions.java new file mode 100644 index 0000000..2b9f3cb --- /dev/null +++ b/InvSee++_Common/src/main/java/com/janboerman/invsee/spigot/api/logging/LogOptions.java @@ -0,0 +1,202 @@ +package com.janboerman.invsee.spigot.api.logging; + +import static com.janboerman.invsee.spigot.api.logging.LogTarget.*; +import static com.janboerman.invsee.utils.Compat.mapEntry; +import static com.janboerman.invsee.utils.Compat.mapOfEntries; + +import java.util.Collection; +import java.util.Collections; +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +import com.janboerman.invsee.spigot.api.SpectatorInventoryView; + +/** + * Options for logging interactions with {@link SpectatorInventoryView}s. + * + * @see com.janboerman.invsee.spigot.api.CreationOptions + */ +public class LogOptions implements Cloneable { + + public static final String FORMAT_SERVER_LOG_FILE = + "\nSpectator UUID: " + + "\nSpectator Name: " + + "\nTaken : " + + "\nGiven : " + + "\nTarget : "; + public static final String FORMAT_PLUGIN_LOG_FILE = + "\n[