diff --git a/StarPractice (2).zip b/StarPractice (2).zip
new file mode 100644
index 0000000..c679254
Binary files /dev/null and b/StarPractice (2).zip differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6-bin.zip b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6-bin.zip
new file mode 100644
index 0000000..45e2f43
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6-bin.zip differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/LICENSE b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/LICENSE
new file mode 100644
index 0000000..74c11a4
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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.1.jar: com.google.guava:failureaccess:bundle:1.0.1
+ 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-32.0.1-jre.jar: com.google.guava:guava:bundle:32.0.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.5.0.jar: commons-cli:commons-cli:jar:1.5.0
+ Project: Apache Commons CLI
+Project URL: https://commons.apache.org/proper/commons-cli/
+ License: Apache License, Version 2.0 (Apache-2.0)
+
+ License URL: https://www.apache.org/licenses/LICENSE-2.0.txt (lib/commons-cli.license)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+- lib/commons-codec-1.16.0.jar: commons-codec:commons-codec:jar:1.16.0
+ 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/commons-lang3-3.12.0.jar: org.apache.commons:commons-lang3:jar:3.12.0
+ Project: Apache Commons Lang
+Project URL: https://commons.apache.org/proper/commons-lang/
+ License: Apache License, Version 2.0 (Apache-2.0)
+
+ License URL: https://www.apache.org/licenses/LICENSE-2.0.txt (lib/commons-lang3.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.7.0.jar: org.codehaus.plexus:plexus-classworlds:bundle:2.7.0
+ Project: Plexus Classworlds
+Project URL: https://codehaus-plexus.github.io/plexus-classworlds/
+ License: Apache License, Version 2.0 (Apache-2.0)
+
+ License URL: http://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.26.jar: org.codehaus.plexus:plexus-interpolation:bundle:1.26
+ Project: Plexus Interpolation API
+Project URL: http://codehaus-plexus.github.io/plexus-interpolation/
+ License: Apache License, Version 2.0 (Apache-2.0)
+
+ License URL: http://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/org.eclipse.sisu.inject-0.9.0.M2.jar: org.eclipse.sisu:org.eclipse.sisu.inject:jar:0.9.0.M2
+ Project: org.eclipse.sisu.inject
+Project URL: https://www.eclipse.org/sisu/
+ License: Eclipse Public License, Version 1.0 (EPL-1.0)
+
+ License URL: http://www.eclipse.org/legal/epl-v10.html (lib/org.eclipse.sisu.inject.license)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+- lib/org.eclipse.sisu.plexus-0.9.0.M2.jar: org.eclipse.sisu:org.eclipse.sisu.plexus:jar:0.9.0.M2
+ Project: org.eclipse.sisu.plexus
+Project URL: https://www.eclipse.org/sisu/
+ License: Eclipse Public License, Version 1.0 (EPL-1.0)
+
+ License URL: http://www.eclipse.org/legal/epl-v10.html (lib/org.eclipse.sisu.plexus.license)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+- lib/jansi-2.4.0.jar: org.fusesource.jansi:jansi:jar:2.4.0
+ Project: jansi
+Project URL: http://fusesource.github.io/jansi
+ License: The Apache Software 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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/NOTICE b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/NOTICE
new file mode 100644
index 0000000..7763484
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/NOTICE
@@ -0,0 +1,104 @@
+Apache Maven Distribution
+Copyright 2001-2023 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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/README.txt b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/README.txt
new file mode 100644
index 0000000..3e93a84
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/README.txt
@@ -0,0 +1,79 @@
+
+ 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 can be found at https://maven.apache.org/docs/history.html.
+
+ System Requirements
+ -------------------
+
+ JDK:
+ 1.7 or above (this is to execute Maven - it still allows you to build against 1.3
+ and prior JDK's).
+ Memory:
+ No minimum requirement.
+ Disk:
+ Approximately 10MB is required for the Maven installation itself. In addition to
+ that, additional disk space will be used for your local Maven repository. The size
+ of your local repository will vary depending on usage but expect at least 500MB.
+ Operating System:
+ Windows:
+ Windows 2000 or above.
+ Unix based systems (Linux, Solaris and Mac OS X) and others:
+ No minimum requirement.
+
+ Installing Maven
+ ----------------
+
+ 1) Unpack the archive where you would like to store the binaries, e.g.:
+
+ Unix-based operating systems (Linux, Solaris and Mac OS X)
+ tar zxvf apache-maven-3.x.y.tar.gz
+ Windows
+ unzip apache-maven-3.x.y.zip
+
+ 2) A directory called "apache-maven-3.x.y" will be created.
+
+ 3) Add the bin directory to your PATH, e.g.:
+
+ Unix-based operating systems (Linux, Solaris and Mac OS X)
+ export PATH=/usr/local/apache-maven-3.x.y/bin:$PATH
+ Windows
+ set PATH="c:\program files\apache-maven-3.x.y\bin";%PATH%
+
+ 4) Make sure JAVA_HOME is set to the location of your JDK
+
+ 5) Run "mvn --version" to verify that it is correctly installed.
+
+ 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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/bin/m2.conf b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/bin/m2.conf
new file mode 100644
index 0000000..c446568
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/bin/mvn b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/bin/mvn
new file mode 100644
index 0000000..a3004f9
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/bin/mvn
@@ -0,0 +1,203 @@
+#!/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 [ "$wdir" != '/' ] ; do
+ if [ -d "$wdir"/.mvn ] ; then
+ basedir=$wdir
+ 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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/bin/mvn.cmd b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/bin/mvn.cmd
new file mode 100644
index 0000000..065f3c3
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/bin/mvnDebug b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/bin/mvnDebug
new file mode 100644
index 0000000..2d7cafe
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/bin/mvnDebug.cmd b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/bin/mvnDebug.cmd
new file mode 100644
index 0000000..9777cf9
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/bin/mvnyjp b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/bin/mvnyjp
new file mode 100644
index 0000000..6e21a0e
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/boot/plexus-classworlds-2.7.0.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/boot/plexus-classworlds-2.7.0.jar
new file mode 100644
index 0000000..07e1910
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/boot/plexus-classworlds-2.7.0.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/boot/plexus-classworlds.license b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/boot/plexus-classworlds.license
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/conf/logging/simplelogger.properties b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/conf/logging/simplelogger.properties
new file mode 100644
index 0000000..8c4a5d1
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/conf/settings.xml b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/conf/settings.xml
new file mode 100644
index 0000000..0d64976
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/conf/toolchains.xml b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/conf/toolchains.xml
new file mode 100644
index 0000000..b263072
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/conf/toolchains.xml
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/aopalliance-1.0.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/aopalliance-1.0.jar
new file mode 100644
index 0000000..578b1a0
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/aopalliance-1.0.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/aopalliance.license b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/aopalliance.license
new file mode 100644
index 0000000..a7a158b
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/aopalliance.license
@@ -0,0 +1 @@
+Public Domain
\ No newline at end of file
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/commons-cli-1.5.0.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/commons-cli-1.5.0.jar
new file mode 100644
index 0000000..e036456
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/commons-cli-1.5.0.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/commons-cli.license b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/commons-cli.license
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/commons-codec-1.16.0.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/commons-codec-1.16.0.jar
new file mode 100644
index 0000000..854fc7e
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/commons-codec-1.16.0.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/commons-codec.license b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/commons-codec.license
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/commons-lang3-3.12.0.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/commons-lang3-3.12.0.jar
new file mode 100644
index 0000000..4d434a2
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/commons-lang3-3.12.0.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/commons-lang3.license b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/commons-lang3.license
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/commons-lang3.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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/ext/README.txt b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/ext/README.txt
new file mode 100644
index 0000000..ab7f12a
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/ext/hazelcast/README.txt b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/ext/hazelcast/README.txt
new file mode 100644
index 0000000..77d19b1
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/ext/redisson/README.txt b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/ext/redisson/README.txt
new file mode 100644
index 0000000..58342b1
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/failureaccess-1.0.1.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/failureaccess-1.0.1.jar
new file mode 100644
index 0000000..9b56dc7
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/failureaccess-1.0.1.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/failureaccess.license b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/failureaccess.license
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/guava-32.0.1-jre.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/guava-32.0.1-jre.jar
new file mode 100644
index 0000000..5f3a1ee
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/guava-32.0.1-jre.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/guava.license b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/guava.license
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/guice-5.1.0.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/guice-5.1.0.jar
new file mode 100644
index 0000000..31c448f
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/guice-5.1.0.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/guice.license b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/guice.license
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/httpclient-4.5.14.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/httpclient-4.5.14.jar
new file mode 100644
index 0000000..2bb7c07
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/httpclient-4.5.14.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/httpclient.license b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/httpclient.license
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/httpcore-4.4.16.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/httpcore-4.4.16.jar
new file mode 100644
index 0000000..f0bdebe
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/httpcore-4.4.16.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/httpcore.license b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/httpcore.license
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/jansi-2.4.0.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/jansi-2.4.0.jar
new file mode 100644
index 0000000..d6bb12f
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/jansi-2.4.0.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/jansi-native/README.txt b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/jansi-native/README.txt
new file mode 100644
index 0000000..26a957e
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/jansi-native/Windows/x86/jansi.dll b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/jansi-native/Windows/x86/jansi.dll
new file mode 100644
index 0000000..59d1dc2
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/jansi-native/Windows/x86/jansi.dll differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/jansi-native/Windows/x86_64/jansi.dll b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/jansi-native/Windows/x86_64/jansi.dll
new file mode 100644
index 0000000..9739fa3
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/jansi-native/Windows/x86_64/jansi.dll differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/jansi.license b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/jansi.license
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/javax.annotation-api-1.3.2.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/javax.annotation-api-1.3.2.jar
new file mode 100644
index 0000000..a8a470a
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/javax.annotation-api-1.3.2.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/javax.annotation-api.license b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/javax.annotation-api.license
new file mode 100644
index 0000000..b1c74f9
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/javax.inject-1.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/javax.inject-1.jar
new file mode 100644
index 0000000..b2a9d0b
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/javax.inject-1.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/javax.inject.license b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/javax.inject.license
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/jcl-over-slf4j-1.7.36.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/jcl-over-slf4j-1.7.36.jar
new file mode 100644
index 0000000..3ecd7d5
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/jcl-over-slf4j-1.7.36.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/jcl-over-slf4j.license b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/jcl-over-slf4j.license
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-artifact-3.9.6.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-artifact-3.9.6.jar
new file mode 100644
index 0000000..b695c9f
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-artifact-3.9.6.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-builder-support-3.9.6.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-builder-support-3.9.6.jar
new file mode 100644
index 0000000..7129e8f
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-builder-support-3.9.6.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-compat-3.9.6.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-compat-3.9.6.jar
new file mode 100644
index 0000000..4e1e789
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-compat-3.9.6.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-core-3.9.6.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-core-3.9.6.jar
new file mode 100644
index 0000000..599c30c
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-core-3.9.6.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-embedder-3.9.6.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-embedder-3.9.6.jar
new file mode 100644
index 0000000..11f8a6c
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-embedder-3.9.6.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-model-3.9.6.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-model-3.9.6.jar
new file mode 100644
index 0000000..1bbc8c8
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-model-3.9.6.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-model-builder-3.9.6.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-model-builder-3.9.6.jar
new file mode 100644
index 0000000..49b2dde
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-model-builder-3.9.6.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-plugin-api-3.9.6.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-plugin-api-3.9.6.jar
new file mode 100644
index 0000000..d6a6880
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-plugin-api-3.9.6.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-repository-metadata-3.9.6.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-repository-metadata-3.9.6.jar
new file mode 100644
index 0000000..5ad525f
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-repository-metadata-3.9.6.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-api-1.9.18.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-api-1.9.18.jar
new file mode 100644
index 0000000..44c03c9
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-api-1.9.18.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-connector-basic-1.9.18.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-connector-basic-1.9.18.jar
new file mode 100644
index 0000000..0af30a5
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-connector-basic-1.9.18.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-impl-1.9.18.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-impl-1.9.18.jar
new file mode 100644
index 0000000..5263984
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-impl-1.9.18.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-named-locks-1.9.18.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-named-locks-1.9.18.jar
new file mode 100644
index 0000000..e3eae74
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-named-locks-1.9.18.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-provider-3.9.6.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-provider-3.9.6.jar
new file mode 100644
index 0000000..e8024e2
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-provider-3.9.6.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-spi-1.9.18.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-spi-1.9.18.jar
new file mode 100644
index 0000000..b13e20b
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-spi-1.9.18.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-transport-file-1.9.18.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-transport-file-1.9.18.jar
new file mode 100644
index 0000000..39a76a0
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-transport-file-1.9.18.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-transport-http-1.9.18.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-transport-http-1.9.18.jar
new file mode 100644
index 0000000..a84ce3d
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-transport-http-1.9.18.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-transport-wagon-1.9.18.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-transport-wagon-1.9.18.jar
new file mode 100644
index 0000000..4209f2f
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-transport-wagon-1.9.18.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-util-1.9.18.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-util-1.9.18.jar
new file mode 100644
index 0000000..d882859
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-resolver-util-1.9.18.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-settings-3.9.6.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-settings-3.9.6.jar
new file mode 100644
index 0000000..7092f75
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-settings-3.9.6.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-settings-builder-3.9.6.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-settings-builder-3.9.6.jar
new file mode 100644
index 0000000..dfea80e
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-settings-builder-3.9.6.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-shared-utils-3.3.4.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-shared-utils-3.3.4.jar
new file mode 100644
index 0000000..9b99c5a
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-shared-utils-3.3.4.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-slf4j-provider-3.9.6.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-slf4j-provider-3.9.6.jar
new file mode 100644
index 0000000..0539054
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/maven-slf4j-provider-3.9.6.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/org.eclipse.sisu.inject-0.9.0.M2.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/org.eclipse.sisu.inject-0.9.0.M2.jar
new file mode 100644
index 0000000..7b309b7
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/org.eclipse.sisu.inject-0.9.0.M2.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/org.eclipse.sisu.inject.license b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/org.eclipse.sisu.inject.license
new file mode 100644
index 0000000..6a200a1
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/org.eclipse.sisu.inject.license
@@ -0,0 +1,210 @@
+Eclipse Public License - v 1.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 code and documentation
+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 additions
+to the Program which: (i) are separate modules of software distributed in
+conjunction with the Program under their own license agreement, and (ii) are
+not derivative works of the Program.
+
+ "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, including
+all Contributors.
+
+ 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, in source code and object code form.
+
+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 and object code 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.
+
+ 3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form under
+its own license agreement, provided that:
+
+ a) it complies with the terms and conditions of this Agreement; and
+
+ b) its license agreement:
+
+i) effectively disclaims on behalf of all 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 Contributors all liability for damages,
+including direct, indirect, special, incidental and consequential damages,
+such as lost profits;
+
+iii) states that any provisions which differ from this Agreement are offered
+by that Contributor alone and not by any other party; and
+
+iv) states that source code for the Program is available from such Contributor,
+and informs licensees how to obtain it in a reasonable manner on or through
+a medium customarily used for software exchange.
+
+ When the Program is made available in source code form:
+
+ a) it must be made available under this Agreement; and
+
+b) a copy of this Agreement must be included with each copy of the Program.
+
+Contributors may not remove or alter any copyright notices contained within
+the Program.
+
+Each Contributor must identify itself as the originator of its Contribution,
+if any, in a manner that reasonably allows subsequent Recipients to identify
+the originator of the Contribution.
+
+ 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, 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, 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.
+
+This Agreement is governed by the laws of the State of New York and the intellectual
+property laws of the United States of America. No party to this Agreement
+will bring a legal action under this Agreement more than one year after the
+cause of action arose. Each party waives its rights to a jury trial in any
+resulting litigation.
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/org.eclipse.sisu.plexus-0.9.0.M2.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/org.eclipse.sisu.plexus-0.9.0.M2.jar
new file mode 100644
index 0000000..8e11a70
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/org.eclipse.sisu.plexus-0.9.0.M2.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/org.eclipse.sisu.plexus.license b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/org.eclipse.sisu.plexus.license
new file mode 100644
index 0000000..6a200a1
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/org.eclipse.sisu.plexus.license
@@ -0,0 +1,210 @@
+Eclipse Public License - v 1.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 code and documentation
+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 additions
+to the Program which: (i) are separate modules of software distributed in
+conjunction with the Program under their own license agreement, and (ii) are
+not derivative works of the Program.
+
+ "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, including
+all Contributors.
+
+ 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, in source code and object code form.
+
+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 and object code 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.
+
+ 3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form under
+its own license agreement, provided that:
+
+ a) it complies with the terms and conditions of this Agreement; and
+
+ b) its license agreement:
+
+i) effectively disclaims on behalf of all 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 Contributors all liability for damages,
+including direct, indirect, special, incidental and consequential damages,
+such as lost profits;
+
+iii) states that any provisions which differ from this Agreement are offered
+by that Contributor alone and not by any other party; and
+
+iv) states that source code for the Program is available from such Contributor,
+and informs licensees how to obtain it in a reasonable manner on or through
+a medium customarily used for software exchange.
+
+ When the Program is made available in source code form:
+
+ a) it must be made available under this Agreement; and
+
+b) a copy of this Agreement must be included with each copy of the Program.
+
+Contributors may not remove or alter any copyright notices contained within
+the Program.
+
+Each Contributor must identify itself as the originator of its Contribution,
+if any, in a manner that reasonably allows subsequent Recipients to identify
+the originator of the Contribution.
+
+ 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, 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, 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.
+
+This Agreement is governed by the laws of the State of New York and the intellectual
+property laws of the United States of America. No party to this Agreement
+will bring a legal action under this Agreement more than one year after the
+cause of action arose. Each party waives its rights to a jury trial in any
+resulting litigation.
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/plexus-cipher-2.0.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/plexus-cipher-2.0.jar
new file mode 100644
index 0000000..e73475d
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/plexus-cipher-2.0.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/plexus-cipher.license b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/plexus-cipher.license
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/plexus-component-annotations-2.1.0.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/plexus-component-annotations-2.1.0.jar
new file mode 100644
index 0000000..e3793a2
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/plexus-component-annotations-2.1.0.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/plexus-component-annotations.license b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/plexus-component-annotations.license
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/plexus-interpolation-1.26.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/plexus-interpolation-1.26.jar
new file mode 100644
index 0000000..cfcf162
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/plexus-interpolation-1.26.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/plexus-interpolation.license b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/plexus-interpolation.license
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/plexus-sec-dispatcher-2.0.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/plexus-sec-dispatcher-2.0.jar
new file mode 100644
index 0000000..623cc21
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/plexus-sec-dispatcher-2.0.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/plexus-sec-dispatcher.license b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/plexus-sec-dispatcher.license
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/plexus-utils-3.5.1.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/plexus-utils-3.5.1.jar
new file mode 100644
index 0000000..1873c52
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/plexus-utils-3.5.1.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/plexus-utils.license b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/plexus-utils.license
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/slf4j-api-1.7.36.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/slf4j-api-1.7.36.jar
new file mode 100644
index 0000000..7d3ce68
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/slf4j-api-1.7.36.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/slf4j-api.license b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/slf4j-api.license
new file mode 100644
index 0000000..1a3d053
--- /dev/null
+++ b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/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/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/wagon-file-3.5.3.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/wagon-file-3.5.3.jar
new file mode 100644
index 0000000..97222d4
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/wagon-file-3.5.3.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/wagon-http-3.5.3.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/wagon-http-3.5.3.jar
new file mode 100644
index 0000000..fd1f4a0
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/wagon-http-3.5.3.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/wagon-http-shared-3.5.3.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/wagon-http-shared-3.5.3.jar
new file mode 100644
index 0000000..d6f2d75
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/wagon-http-shared-3.5.3.jar differ
diff --git a/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/wagon-provider-api-3.5.3.jar b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/wagon-provider-api-3.5.3.jar
new file mode 100644
index 0000000..ae6f033
Binary files /dev/null and b/StarPractice (2)/StarPractice/.tools/apache-maven-3.9.6/lib/wagon-provider-api-3.5.3.jar differ
diff --git a/StarPractice (2)/StarPractice/pom.xml b/StarPractice (2)/StarPractice/pom.xml
new file mode 100644
index 0000000..fb4d256
--- /dev/null
+++ b/StarPractice (2)/StarPractice/pom.xml
@@ -0,0 +1,72 @@
+
+ 4.0.0
+ com.starpractice
+ starpractice
+ 1.0.0
+ jar
+
+
+ 21
+ UTF-8
+
+
+
+
+ spigotmc-repo
+ https://hub.spigotmc.org/nexus/content/repositories/snapshots/
+
+
+
+
+
+ org.spigotmc
+ spigot-api
+ 1.21.1-R0.1-SNAPSHOT
+ provided
+
+
+ com.zaxxer
+ HikariCP
+ 5.1.0
+
+
+ org.xerial
+ sqlite-jdbc
+ 3.46.0.0
+
+
+ org.mariadb.jdbc
+ mariadb-java-client
+ 3.3.3
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.12.1
+
+ ${maven.compiler.release}
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.5.3
+
+
+ package
+
+ shade
+
+
+ false
+
+
+
+
+
+
+
diff --git a/StarPractice (2)/StarPractice/reference photos/bug16 (1).png b/StarPractice (2)/StarPractice/reference photos/bug16 (1).png
new file mode 100644
index 0000000..568905a
Binary files /dev/null and b/StarPractice (2)/StarPractice/reference photos/bug16 (1).png differ
diff --git a/StarPractice (2)/StarPractice/reference photos/bug16 (2).png b/StarPractice (2)/StarPractice/reference photos/bug16 (2).png
new file mode 100644
index 0000000..9fb4af6
Binary files /dev/null and b/StarPractice (2)/StarPractice/reference photos/bug16 (2).png differ
diff --git a/StarPractice (2)/StarPractice/reference photos/bug16.png b/StarPractice (2)/StarPractice/reference photos/bug16.png
new file mode 100644
index 0000000..d6cd5bc
Binary files /dev/null and b/StarPractice (2)/StarPractice/reference photos/bug16.png differ
diff --git a/StarPractice (2)/StarPractice/reference photos/bug17.png b/StarPractice (2)/StarPractice/reference photos/bug17.png
new file mode 100644
index 0000000..2514d0a
Binary files /dev/null and b/StarPractice (2)/StarPractice/reference photos/bug17.png differ
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/StarPracticePlugin.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/StarPracticePlugin.java
new file mode 100644
index 0000000..fa64b0f
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/StarPracticePlugin.java
@@ -0,0 +1,294 @@
+package com.starpractice;
+
+import com.starpractice.command.LeaveCommand;
+import com.starpractice.command.PracticeCommand;
+import com.starpractice.command.QueueCommand;
+import com.starpractice.command.SetPracticeSpawnCommand;
+import com.starpractice.command.StarPracticeCommand;
+import com.starpractice.command.SpectateCommand;
+import com.starpractice.command.DuelCommand;
+import com.starpractice.command.FriendCommand;
+import com.starpractice.command.PartyCommand;
+import com.starpractice.gui.GuiManager;
+import com.starpractice.listener.PlayerListener;
+import com.starpractice.manager.ArenaManager;
+import com.starpractice.manager.DuelRequestManager;
+import com.starpractice.manager.FriendManager;
+import com.starpractice.manager.GamemodeManager;
+import com.starpractice.manager.HotbarManager;
+import com.starpractice.manager.KitEditorSessionManager;
+import com.starpractice.manager.MatchManager;
+import com.starpractice.manager.PartyManager;
+import com.starpractice.manager.PartyMatchManager;
+import com.starpractice.manager.PlayerKitManager;
+import com.starpractice.manager.QueueManager;
+import com.starpractice.manager.SettingsManager;
+import com.starpractice.manager.SpectateManager;
+import com.starpractice.manager.StorageManager;
+import com.starpractice.storage.MySqlStorage;
+import com.starpractice.storage.MariaDbSocialStorage;
+import com.starpractice.storage.NoopSocialStorage;
+import com.starpractice.storage.SocialStorage;
+import com.starpractice.storage.SqliteSocialStorage;
+import com.starpractice.storage.Storage;
+import com.starpractice.storage.YmlStorage;
+import com.starpractice.util.ChatInputManager;
+import com.starpractice.util.SchedulerAdapter;
+import com.starpractice.util.Text;
+import com.starpractice.util.WorldEditAdapter;
+import org.bukkit.Bukkit;
+import org.bukkit.plugin.java.JavaPlugin;
+
+public class StarPracticePlugin extends JavaPlugin {
+ private static final boolean TEMP_DISABLE_FRIENDS = true;
+ private static final boolean TEMP_DISABLE_PARTIES = true;
+ private SchedulerAdapter scheduler;
+ private Storage storage;
+ private SocialStorage socialStorage;
+ private StorageManager storageManager;
+ private GamemodeManager gamemodeManager;
+ private ArenaManager arenaManager;
+ private QueueManager queueManager;
+ private MatchManager matchManager;
+ private SpectateManager spectateManager;
+ private HotbarManager hotbarManager;
+ private KitEditorSessionManager kitEditorSessionManager;
+ private SettingsManager settingsManager;
+ private DuelRequestManager duelRequestManager;
+ private FriendManager friendManager;
+ private PartyManager partyManager;
+ private PartyMatchManager partyMatchManager;
+ private PlayerKitManager playerKitManager;
+ private GuiManager guiManager;
+ private ChatInputManager chatInputManager;
+ private WorldEditAdapter worldEditAdapter;
+
+ @Override
+ public void onEnable() {
+ saveDefaultConfig();
+ enforceTemporaryFeatureDisables();
+
+ scheduler = SchedulerAdapter.create(this);
+ worldEditAdapter = new WorldEditAdapter(this, scheduler);
+
+ String type = getConfig().getString("storage.type", "YML");
+ if ("MYSQL".equalsIgnoreCase(type)) {
+ storage = new MySqlStorage(this);
+ } else {
+ storage = new YmlStorage(this);
+ }
+
+ try {
+ storage.init();
+ } catch (Exception e) {
+ getLogger().severe("Storage failed to initialize: " + e.getMessage());
+ Bukkit.getPluginManager().disablePlugin(this);
+ return;
+ }
+
+ if (areSocialFeaturesTemporarilyDisabled()) {
+ socialStorage = new NoopSocialStorage();
+ } else {
+ String socialType = getConfig().getString("social.storage.type", "SQLITE");
+ if ("MARIADB".equalsIgnoreCase(socialType)) {
+ socialStorage = new MariaDbSocialStorage(this);
+ } else {
+ socialStorage = new SqliteSocialStorage(this);
+ }
+ try {
+ socialStorage.init();
+ } catch (Exception e) {
+ getLogger().warning("Social storage failed to initialize: " + e.getMessage());
+ socialStorage = new NoopSocialStorage();
+ }
+ socialStorage.clearParties();
+ }
+
+ gamemodeManager = new GamemodeManager(this);
+ arenaManager = new ArenaManager(this, worldEditAdapter);
+ spectateManager = new SpectateManager(this);
+ hotbarManager = new HotbarManager(this);
+ kitEditorSessionManager = new KitEditorSessionManager();
+ matchManager = new MatchManager(this, worldEditAdapter);
+ queueManager = new QueueManager(this);
+ settingsManager = new SettingsManager(this);
+ duelRequestManager = new DuelRequestManager(this);
+ friendManager = new FriendManager(this);
+ partyManager = new PartyManager(this);
+ partyMatchManager = new PartyMatchManager(this, worldEditAdapter);
+ playerKitManager = new PlayerKitManager(this);
+ storageManager = new StorageManager(this, storage, socialStorage);
+ guiManager = new GuiManager(this);
+ chatInputManager = new ChatInputManager(this);
+
+ settingsManager.load();
+ storageManager.loadAll();
+ disableSocialFeatureRuntime();
+
+ getServer().getPluginManager().registerEvents(guiManager, this);
+ getServer().getPluginManager().registerEvents(chatInputManager, this);
+ getServer().getPluginManager().registerEvents(new PlayerListener(this), this);
+
+ registerCommand("practiceeditor", new PracticeCommand(this));
+ registerCommand("queue", new QueueCommand(this));
+ registerCommand("leave", new LeaveCommand(this));
+ registerCommand("spectate", new SpectateCommand(this));
+ registerCommand("setpracticespawn", new SetPracticeSpawnCommand(this));
+ registerCommand("kiteditor", new com.starpractice.command.KitEditorCommand(this));
+ DuelCommand duelCommand = new DuelCommand(this);
+ if (getCommand("duel") != null) {
+ getCommand("duel").setExecutor(duelCommand);
+ getCommand("duel").setTabCompleter(duelCommand);
+ } else {
+ getLogger().warning("Command 'duel' is missing from plugin.yml.");
+ }
+ StarPracticeCommand starPracticeCommand = new StarPracticeCommand(this);
+ if (getCommand("starpractice") != null) {
+ getCommand("starpractice").setExecutor(starPracticeCommand);
+ getCommand("starpractice").setTabCompleter(starPracticeCommand);
+ } else {
+ getLogger().warning("Command 'starpractice' is missing from plugin.yml.");
+ }
+ registerCommand("settings", new com.starpractice.command.SettingsCommand(this));
+ registerCommand("friend", new FriendCommand(this));
+ registerCommand("party", new PartyCommand(this));
+
+ getLogger().info("StarPractice enabled.");
+ if (!worldEditAdapter.isAvailable()) {
+ getLogger().warning("WorldEdit/FAWE not found. Arena snapshots and rollback are disabled.");
+ }
+ }
+
+ @Override
+ public void onDisable() {
+ if (storageManager != null) {
+ storageManager.saveAll();
+ if (playerKitManager != null) {
+ storageManager.savePlayerKits(playerKitManager.exportData());
+ }
+ }
+ if (settingsManager != null) {
+ settingsManager.save();
+ }
+ }
+
+ public SchedulerAdapter getScheduler() {
+ return scheduler;
+ }
+
+ public GamemodeManager getGamemodeManager() {
+ return gamemodeManager;
+ }
+
+ public ArenaManager getArenaManager() {
+ return arenaManager;
+ }
+
+ public QueueManager getQueueManager() {
+ return queueManager;
+ }
+
+ public MatchManager getMatchManager() {
+ return matchManager;
+ }
+
+ public SpectateManager getSpectateManager() {
+ return spectateManager;
+ }
+
+ public HotbarManager getHotbarManager() {
+ return hotbarManager;
+ }
+
+ public KitEditorSessionManager getKitEditorSessionManager() {
+ return kitEditorSessionManager;
+ }
+
+ public SettingsManager getSettingsManager() {
+ return settingsManager;
+ }
+
+ public DuelRequestManager getDuelRequestManager() {
+ return duelRequestManager;
+ }
+
+ public FriendManager getFriendManager() {
+ return friendManager;
+ }
+
+ public PartyManager getPartyManager() {
+ return partyManager;
+ }
+
+ public PartyMatchManager getPartyMatchManager() {
+ return partyMatchManager;
+ }
+
+ public PlayerKitManager getPlayerKitManager() {
+ return playerKitManager;
+ }
+
+ public GuiManager getGuiManager() {
+ return guiManager;
+ }
+
+ public ChatInputManager getChatInputManager() {
+ return chatInputManager;
+ }
+
+ public StorageManager getStorageManager() {
+ return storageManager;
+ }
+
+ public SocialStorage getSocialStorage() {
+ return socialStorage;
+ }
+
+ public WorldEditAdapter getWorldEditAdapter() {
+ return worldEditAdapter;
+ }
+
+ public void sendMessage(org.bukkit.command.CommandSender sender, String msg) {
+ sender.sendMessage(Text.color(getConfig().getString("messages.prefix", "&eStarPractice &7") + msg));
+ }
+
+ public String getAdminPermission() {
+ return getConfig().getString("permissions.admin", "practice.admin");
+ }
+
+ public void enforceTemporaryFeatureDisables() {
+ if (TEMP_DISABLE_FRIENDS) {
+ getConfig().set("features.friends.enabled", false);
+ }
+ if (TEMP_DISABLE_PARTIES) {
+ getConfig().set("features.parties.enabled", false);
+ }
+ }
+
+ public void disableSocialFeatureRuntime() {
+ if (friendManager != null && !getConfig().getBoolean("features.friends.enabled", true)) {
+ friendManager.clearAll();
+ }
+ if (partyManager != null && !getConfig().getBoolean("features.parties.enabled", true)) {
+ partyManager.clearAll();
+ }
+ if (partyMatchManager != null && !getConfig().getBoolean("features.parties.enabled", true)) {
+ partyMatchManager.clearAllRuntime();
+ }
+ }
+
+ private boolean areSocialFeaturesTemporarilyDisabled() {
+ return TEMP_DISABLE_FRIENDS && TEMP_DISABLE_PARTIES;
+ }
+
+ private void registerCommand(String name, org.bukkit.command.CommandExecutor executor) {
+ if (getCommand(name) == null) {
+ getLogger().warning("Command '" + name + "' is missing from plugin.yml.");
+ return;
+ }
+ getCommand(name).setExecutor(executor);
+ if (executor instanceof org.bukkit.command.TabCompleter completer) {
+ getCommand(name).setTabCompleter(completer);
+ }
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/DuelCommand.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/DuelCommand.java
new file mode 100644
index 0000000..637e4bb
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/DuelCommand.java
@@ -0,0 +1,110 @@
+package com.starpractice.command;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.gui.DuelGamemodeGui;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.bukkit.Bukkit;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabCompleter;
+import org.bukkit.entity.Player;
+
+public class DuelCommand implements CommandExecutor, TabCompleter {
+ private final StarPracticePlugin plugin;
+
+ public DuelCommand(StarPracticePlugin plugin) {
+ this.plugin = plugin;
+ }
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+ if (!(sender instanceof Player player)) {
+ sender.sendMessage("Only players can use this command.");
+ return true;
+ }
+ if (!player.hasPermission("practice.duel")) {
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.no-permission"));
+ return true;
+ }
+ if (args.length == 0) {
+ plugin.sendMessage(player, "&cUsage: /duel ");
+ return true;
+ }
+ if ("accept".equalsIgnoreCase(args[0]) || "deny".equalsIgnoreCase(args[0])) {
+ if (args.length < 2) {
+ plugin.sendMessage(player, "&cUsage: /duel " + args[0].toLowerCase() + " ");
+ return true;
+ }
+ Player requester = Bukkit.getPlayer(args[1]);
+ if (requester == null) {
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.duel-request-offline", "&cThat player is offline."));
+ return true;
+ }
+ if ("accept".equalsIgnoreCase(args[0])) {
+ plugin.getDuelRequestManager().accept(player, requester);
+ } else {
+ plugin.getDuelRequestManager().deny(player, requester);
+ }
+ return true;
+ }
+ Player target = Bukkit.getPlayer(args[0]);
+ if (target == null || !target.isOnline()) {
+ plugin.sendMessage(player, "&cPlayer not found.");
+ return true;
+ }
+ if (target.getUniqueId().equals(player.getUniqueId())) {
+ plugin.sendMessage(player, "&cYou cannot duel yourself.");
+ return true;
+ }
+ if (plugin.getMatchManager().isInMatch(player) || plugin.getSpectateManager().isSpectating(player)) {
+ plugin.sendMessage(player, "&cYou cannot duel right now.");
+ return true;
+ }
+ if (plugin.getMatchManager().isInMatch(target) || plugin.getSpectateManager().isSpectating(target)) {
+ plugin.sendMessage(player, "&cThat player is busy.");
+ return true;
+ }
+ new DuelGamemodeGui(plugin, player, target).open();
+ return true;
+ }
+
+ @Override
+ public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+ if (!(sender instanceof Player player)) {
+ return Collections.emptyList();
+ }
+ if (args.length == 1) {
+ String prefix = args[0].toLowerCase();
+ List names = new ArrayList<>();
+ for (Player online : Bukkit.getOnlinePlayers()) {
+ if (player.getUniqueId().equals(online.getUniqueId())) {
+ continue;
+ }
+ if (online.getName().toLowerCase().startsWith(prefix)) {
+ names.add(online.getName());
+ }
+ }
+ if ("accept".startsWith(prefix)) {
+ names.add("accept");
+ }
+ if ("deny".startsWith(prefix)) {
+ names.add("deny");
+ }
+ return names;
+ }
+ if (args.length == 2 && ("accept".equalsIgnoreCase(args[0]) || "deny".equalsIgnoreCase(args[0]))) {
+ String prefix = args[1].toLowerCase();
+ List names = new ArrayList<>();
+ for (String name : plugin.getDuelRequestManager().getPendingRequesterNames(player)) {
+ if (name.toLowerCase().startsWith(prefix)) {
+ names.add(name);
+ }
+ }
+ return names;
+ }
+ return Collections.emptyList();
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/FriendCommand.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/FriendCommand.java
new file mode 100644
index 0000000..e2b8cdc
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/FriendCommand.java
@@ -0,0 +1,103 @@
+package com.starpractice.command;
+
+import com.starpractice.StarPracticePlugin;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.bukkit.Bukkit;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabCompleter;
+import org.bukkit.entity.Player;
+
+public class FriendCommand implements CommandExecutor, TabCompleter {
+ private final StarPracticePlugin plugin;
+
+ public FriendCommand(StarPracticePlugin plugin) {
+ this.plugin = plugin;
+ }
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+ if (!(sender instanceof Player player)) {
+ sender.sendMessage("Only players can use this command.");
+ return true;
+ }
+ if (!plugin.getConfig().getBoolean("features.friends.enabled", true)) {
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.friend-feature-disabled", "&cFriends are disabled on this server."));
+ return true;
+ }
+ if (args.length == 0) {
+ plugin.sendMessage(player, "&cUsage: /friend [player]");
+ return true;
+ }
+ String sub = args[0].toLowerCase();
+ if ("list".equals(sub)) {
+ List friends = plugin.getFriendManager().getFriendNames(player);
+ if (friends.isEmpty()) {
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.friend-list-empty", "&eYou have no friends online."));
+ return true;
+ }
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.friend-list", "&aFriends online: &f%list%")
+ .replace("%list%", String.join(", ", friends)));
+ return true;
+ }
+ if (args.length < 2) {
+ plugin.sendMessage(player, "&cUsage: /friend " + sub + " ");
+ return true;
+ }
+ Player target = Bukkit.getPlayer(args[1]);
+ if (target == null || !target.isOnline()) {
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.friend-offline", "&cThat player is offline."));
+ return true;
+ }
+ if (target.getUniqueId().equals(player.getUniqueId())) {
+ plugin.sendMessage(player, "&cYou cannot target yourself.");
+ return true;
+ }
+
+ switch (sub) {
+ case "add" -> plugin.getFriendManager().sendRequest(player, target);
+ case "remove" -> plugin.getFriendManager().remove(player, target);
+ case "accept" -> plugin.getFriendManager().accept(player, target);
+ case "deny" -> plugin.getFriendManager().deny(player, target);
+ default -> plugin.sendMessage(player, "&cUsage: /friend [player]");
+ }
+ return true;
+ }
+
+ @Override
+ public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+ if (!(sender instanceof Player player)) {
+ return Collections.emptyList();
+ }
+ if (args.length == 1) {
+ List options = new ArrayList<>();
+ for (String opt : new String[] { "add", "remove", "list", "accept", "deny" }) {
+ if (opt.startsWith(args[0].toLowerCase())) {
+ options.add(opt);
+ }
+ }
+ return options;
+ }
+ if (args.length == 2) {
+ String sub = args[0].toLowerCase();
+ if (!List.of("add", "remove", "accept", "deny").contains(sub)) {
+ return Collections.emptyList();
+ }
+ String prefix = args[1].toLowerCase();
+ List names = new ArrayList<>();
+ for (Player online : Bukkit.getOnlinePlayers()) {
+ if (online.getUniqueId().equals(player.getUniqueId())) {
+ continue;
+ }
+ if (online.getName().toLowerCase().startsWith(prefix)) {
+ names.add(online.getName());
+ }
+ }
+ return names;
+ }
+ return Collections.emptyList();
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/KitEditorCommand.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/KitEditorCommand.java
new file mode 100644
index 0000000..35b21d4
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/KitEditorCommand.java
@@ -0,0 +1,30 @@
+package com.starpractice.command;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.gui.KitEditorGamemodeGui;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public class KitEditorCommand implements CommandExecutor {
+ private final StarPracticePlugin plugin;
+
+ public KitEditorCommand(StarPracticePlugin plugin) {
+ this.plugin = plugin;
+ }
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+ if (!(sender instanceof Player player)) {
+ sender.sendMessage("Players only.");
+ return true;
+ }
+ if (!player.hasPermission("practice.kiteditor")) {
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.no-permission"));
+ return true;
+ }
+ new KitEditorGamemodeGui(plugin, player).open();
+ return true;
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/LeaveCommand.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/LeaveCommand.java
new file mode 100644
index 0000000..5dccc05
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/LeaveCommand.java
@@ -0,0 +1,37 @@
+package com.starpractice.command;
+
+import com.starpractice.StarPracticePlugin;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public class LeaveCommand implements CommandExecutor {
+ private final StarPracticePlugin plugin;
+
+ public LeaveCommand(StarPracticePlugin plugin) {
+ this.plugin = plugin;
+ }
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+ if (!(sender instanceof Player player)) {
+ sender.sendMessage("Only players can use this command.");
+ return true;
+ }
+ if (plugin.getSpectateManager().isSpectating(player)) {
+ plugin.getSpectateManager().leave(player);
+ return true;
+ }
+ if (plugin.getMatchManager().isInMatch(player)) {
+ plugin.getMatchManager().forfeit(player);
+ return true;
+ }
+ if (plugin.getPartyMatchManager().isInMatch(player)) {
+ plugin.getPartyMatchManager().leaveMatch(player);
+ return true;
+ }
+ plugin.getQueueManager().leaveQueue(player);
+ return true;
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/PartyCommand.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/PartyCommand.java
new file mode 100644
index 0000000..429d8dd
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/PartyCommand.java
@@ -0,0 +1,167 @@
+package com.starpractice.command;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.gui.PartyGamemodeGui;
+import com.starpractice.gui.PartyModeGui;
+import com.starpractice.model.Party;
+import com.starpractice.model.PartyMatch;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.bukkit.Bukkit;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabCompleter;
+import org.bukkit.entity.Player;
+
+public class PartyCommand implements CommandExecutor, TabCompleter {
+ private final StarPracticePlugin plugin;
+
+ public PartyCommand(StarPracticePlugin plugin) {
+ this.plugin = plugin;
+ }
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+ if (!(sender instanceof Player player)) {
+ sender.sendMessage("Only players can use this command.");
+ return true;
+ }
+ if (!plugin.getConfig().getBoolean("features.parties.enabled", true)) {
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.party-feature-disabled", "&cParties are disabled on this server."));
+ return true;
+ }
+ if (args.length == 0) {
+ plugin.sendMessage(player, "&cUsage: /party ");
+ return true;
+ }
+ String sub = args[0].toLowerCase();
+ boolean inMatch = plugin.getMatchManager().isInMatch(player)
+ || plugin.getPartyMatchManager().isInMatch(player);
+ if (inMatch && !List.of("leave", "disband", "list").contains(sub)) {
+ plugin.sendMessage(player, "&cYou can only use /party leave, /party disband, or /party list while in a match.");
+ return true;
+ }
+ if ("list".equals(sub)) {
+ plugin.getPartyManager().list(player);
+ return true;
+ }
+ if ("leave".equals(sub)) {
+ plugin.getPartyManager().leave(player);
+ return true;
+ }
+ if ("disband".equals(sub)) {
+ plugin.getPartyManager().disband(player);
+ return true;
+ }
+ if ("play".equals(sub)) {
+ Party party = plugin.getPartyManager().getParty(player.getUniqueId());
+ if (party == null) {
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.party-none", "&cYou are not in a party."));
+ return true;
+ }
+ if (!party.getLeader().equals(player.getUniqueId())) {
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.party-not-leader", "&cOnly the party leader can do that."));
+ return true;
+ }
+ if (args.length >= 2) {
+ PartyMatch.Mode mode = parseMode(args[1]);
+ if (mode != null) {
+ new PartyGamemodeGui(plugin, player, mode).open();
+ return true;
+ }
+ }
+ new PartyModeGui(plugin, player).open();
+ return true;
+ }
+ if (args.length < 2) {
+ plugin.sendMessage(player, "&cUsage: /party " + sub + " ");
+ return true;
+ }
+ Player target = Bukkit.getPlayer(args[1]);
+ if (target == null || !target.isOnline()) {
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.party-offline", "&cThat player is offline."));
+ return true;
+ }
+ if (target.getUniqueId().equals(player.getUniqueId())) {
+ plugin.sendMessage(player, "&cYou cannot target yourself.");
+ return true;
+ }
+
+ switch (sub) {
+ case "invite" -> plugin.getPartyManager().invite(player, target);
+ case "accept" -> plugin.getPartyManager().accept(player, target);
+ case "deny" -> plugin.getPartyManager().deny(player, target);
+ case "kick" -> plugin.getPartyManager().kick(player, target);
+ case "leader" -> plugin.getPartyManager().promote(player, target);
+ default -> plugin.sendMessage(player, "&cUsage: /party ");
+ }
+ return true;
+ }
+
+ @Override
+ public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+ if (!(sender instanceof Player player)) {
+ return Collections.emptyList();
+ }
+ if (args.length == 1) {
+ List options = new ArrayList<>();
+ for (String opt : new String[] { "invite", "accept", "deny", "kick", "disband", "leader", "list", "leave", "play" }) {
+ if (opt.startsWith(args[0].toLowerCase())) {
+ options.add(opt);
+ }
+ }
+ return options;
+ }
+ if (args.length == 2) {
+ String sub = args[0].toLowerCase();
+ if ("play".equals(sub)) {
+ List modes = new ArrayList<>();
+ for (String mode : new String[] { "1v1", "2v2", "ffa" }) {
+ if (mode.startsWith(args[1].toLowerCase())) {
+ modes.add(mode);
+ }
+ }
+ return modes;
+ }
+ if (!List.of("invite", "kick", "leader", "accept", "deny").contains(sub)) {
+ return Collections.emptyList();
+ }
+ String prefix = args[1].toLowerCase();
+ List names = new ArrayList<>();
+ if ("kick".equals(sub) || "leader".equals(sub)) {
+ Party party = plugin.getPartyManager().getParty(player.getUniqueId());
+ if (party == null) {
+ return Collections.emptyList();
+ }
+ for (String name : plugin.getPartyManager().getMemberNames(party)) {
+ if (name.toLowerCase().startsWith(prefix)) {
+ names.add(name);
+ }
+ }
+ return names;
+ }
+ for (Player online : Bukkit.getOnlinePlayers()) {
+ if (online.getUniqueId().equals(player.getUniqueId())) {
+ continue;
+ }
+ if (online.getName().toLowerCase().startsWith(prefix)) {
+ names.add(online.getName());
+ }
+ }
+ return names;
+ }
+ return Collections.emptyList();
+ }
+
+ private PartyMatch.Mode parseMode(String input) {
+ String lower = input.toLowerCase();
+ return switch (lower) {
+ case "1v1" -> PartyMatch.Mode.ONE_V_ONE;
+ case "2v2" -> PartyMatch.Mode.TWO_V_TWO;
+ case "ffa" -> PartyMatch.Mode.FFA;
+ default -> null;
+ };
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/PracticeCommand.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/PracticeCommand.java
new file mode 100644
index 0000000..66dd68d
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/PracticeCommand.java
@@ -0,0 +1,286 @@
+package com.starpractice.command;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.gui.ArenaEditGui;
+import com.starpractice.gui.ArenaListGui;
+import com.starpractice.gui.ConfirmDeleteGui;
+import com.starpractice.gui.GamemodeEditGui;
+import com.starpractice.gui.GamemodeListGui;
+import com.starpractice.gui.MainAdminGui;
+import com.starpractice.model.Arena;
+import com.starpractice.model.Gamemode;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabCompleter;
+import org.bukkit.entity.Player;
+
+public class PracticeCommand implements CommandExecutor, TabCompleter {
+ private final StarPracticePlugin plugin;
+
+ public PracticeCommand(StarPracticePlugin plugin) {
+ this.plugin = plugin;
+ }
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+ if (!(sender instanceof Player player)) {
+ sender.sendMessage("Only players can use this command.");
+ return true;
+ }
+ if (!player.hasPermission(plugin.getAdminPermission())) {
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.no-permission"));
+ return true;
+ }
+ if (args.length == 0) {
+ new MainAdminGui(plugin, player).open();
+ return true;
+ }
+ int index = 0;
+ if ("editor".equalsIgnoreCase(args[0])) {
+ index = 1;
+ }
+ if (index >= args.length) {
+ new MainAdminGui(plugin, player).open();
+ return true;
+ }
+ String section = args[index].toLowerCase();
+ String action = args.length > index + 1 ? args[index + 1].toLowerCase() : "";
+ String targetName = args.length > index + 2 ? args[index + 2] : "";
+
+ if ("gamemodes".equals(section)) {
+ handleGamemode(player, action, targetName);
+ return true;
+ }
+ if ("arenas".equals(section)) {
+ handleArena(player, action, targetName);
+ return true;
+ }
+ new MainAdminGui(plugin, player).open();
+ return true;
+ }
+
+ private void handleGamemode(Player player, String action, String targetName) {
+ switch (action) {
+ case "add" -> {
+ if (targetName.isEmpty()) {
+ player.closeInventory();
+ plugin.sendMessage(player, "&eType the gamemode name in chat.");
+ plugin.getChatInputManager().prompt(player, input -> {
+ String name = input.trim();
+ if (name.isEmpty()) {
+ name = "mode";
+ }
+ createGamemode(player, name);
+ });
+ return;
+ }
+ createGamemode(player, targetName);
+ }
+ case "remove" -> {
+ if (targetName.isEmpty()) {
+ new GamemodeListGui(plugin, player, GamemodeListGui.Mode.REMOVE).open();
+ return;
+ }
+ Gamemode mode = findGamemode(targetName);
+ if (mode == null) {
+ plugin.sendMessage(player, "&cGamemode not found.");
+ return;
+ }
+ new ConfirmDeleteGui(plugin, player, () -> {
+ plugin.getGamemodeManager().remove(mode.getId());
+ plugin.getStorageManager().saveGamemodes();
+ plugin.sendMessage(player, "&cGamemode removed.");
+ new GamemodeListGui(plugin, player, GamemodeListGui.Mode.REMOVE).open();
+ }, () -> new GamemodeListGui(plugin, player, GamemodeListGui.Mode.REMOVE).open()).open();
+ }
+ case "edit" -> {
+ if (targetName.isEmpty()) {
+ new GamemodeListGui(plugin, player, GamemodeListGui.Mode.EDIT).open();
+ return;
+ }
+ Gamemode mode = findGamemode(targetName);
+ if (mode == null) {
+ plugin.sendMessage(player, "&cGamemode not found.");
+ return;
+ }
+ new GamemodeEditGui(plugin, player, mode).open();
+ }
+ default -> new GamemodeListGui(plugin, player, GamemodeListGui.Mode.EDIT).open();
+ }
+ }
+
+ private void handleArena(Player player, String action, String targetName) {
+ switch (action) {
+ case "add" -> {
+ if (targetName.isEmpty()) {
+ player.closeInventory();
+ plugin.sendMessage(player, "&eType the arena name in chat.");
+ plugin.getChatInputManager().prompt(player, input -> {
+ String name = input.trim();
+ if (name.isEmpty()) {
+ name = "arena";
+ }
+ createArena(player, name);
+ });
+ return;
+ }
+ createArena(player, targetName);
+ }
+ case "remove" -> {
+ if (targetName.isEmpty()) {
+ new ArenaListGui(plugin, player, ArenaListGui.Mode.REMOVE).open();
+ return;
+ }
+ Arena arena = findArena(targetName);
+ if (arena == null) {
+ plugin.sendMessage(player, "&cArena not found.");
+ return;
+ }
+ new ConfirmDeleteGui(plugin, player, () -> {
+ plugin.getArenaManager().remove(arena.getId());
+ plugin.getStorageManager().saveArenas();
+ plugin.sendMessage(player, "&cArena removed.");
+ new ArenaListGui(plugin, player, ArenaListGui.Mode.REMOVE).open();
+ }, () -> new ArenaListGui(plugin, player, ArenaListGui.Mode.REMOVE).open()).open();
+ }
+ case "edit" -> {
+ if (targetName.isEmpty()) {
+ new ArenaListGui(plugin, player, ArenaListGui.Mode.EDIT).open();
+ return;
+ }
+ Arena arena = findArena(targetName);
+ if (arena == null) {
+ plugin.sendMessage(player, "&cArena not found.");
+ return;
+ }
+ new ArenaEditGui(plugin, player, arena).open();
+ }
+ default -> new ArenaListGui(plugin, player, ArenaListGui.Mode.EDIT).open();
+ }
+ }
+
+ private void createGamemode(Player player, String name) {
+ String id = plugin.getGamemodeManager().generateId(name);
+ Gamemode mode = new Gamemode(id);
+ mode.setDisplayName(name);
+ plugin.getGamemodeManager().add(mode);
+ plugin.getStorageManager().saveGamemodes();
+ new GamemodeEditGui(plugin, player, mode).open();
+ }
+
+ private void createArena(Player player, String name) {
+ String id = plugin.getArenaManager().generateId(name);
+ Arena arena = new Arena(id);
+ arena.setDisplayName(name);
+ plugin.getArenaManager().add(arena);
+ plugin.getStorageManager().saveArenas();
+ new ArenaEditGui(plugin, player, arena).open();
+ }
+
+ private Gamemode findGamemode(String name) {
+ if (name == null) {
+ return null;
+ }
+ Gamemode byId = plugin.getGamemodeManager().getById(name.toLowerCase());
+ if (byId != null) {
+ return byId;
+ }
+ for (Gamemode mode : plugin.getGamemodeManager().getAll()) {
+ if (mode.getDisplayName().equalsIgnoreCase(name) || mode.getId().equalsIgnoreCase(name)) {
+ return mode;
+ }
+ }
+ return null;
+ }
+
+ private Arena findArena(String name) {
+ if (name == null) {
+ return null;
+ }
+ Arena byId = plugin.getArenaManager().getById(name.toLowerCase());
+ if (byId != null) {
+ return byId;
+ }
+ for (Arena arena : plugin.getArenaManager().getAll()) {
+ if (arena.getDisplayName().equalsIgnoreCase(name) || arena.getId().equalsIgnoreCase(name)) {
+ return arena;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+ if (!(sender instanceof Player)) {
+ return Collections.emptyList();
+ }
+ int index = 0;
+ if (args.length > 0 && "editor".equalsIgnoreCase(args[0])) {
+ index = 1;
+ }
+ if (args.length == 1) {
+ List options = new ArrayList<>();
+ options.add("gamemodes");
+ options.add("arenas");
+ options.add("editor");
+ return filter(options, args[0]);
+ }
+ if (args.length == index + 1) {
+ return filter(List.of("gamemodes", "arenas"), args[index]);
+ }
+ if (args.length == index + 2) {
+ return filter(List.of("add", "edit", "remove"), args[index + 1]);
+ }
+ if (args.length == index + 3) {
+ String section = args[index].toLowerCase();
+ String action = args[index + 1].toLowerCase();
+ if (!("edit".equals(action) || "remove".equals(action))) {
+ return Collections.emptyList();
+ }
+ if ("gamemodes".equals(section)) {
+ return filter(listGamemodeNames(), args[index + 2]);
+ }
+ if ("arenas".equals(section)) {
+ return filter(listArenaNames(), args[index + 2]);
+ }
+ }
+ return Collections.emptyList();
+ }
+
+ private List listGamemodeNames() {
+ List names = new ArrayList<>();
+ for (Gamemode mode : plugin.getGamemodeManager().getAll()) {
+ names.add(mode.getId());
+ if (!mode.getDisplayName().contains(" ")) {
+ names.add(mode.getDisplayName());
+ }
+ }
+ return names;
+ }
+
+ private List listArenaNames() {
+ List names = new ArrayList<>();
+ for (Arena arena : plugin.getArenaManager().getAll()) {
+ names.add(arena.getId());
+ if (!arena.getDisplayName().contains(" ")) {
+ names.add(arena.getDisplayName());
+ }
+ }
+ return names;
+ }
+
+ private List filter(List options, String prefix) {
+ String lower = prefix == null ? "" : prefix.toLowerCase();
+ List matches = new ArrayList<>();
+ for (String option : options) {
+ if (option.toLowerCase().startsWith(lower)) {
+ matches.add(option);
+ }
+ }
+ return matches;
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/QueueCommand.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/QueueCommand.java
new file mode 100644
index 0000000..5ee8bb3
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/QueueCommand.java
@@ -0,0 +1,35 @@
+package com.starpractice.command;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.gui.QueueGui;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public class QueueCommand implements CommandExecutor {
+ private final StarPracticePlugin plugin;
+
+ public QueueCommand(StarPracticePlugin plugin) {
+ this.plugin = plugin;
+ }
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+ if (!(sender instanceof Player player)) {
+ sender.sendMessage("Only players can use this command.");
+ return true;
+ }
+ if (!player.hasPermission("practice.queue")) {
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.no-permission"));
+ return true;
+ }
+ if (plugin.getConfig().getBoolean("features.parties.enabled", true)
+ && plugin.getPartyManager().getParty(player.getUniqueId()) != null) {
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.party-queue-block", "&cYou cannot queue while in a party."));
+ return true;
+ }
+ new QueueGui(plugin, player).open();
+ return true;
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/SetPracticeSpawnCommand.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/SetPracticeSpawnCommand.java
new file mode 100644
index 0000000..370fbd9
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/SetPracticeSpawnCommand.java
@@ -0,0 +1,31 @@
+package com.starpractice.command;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.SpawnData;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public class SetPracticeSpawnCommand implements CommandExecutor {
+ private final StarPracticePlugin plugin;
+
+ public SetPracticeSpawnCommand(StarPracticePlugin plugin) {
+ this.plugin = plugin;
+ }
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+ if (!(sender instanceof Player player)) {
+ sender.sendMessage("Only players can use this command.");
+ return true;
+ }
+ if (!player.hasPermission(plugin.getAdminPermission())) {
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.no-permission"));
+ return true;
+ }
+ plugin.getHotbarManager().setSpawnData(new SpawnData(player.getLocation()));
+ plugin.sendMessage(player, "&aPractice spawn set.");
+ return true;
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/SettingsCommand.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/SettingsCommand.java
new file mode 100644
index 0000000..1b86da7
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/SettingsCommand.java
@@ -0,0 +1,34 @@
+package com.starpractice.command;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.gui.SettingsGui;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public class SettingsCommand implements CommandExecutor {
+ private final StarPracticePlugin plugin;
+
+ public SettingsCommand(StarPracticePlugin plugin) {
+ this.plugin = plugin;
+ }
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+ if (!(sender instanceof Player player)) {
+ sender.sendMessage("Only players can use this command.");
+ return true;
+ }
+ boolean permEnabled = plugin.getConfig().getBoolean("settings.command.permission.enabled", false);
+ if (permEnabled) {
+ String node = plugin.getConfig().getString("settings.command.permission.node", "practice.settings");
+ if (!player.hasPermission(node)) {
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.no-permission"));
+ return true;
+ }
+ }
+ new SettingsGui(plugin, player).open();
+ return true;
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/SpectateCommand.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/SpectateCommand.java
new file mode 100644
index 0000000..167d85d
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/SpectateCommand.java
@@ -0,0 +1,39 @@
+package com.starpractice.command;
+
+import com.starpractice.StarPracticePlugin;
+import org.bukkit.Bukkit;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public class SpectateCommand implements CommandExecutor {
+ private final StarPracticePlugin plugin;
+
+ public SpectateCommand(StarPracticePlugin plugin) {
+ this.plugin = plugin;
+ }
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+ if (!(sender instanceof Player player)) {
+ sender.sendMessage("Only players can use this command.");
+ return true;
+ }
+ if (!player.hasPermission("practice.spectate")) {
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.no-permission"));
+ return true;
+ }
+ if (args.length == 0) {
+ plugin.sendMessage(player, "&cUsage: /spectate ");
+ return true;
+ }
+ Player target = Bukkit.getPlayer(args[0]);
+ if (target == null) {
+ plugin.sendMessage(player, "&cPlayer not found.");
+ return true;
+ }
+ plugin.getSpectateManager().spectate(player, target);
+ return true;
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/StarPracticeCommand.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/StarPracticeCommand.java
new file mode 100644
index 0000000..f855892
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/command/StarPracticeCommand.java
@@ -0,0 +1,48 @@
+package com.starpractice.command;
+
+import com.starpractice.StarPracticePlugin;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabCompleter;
+import org.bukkit.entity.Player;
+
+public class StarPracticeCommand implements CommandExecutor, TabCompleter {
+ private final StarPracticePlugin plugin;
+
+ public StarPracticeCommand(StarPracticePlugin plugin) {
+ this.plugin = plugin;
+ }
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+ if (args.length == 0 || args[0].equalsIgnoreCase("version")) {
+ plugin.sendMessage(sender, "&aStarPractice v" + plugin.getDescription().getVersion() + " &7by Starified");
+ return true;
+ }
+ if (args[0].equalsIgnoreCase("reload")) {
+ if (sender instanceof Player player && !player.hasPermission(plugin.getAdminPermission())) {
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.no-permission"));
+ return true;
+ }
+ plugin.reloadConfig();
+ plugin.enforceTemporaryFeatureDisables();
+ plugin.disableSocialFeatureRuntime();
+ plugin.sendMessage(sender, "&aConfig reloaded.");
+ return true;
+ }
+ plugin.sendMessage(sender, "&cUsage: /starpractice ");
+ return true;
+ }
+
+ @Override
+ public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+ if (args.length == 1) {
+ return Arrays.asList("version", "reload");
+ }
+ return Collections.emptyList();
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/AbstractGui.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/AbstractGui.java
new file mode 100644
index 0000000..5d39abb
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/AbstractGui.java
@@ -0,0 +1,87 @@
+package com.starpractice.gui;
+
+import com.starpractice.util.Text;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Consumer;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.event.inventory.InventoryDragEvent;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.InventoryHolder;
+import org.bukkit.inventory.ItemStack;
+
+public abstract class AbstractGui implements InventoryHolder {
+ protected final Player player;
+ protected final java.util.UUID ownerId;
+ protected final int size;
+ protected final String title;
+ protected final Map> actions = new HashMap<>();
+ protected Inventory inventory;
+
+ protected AbstractGui(Player player, int size, String title) {
+ this.player = player;
+ this.ownerId = player.getUniqueId();
+ this.size = size;
+ this.title = Text.color(title);
+ }
+
+ public void open() {
+ inventory = Bukkit.createInventory(this, size, title);
+ draw(inventory);
+ player.openInventory(inventory);
+ }
+
+ protected abstract void draw(Inventory inventory);
+
+ protected void fillBackground(ItemStack item) {
+ if (item == null) {
+ return;
+ }
+ for (int i = 0; i < size; i++) {
+ inventory.setItem(i, item);
+ }
+ }
+
+ protected void setItem(int slot, ItemStack item, Consumer action) {
+ inventory.setItem(slot, item);
+ if (action != null) {
+ actions.put(slot, action);
+ }
+ }
+
+ public void onClick(InventoryClickEvent event) {
+ if (event.getClickedInventory() == null) {
+ return;
+ }
+ if (event.getView().getTopInventory().getHolder() != this) {
+ return;
+ }
+ if (event.getRawSlot() < 0 || event.getRawSlot() >= size) {
+ event.setCancelled(true);
+ return;
+ }
+ event.setCancelled(true);
+ Consumer action = actions.get(event.getRawSlot());
+ if (action != null) {
+ action.accept(event);
+ }
+ }
+
+ public void onDrag(InventoryDragEvent event) {
+ if (event.getView().getTopInventory().getHolder() != this) {
+ return;
+ }
+ event.setCancelled(true);
+ }
+
+ @Override
+ public Inventory getInventory() {
+ return inventory;
+ }
+
+ public boolean isOwner(Player player) {
+ return player != null && player.getUniqueId().equals(ownerId);
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/ArenaEditGui.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/ArenaEditGui.java
new file mode 100644
index 0000000..9e128cc
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/ArenaEditGui.java
@@ -0,0 +1,329 @@
+package com.starpractice.gui;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.Arena;
+import com.starpractice.util.ConfigUtil;
+import com.starpractice.util.GuiUtil;
+import com.starpractice.util.ItemBuilder;
+import com.starpractice.util.SoundUtil;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.bukkit.Material;
+import org.bukkit.Location;
+import org.bukkit.World;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+
+public class ArenaEditGui extends AbstractGui {
+ private final StarPracticePlugin plugin;
+ private final Arena arena;
+
+ public ArenaEditGui(StarPracticePlugin plugin, Player player, Arena arena) {
+ super(player, 54, plugin.getConfig().getString("ui.titles.arena_edit"));
+ this.plugin = plugin;
+ this.arena = arena;
+ }
+
+ @Override
+ protected void draw(Inventory inventory) {
+ fillBackground(GuiUtil.backgroundItem(plugin));
+ ItemStack name = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.edit_name", Material.NAME_TAG))
+ .name("&aEdit Name")
+ .lore(statusLore(Arrays.asList("&7Current: &f" + arena.getDisplayName(), "&eClick to edit"), true, null))
+ .build();
+ ItemStack icon = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.set_icon", Material.ITEM_FRAME))
+ .name("&aSet Icon From Hand")
+ .lore(Arrays.asList("&7Hold item in hand"))
+ .build();
+ ItemStack toggle = new ItemBuilder(arena.isEnabled()
+ ? ConfigUtil.material(plugin, "ui.icons.toggle_enabled", Material.LIME_DYE)
+ : ConfigUtil.material(plugin, "ui.icons.toggle_disabled", Material.GRAY_DYE))
+ .name(arena.isEnabled() ? "&aEnabled" : "&cDisabled")
+ .lore(statusLore(Arrays.asList("&eClick to toggle"), arena.isEnabled(), null))
+ .build();
+ ItemStack corner1 = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.set_corner1", Material.GOLD_BLOCK))
+ .name("&aSet Corner 1")
+ .lore(statusLore(Arrays.asList("&7Use your current location"), arena.getCorner1() != null, arena.getCorner1()))
+ .build();
+ ItemStack corner2 = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.set_corner2", Material.GOLD_BLOCK))
+ .name("&aSet Corner 2")
+ .lore(statusLore(Arrays.asList("&7Use your current location"), arena.getCorner2() != null, arena.getCorner2()))
+ .build();
+ ItemStack spawn1 = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.set_spawn1", Material.RED_BED))
+ .name("&aSet Spawn 1")
+ .lore(statusLore(Arrays.asList("&7Use your current location"), arena.getSpawn1() != null, arena.getSpawn1()))
+ .build();
+ ItemStack spawn2 = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.set_spawn2", Material.BLUE_BED))
+ .name("&aSet Spawn 2")
+ .lore(statusLore(Arrays.asList("&7Use your current location"), arena.getSpawn2() != null, arena.getSpawn2()))
+ .build();
+ ItemStack spec = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.set_spec_spawn", Material.ENDER_EYE))
+ .name("&aSet Spectator Spawn")
+ .lore(statusLore(Arrays.asList("&7Use your current location"), arena.getSpectatorSpawn() != null, arena.getSpectatorSpawn()))
+ .build();
+ ItemStack center = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.set_center", Material.BEACON))
+ .name("&aSet Center Spawn")
+ .lore(statusLore(Arrays.asList("&7Used for party FFA", "&eLeft click: set here", "&eRight click: teleport"), arena.getCenterSpawn() != null, arena.getCenterSpawn()))
+ .build();
+ ItemStack copy = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.copy_arena", Material.PAPER))
+ .name("&aCopy Arena")
+ .lore(Arrays.asList("&7Clone this arena at your location"))
+ .build();
+ boolean snapshotReady = plugin.getWorldEditAdapter().isAvailable()
+ && plugin.getWorldEditAdapter().getSnapshotFile(arena).exists();
+ ItemStack snapshot = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.save_snapshot", Material.STRUCTURE_BLOCK))
+ .name("&aResave Snapshot")
+ .lore(statusLore(Arrays.asList("&7Uses Corner 1 and Corner 2"), snapshotReady, null, snapshotReady ? "&7&o" + plugin.getWorldEditAdapter().getSnapshotFile(arena).getName() : null))
+ .build();
+ ItemStack back = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.back", Material.BARRIER)).name("&cBack").build();
+
+ setItem(10, name, e -> {
+ SoundUtil.play(player, plugin, "click");
+ plugin.sendMessage(player, "&eType a new display name in chat.");
+ plugin.getChatInputManager().prompt(player, input -> {
+ arena.setDisplayName(input);
+ plugin.getStorageManager().saveArenas();
+ new ArenaEditGui(plugin, player, arena).open();
+ });
+ });
+ setItem(11, icon, e -> {
+ ItemStack hand = player.getInventory().getItemInMainHand();
+ if (hand == null || hand.getType() == Material.AIR) {
+ SoundUtil.play(player, plugin, "error");
+ plugin.sendMessage(player, "&cHold a valid item in your main hand.");
+ return;
+ }
+ arena.setIconItem(hand);
+ plugin.getStorageManager().saveArenas();
+ SoundUtil.play(player, plugin, "success");
+ new ArenaEditGui(plugin, player, arena).open();
+ });
+ setItem(28, toggle, e -> {
+ if (!arena.isEnabled()) {
+ if (!plugin.getArenaManager().isFullyConfigured(arena)) {
+ SoundUtil.play(player, plugin, "error");
+ plugin.sendMessage(player, "&cArena must be fully configured before enabling.");
+ return;
+ }
+ arena.setEnabled(true);
+ } else {
+ arena.setEnabled(false);
+ }
+ plugin.getStorageManager().saveArenas();
+ SoundUtil.play(player, plugin, "success");
+ new ArenaEditGui(plugin, player, arena).open();
+ });
+ setItem(12, corner1, e -> {
+ arena.setCorner1(player.getLocation());
+ plugin.getStorageManager().saveArenas();
+ SoundUtil.play(player, plugin, "success");
+ attemptAutoSnapshot(player);
+ new ArenaEditGui(plugin, player, arena).open();
+ });
+ setItem(14, corner2, e -> {
+ arena.setCorner2(player.getLocation());
+ plugin.getStorageManager().saveArenas();
+ SoundUtil.play(player, plugin, "success");
+ attemptAutoSnapshot(player);
+ new ArenaEditGui(plugin, player, arena).open();
+ });
+ setItem(21, spawn1, e -> {
+ arena.setSpawn1(player.getLocation());
+ plugin.getStorageManager().saveArenas();
+ SoundUtil.play(player, plugin, "success");
+ new ArenaEditGui(plugin, player, arena).open();
+ });
+ setItem(23, spawn2, e -> {
+ arena.setSpawn2(player.getLocation());
+ plugin.getStorageManager().saveArenas();
+ SoundUtil.play(player, plugin, "success");
+ new ArenaEditGui(plugin, player, arena).open();
+ });
+ setItem(30, spec, e -> {
+ arena.setSpectatorSpawn(player.getLocation());
+ plugin.getStorageManager().saveArenas();
+ SoundUtil.play(player, plugin, "success");
+ new ArenaEditGui(plugin, player, arena).open();
+ });
+ setItem(32, center, e -> {
+ if (e.isRightClick()) {
+ if (arena.getCenterSpawn() == null) {
+ SoundUtil.play(player, plugin, "error");
+ plugin.sendMessage(player, "&cCenter spawn not set.");
+ return;
+ }
+ SoundUtil.play(player, plugin, "click");
+ player.teleport(arena.getCenterSpawn());
+ return;
+ }
+ arena.setCenterSpawn(player.getLocation());
+ plugin.getStorageManager().saveArenas();
+ SoundUtil.play(player, plugin, "success");
+ new ArenaEditGui(plugin, player, arena).open();
+ });
+ setItem(16, copy, e -> {
+ player.closeInventory();
+ plugin.sendMessage(player, "&eType the new arena name in chat.");
+ plugin.getChatInputManager().prompt(player, input -> copyArena(player, input));
+ });
+ setItem(34, snapshot, e -> {
+ if (!plugin.getWorldEditAdapter().isAvailable()) {
+ SoundUtil.play(player, plugin, "error");
+ plugin.sendMessage(player, "&cWorldEdit/FAWE not available.");
+ return;
+ }
+ if (arena.getCorner1() == null || arena.getCorner2() == null) {
+ SoundUtil.play(player, plugin, "error");
+ plugin.sendMessage(player, "&cSet both corners first.");
+ return;
+ }
+ plugin.getScheduler().runAtLocation(player.getLocation(), () -> {
+ boolean success = plugin.getWorldEditAdapter().saveSnapshot(arena);
+ if (success) {
+ SoundUtil.play(player, plugin, "success");
+ plugin.sendMessage(player, "&aSnapshot saved.");
+ } else {
+ SoundUtil.play(player, plugin, "error");
+ plugin.sendMessage(player, "&cFailed to save snapshot.");
+ }
+ });
+ });
+ setItem(49, back, e -> new ArenaListGui(plugin, player, ArenaListGui.Mode.EDIT).open());
+ }
+
+ private void copyArena(Player player, String input) {
+ String name = input.trim();
+ if (name.isEmpty()) {
+ name = "arena";
+ }
+ if (isDuplicateArenaName(name)) {
+ plugin.sendMessage(player, "&cFailed to copy arena: duplicate name.");
+ return;
+ }
+ String id = plugin.getArenaManager().generateId(name);
+ Arena copy = new Arena(id);
+ copy.setDisplayName(name);
+ copy.setEnabled(arena.isEnabled());
+
+ Location oldCenter = resolveArenaCenter(arena);
+ Location newCenter = player.getLocation();
+ double dx = 0;
+ double dy = 0;
+ double dz = 0;
+ World targetWorld = newCenter.getWorld();
+ if (oldCenter != null && targetWorld != null) {
+ dx = newCenter.getX() - oldCenter.getX();
+ dy = newCenter.getY() - oldCenter.getY();
+ dz = newCenter.getZ() - oldCenter.getZ();
+ }
+
+ copy.setCorner1(shift(arena.getCorner1(), dx, dy, dz, targetWorld));
+ copy.setCorner2(shift(arena.getCorner2(), dx, dy, dz, targetWorld));
+ copy.setSpawn1(shift(arena.getSpawn1(), dx, dy, dz, targetWorld));
+ copy.setSpawn2(shift(arena.getSpawn2(), dx, dy, dz, targetWorld));
+ copy.setSpectatorSpawn(shift(arena.getSpectatorSpawn(), dx, dy, dz, targetWorld));
+ copy.setCenterSpawn(shift(arena.getCenterSpawn(), dx, dy, dz, targetWorld));
+ if (targetWorld != null) {
+ copy.setWorldName(targetWorld.getName());
+ }
+
+ if (plugin.getWorldEditAdapter().isAvailable()) {
+ java.io.File src = plugin.getWorldEditAdapter().getSnapshotFile(arena);
+ java.io.File dst = plugin.getWorldEditAdapter().getSnapshotFile(copy);
+ if (src.exists()) {
+ try {
+ Files.copy(src.toPath(), dst.toPath(), StandardCopyOption.REPLACE_EXISTING);
+ copy.setSnapshotPath(dst.getName());
+ if (copy.getCorner1() != null) {
+ plugin.getScheduler().runAtLocation(copy.getCorner1(), () -> {
+ boolean restored = plugin.getWorldEditAdapter().restoreSnapshot(copy);
+ if (!restored) {
+ plugin.getLogger().warning("Failed to paste copied arena " + copy.getId());
+ }
+ });
+ }
+ } catch (Exception e) {
+ plugin.getLogger().warning("Failed to copy snapshot for arena " + arena.getId() + ": " + e.getMessage());
+ }
+ }
+ }
+
+ plugin.getArenaManager().add(copy);
+ plugin.getStorageManager().saveArenas();
+ new ArenaEditGui(plugin, player, copy).open();
+ }
+
+ private boolean isDuplicateArenaName(String name) {
+ for (Arena existing : plugin.getArenaManager().getAll()) {
+ if (existing.getId().equalsIgnoreCase(name) || existing.getDisplayName().equalsIgnoreCase(name)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private Location resolveArenaCenter(Arena arena) {
+ if (arena.getCenterSpawn() != null) {
+ return arena.getCenterSpawn();
+ }
+ Location c1 = arena.getCorner1();
+ Location c2 = arena.getCorner2();
+ if (c1 != null && c2 != null && c1.getWorld() != null) {
+ double x = (c1.getX() + c2.getX()) / 2.0;
+ double y = (c1.getY() + c2.getY()) / 2.0;
+ double z = (c1.getZ() + c2.getZ()) / 2.0;
+ return new Location(c1.getWorld(), x, y, z, c1.getYaw(), c1.getPitch());
+ }
+ if (arena.getSpawn1() != null) {
+ return arena.getSpawn1();
+ }
+ if (arena.getSpectatorSpawn() != null) {
+ return arena.getSpectatorSpawn();
+ }
+ return null;
+ }
+
+ private Location shift(Location original, double dx, double dy, double dz, World world) {
+ if (original == null || world == null) {
+ return null;
+ }
+ return new Location(world, original.getX() + dx, original.getY() + dy, original.getZ() + dz, original.getYaw(), original.getPitch());
+ }
+
+ private void attemptAutoSnapshot(Player player) {
+ if (!plugin.getWorldEditAdapter().isAvailable()) {
+ return;
+ }
+ if (arena.getCorner1() == null || arena.getCorner2() == null) {
+ return;
+ }
+ plugin.getScheduler().runAtLocation(player.getLocation(), () -> {
+ boolean success = plugin.getWorldEditAdapter().saveSnapshot(arena);
+ if (success) {
+ plugin.sendMessage(player, "&aSnapshot saved.");
+ } else {
+ plugin.sendMessage(player, "&cFailed to save snapshot.");
+ }
+ });
+ }
+
+ private List statusLore(List base, boolean enabled, org.bukkit.Location loc) {
+ return statusLore(base, enabled, loc, null);
+ }
+
+ private List statusLore(List base, boolean enabled, org.bukkit.Location loc, String extraLine) {
+ List lore = new ArrayList<>(base);
+ lore.add(enabled ? "&aStatus: ENABLED" : "&cStatus: DISABLED");
+ if (enabled && loc != null && loc.getWorld() != null) {
+ lore.add("&7&o" + loc.getWorld().getName() + " " + loc.getBlockX() + " " + loc.getBlockY() + " " + loc.getBlockZ());
+ }
+ if (extraLine != null) {
+ lore.add(extraLine);
+ }
+ return lore;
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/ArenaListGui.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/ArenaListGui.java
new file mode 100644
index 0000000..999c8f9
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/ArenaListGui.java
@@ -0,0 +1,149 @@
+package com.starpractice.gui;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.Arena;
+import com.starpractice.util.ConfigUtil;
+import com.starpractice.util.GuiUtil;
+import com.starpractice.util.IconUtil;
+import com.starpractice.util.ItemBuilder;
+import com.starpractice.util.SoundUtil;
+import java.util.Arrays;
+import java.util.List;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+
+public class ArenaListGui extends AbstractGui {
+ public enum Mode { EDIT, REMOVE }
+
+ private final StarPracticePlugin plugin;
+ private final Mode mode;
+ private final int page;
+
+ public ArenaListGui(StarPracticePlugin plugin, Player player, Mode mode) {
+ this(plugin, player, mode, 0);
+ }
+
+ public ArenaListGui(StarPracticePlugin plugin, Player player, Mode mode, int page) {
+ super(player, 54, plugin.getConfig().getString("ui.titles.arenas"));
+ this.plugin = plugin;
+ this.mode = mode;
+ this.page = page;
+ }
+
+ @Override
+ protected void draw(Inventory inventory) {
+ fillBackground(GuiUtil.backgroundItem(plugin));
+ List arenas = plugin.getArenaManager().getAll();
+ int totalPages = (int) Math.ceil(arenas.size() / 45.0);
+ int start = page * 45;
+ for (int i = 0; i < 45; i++) {
+ int index = start + i;
+ if (index >= arenas.size()) {
+ break;
+ }
+ Arena arena = arenas.get(index);
+ ItemStack item = IconUtil.arenaIcon(arena,
+ Arrays.asList("&7ID: &f" + arena.getId(), "&7Enabled: &f" + arena.isEnabled(), actionLabel()));
+ int slot = i;
+ setItem(slot, item, e -> handleClick(arena));
+ }
+
+ ItemStack add = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.add", Material.LIME_WOOL)).name("&aAdd Arena").build();
+ ItemStack edit = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.edit", Material.ANVIL))
+ .name("&eEdit Mode")
+ .lore(Arrays.asList(mode == Mode.EDIT ? "&aSelected" : "&7Click to select"))
+ .build();
+ ItemStack remove = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.remove", Material.RED_WOOL))
+ .name("&cRemove Mode")
+ .lore(Arrays.asList(mode == Mode.REMOVE ? "&aSelected" : "&7Click to select"))
+ .build();
+ if (mode == Mode.EDIT) {
+ org.bukkit.inventory.meta.ItemMeta meta = edit.getItemMeta();
+ if (meta != null) {
+ meta.addEnchant(org.bukkit.enchantments.Enchantment.UNBREAKING, 1, true);
+ meta.addItemFlags(org.bukkit.inventory.ItemFlag.HIDE_ENCHANTS);
+ edit.setItemMeta(meta);
+ }
+ } else {
+ org.bukkit.inventory.meta.ItemMeta meta = remove.getItemMeta();
+ if (meta != null) {
+ meta.addEnchant(org.bukkit.enchantments.Enchantment.UNBREAKING, 1, true);
+ meta.addItemFlags(org.bukkit.inventory.ItemFlag.HIDE_ENCHANTS);
+ remove.setItemMeta(meta);
+ }
+ }
+ setItem(45, edit, e -> {
+ SoundUtil.play(player, plugin, "click");
+ new ArenaListGui(plugin, player, Mode.EDIT, page).open();
+ });
+ setItem(46, remove, e -> {
+ SoundUtil.play(player, plugin, "click");
+ new ArenaListGui(plugin, player, Mode.REMOVE, page).open();
+ });
+ setItem(47, add, e -> {
+ SoundUtil.play(player, plugin, "click");
+ player.closeInventory();
+ plugin.sendMessage(player, "&eType the arena name in chat.");
+ plugin.getChatInputManager().prompt(player, input -> {
+ String name = input.trim();
+ if (name.isEmpty()) {
+ name = "arena";
+ }
+ String id = plugin.getArenaManager().generateId(name);
+ Arena newArena = new Arena(id);
+ newArena.setDisplayName(name);
+ plugin.getArenaManager().add(newArena);
+ plugin.getStorageManager().saveArenas();
+ new ArenaListGui(plugin, player, Mode.EDIT).open();
+ });
+ });
+
+ if (page > 0) {
+ ItemStack prev = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.prev_page", Material.ARROW)).name("&ePrevious Page").build();
+ setItem(51, prev, e -> new ArenaListGui(plugin, player, mode, page - 1).open());
+ }
+ if (page + 1 < totalPages) {
+ ItemStack next = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.next_page", Material.ARROW)).name("&eNext Page").build();
+ setItem(52, next, e -> new ArenaListGui(plugin, player, mode, page + 1).open());
+ }
+ ItemStack back = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.back", Material.BARRIER)).name("&cBack").build();
+ setItem(53, back, e -> new MainAdminGui(plugin, player).open());
+ }
+
+ private String actionLabel() {
+ return switch (mode) {
+ case EDIT -> "&eClick to edit";
+ case REMOVE -> "&cClick to delete";
+ default -> "&7";
+ };
+ }
+
+ private void handleClick(Arena arena) {
+ if (mode == Mode.EDIT) {
+ SoundUtil.play(player, plugin, "click");
+ new ArenaEditGui(plugin, player, arena).open();
+ return;
+ }
+ if (mode == Mode.REMOVE) {
+ SoundUtil.play(player, plugin, "click");
+ new ConfirmDeleteGui(plugin, player, () -> {
+ Arena target = arena;
+ if (plugin.getWorldEditAdapter().isAvailable()
+ && target.getCorner1() != null
+ && target.getCorner2() != null
+ && target.getCorner1().getWorld() != null) {
+ plugin.getScheduler().runAtLocation(target.getCorner1(), () -> {
+ plugin.getWorldEditAdapter().clearArena(target);
+ });
+ }
+ plugin.getArenaManager().remove(arena.getId());
+ plugin.getStorageManager().saveArenas();
+ plugin.sendMessage(player, "&cArena removed.");
+ new ArenaListGui(plugin, player, Mode.REMOVE, page).open();
+ }, () -> new ArenaListGui(plugin, player, Mode.REMOVE, page).open()).open();
+ return;
+ }
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/ArenaSelectGui.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/ArenaSelectGui.java
new file mode 100644
index 0000000..24add87
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/ArenaSelectGui.java
@@ -0,0 +1,70 @@
+package com.starpractice.gui;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.Arena;
+import com.starpractice.model.Gamemode;
+import com.starpractice.util.ConfigUtil;
+import com.starpractice.util.GuiUtil;
+import com.starpractice.util.ItemBuilder;
+import java.util.Arrays;
+import java.util.List;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+
+public class ArenaSelectGui extends AbstractGui {
+ private final StarPracticePlugin plugin;
+ private final Gamemode gamemode;
+ private final int page;
+
+ public ArenaSelectGui(StarPracticePlugin plugin, Player player, Gamemode gamemode) {
+ this(plugin, player, gamemode, 0);
+ }
+
+ public ArenaSelectGui(StarPracticePlugin plugin, Player player, Gamemode gamemode, int page) {
+ super(player, 54, plugin.getConfig().getString("ui.titles.arena_select"));
+ this.plugin = plugin;
+ this.gamemode = gamemode;
+ this.page = page;
+ }
+
+ @Override
+ protected void draw(Inventory inventory) {
+ fillBackground(GuiUtil.backgroundItem(plugin));
+ List arenas = plugin.getArenaManager().getAll();
+ int totalPages = (int) Math.ceil(arenas.size() / 45.0);
+ int start = page * 45;
+ for (int i = 0; i < 45; i++) {
+ int index = start + i;
+ if (index >= arenas.size()) {
+ break;
+ }
+ Arena arena = arenas.get(index);
+ boolean allowed = gamemode.getAllowedArenas().contains(arena.getId());
+ Material mat = allowed ? Material.LIME_WOOL : Material.GRAY_WOOL;
+ ItemStack item = new ItemBuilder(mat)
+ .name("&a" + arena.getDisplayName())
+ .lore(Arrays.asList("&7ID: &f" + arena.getId(), allowed ? "&aAllowed" : "&cNot Allowed", "&eClick to toggle"))
+ .build();
+ setItem(i, item, e -> {
+ if (allowed) {
+ gamemode.getAllowedArenas().remove(arena.getId());
+ } else {
+ gamemode.getAllowedArenas().add(arena.getId());
+ }
+ new ArenaSelectGui(plugin, player, gamemode, page).open();
+ });
+ }
+ if (page > 0) {
+ ItemStack prev = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.prev_page", Material.ARROW)).name("&ePrevious Page").build();
+ setItem(51, prev, e -> new ArenaSelectGui(plugin, player, gamemode, page - 1).open());
+ }
+ if (page + 1 < totalPages) {
+ ItemStack next = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.next_page", Material.ARROW)).name("&eNext Page").build();
+ setItem(52, next, e -> new ArenaSelectGui(plugin, player, gamemode, page + 1).open());
+ }
+ ItemStack back = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.back", Material.BARRIER)).name("&cBack").build();
+ setItem(53, back, e -> new GamemodeEditGui(plugin, player, gamemode).open());
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/ConfirmDeleteGui.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/ConfirmDeleteGui.java
new file mode 100644
index 0000000..b475b91
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/ConfirmDeleteGui.java
@@ -0,0 +1,46 @@
+package com.starpractice.gui;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.util.GuiUtil;
+import com.starpractice.util.ItemBuilder;
+import com.starpractice.util.SoundUtil;
+import java.util.Arrays;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+
+public class ConfirmDeleteGui extends AbstractGui {
+ private final StarPracticePlugin plugin;
+ private final Runnable confirm;
+ private final Runnable cancel;
+
+ public ConfirmDeleteGui(StarPracticePlugin plugin, Player player, Runnable confirm, Runnable cancel) {
+ super(player, 27, "&cAre you sure you want to delete?");
+ this.plugin = plugin;
+ this.confirm = confirm;
+ this.cancel = cancel;
+ }
+
+ @Override
+ protected void draw(Inventory inventory) {
+ fillBackground(GuiUtil.backgroundItem(plugin));
+ ItemStack confirmItem = new ItemBuilder(Material.GREEN_WOOL)
+ .name("&aConfirm")
+ .lore(Arrays.asList("&7This action cannot be undone"))
+ .build();
+ ItemStack cancelItem = new ItemBuilder(Material.RED_WOOL)
+ .name("&cCancel")
+ .lore(Arrays.asList("&7Return to the list"))
+ .build();
+
+ setItem(11, confirmItem, e -> {
+ SoundUtil.play(player, plugin, "success");
+ confirm.run();
+ });
+ setItem(15, cancelItem, e -> {
+ SoundUtil.play(player, plugin, "error");
+ cancel.run();
+ });
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/DuelGamemodeGui.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/DuelGamemodeGui.java
new file mode 100644
index 0000000..b281e1d
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/DuelGamemodeGui.java
@@ -0,0 +1,53 @@
+package com.starpractice.gui;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.Gamemode;
+import com.starpractice.util.GuiUtil;
+import com.starpractice.util.IconUtil;
+import com.starpractice.util.SoundUtil;
+import java.util.Arrays;
+import java.util.List;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+
+public class DuelGamemodeGui extends AbstractGui {
+ private final StarPracticePlugin plugin;
+ private final Player target;
+ private Gamemode selected;
+
+ public DuelGamemodeGui(StarPracticePlugin plugin, Player player, Player target) {
+ super(player, 27, plugin.getConfig().getString("ui.titles.duel_gamemode"));
+ this.plugin = plugin;
+ this.target = target;
+ }
+
+ @Override
+ protected void draw(Inventory inventory) {
+ fillBackground(GuiUtil.backgroundItem(plugin));
+ List modes = plugin.getGamemodeManager().getEnabled();
+ for (int i = 0; i < Math.min(27, modes.size()); i++) {
+ Gamemode mode = modes.get(i);
+ ItemStack item = IconUtil.gamemodeIcon(mode, Arrays.asList("&7Click to select"));
+ int slot = i;
+ setItem(slot, item, e -> {
+ SoundUtil.play(player, plugin, "click");
+ selected = mode;
+ plugin.getScheduler().runLaterAtEntity(player, 1L, () -> {
+ if (!player.isOnline()) {
+ return;
+ }
+ new DuelRoundsGui(plugin, player, target, mode).open();
+ });
+ });
+ }
+ }
+
+ public Gamemode getSelected() {
+ return selected;
+ }
+
+ public Player getTarget() {
+ return target;
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/DuelRoundsGui.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/DuelRoundsGui.java
new file mode 100644
index 0000000..04cd061
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/DuelRoundsGui.java
@@ -0,0 +1,81 @@
+package com.starpractice.gui;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.Arena;
+import com.starpractice.model.Gamemode;
+import com.starpractice.util.GuiUtil;
+import com.starpractice.util.ItemBuilder;
+import com.starpractice.util.SoundUtil;
+import java.util.Arrays;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.SkullMeta;
+
+public class DuelRoundsGui extends AbstractGui {
+ private final StarPracticePlugin plugin;
+ private final Player target;
+ private final Gamemode gamemode;
+
+ public DuelRoundsGui(StarPracticePlugin plugin, Player player, Player target, Gamemode gamemode) {
+ super(player, 27, plugin.getConfig().getString("ui.titles.duel_rounds"));
+ this.plugin = plugin;
+ this.target = target;
+ this.gamemode = gamemode;
+ }
+
+ @Override
+ protected void draw(Inventory inventory) {
+ fillBackground(GuiUtil.backgroundItem(plugin));
+
+ ItemStack head = new ItemStack(Material.PLAYER_HEAD);
+ SkullMeta meta = (SkullMeta) head.getItemMeta();
+ if (meta != null) {
+ meta.setOwningPlayer(target);
+ meta.setDisplayName(com.starpractice.util.Text.color("&a" + target.getName()));
+ head.setItemMeta(meta);
+ }
+ setItem(4, head, null);
+
+ setRoundItem(18, Material.GREEN_WOOL, 1);
+ setRoundItem(19, Material.LIME_WOOL, 2);
+ setRoundItem(20, Material.YELLOW_WOOL, 3);
+ setRoundItem(21, Material.ORANGE_WOOL, 4);
+ setRoundItem(22, Material.RED_WOOL, 5);
+ setRoundItem(23, Material.PINK_WOOL, 10);
+ setRoundItem(24, Material.MAGENTA_WOOL, 15);
+ setRoundItem(25, Material.PURPLE_WOOL, 20);
+ setRoundItem(26, Material.BLACK_WOOL, 25);
+ }
+
+ private void setRoundItem(int slot, Material material, int rounds) {
+ int requiredWins = rounds / 2 + 1;
+ ItemStack item = new ItemBuilder(material)
+ .name("&aRounds: " + rounds)
+ .lore(Arrays.asList("&7First to " + requiredWins + " wins", "&7Click to start duel"))
+ .build();
+ setItem(slot, item, e -> {
+ if (!target.isOnline()) {
+ plugin.sendMessage(player, "&cPlayer not found.");
+ return;
+ }
+ if (plugin.getMatchManager().isInMatch(player) || plugin.getSpectateManager().isSpectating(player)) {
+ plugin.sendMessage(player, "&cYou cannot duel right now.");
+ return;
+ }
+ if (plugin.getMatchManager().isInMatch(target) || plugin.getSpectateManager().isSpectating(target)) {
+ plugin.sendMessage(player, "&cThat player is busy.");
+ return;
+ }
+ Arena arena = plugin.getArenaManager().findAvailableArena(gamemode);
+ if (arena == null) {
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.no-arenas"));
+ return;
+ }
+ SoundUtil.play(player, plugin, "success");
+ player.closeInventory();
+ plugin.getDuelRequestManager().sendRequest(player, target, gamemode, rounds);
+ });
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/GamemodeEditGui.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/GamemodeEditGui.java
new file mode 100644
index 0000000..82da400
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/GamemodeEditGui.java
@@ -0,0 +1,96 @@
+package com.starpractice.gui;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.Gamemode;
+import com.starpractice.model.Kit;
+import com.starpractice.util.ConfigUtil;
+import com.starpractice.util.GuiUtil;
+import com.starpractice.util.ItemBuilder;
+import com.starpractice.util.SoundUtil;
+import java.util.Arrays;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+
+public class GamemodeEditGui extends AbstractGui {
+ private final StarPracticePlugin plugin;
+ private final Gamemode gamemode;
+
+ public GamemodeEditGui(StarPracticePlugin plugin, Player player, Gamemode gamemode) {
+ super(player, 54, plugin.getConfig().getString("ui.titles.gamemode_edit"));
+ this.plugin = plugin;
+ this.gamemode = gamemode;
+ }
+
+ @Override
+ protected void draw(Inventory inventory) {
+ fillBackground(GuiUtil.backgroundItem(plugin));
+ ItemStack name = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.edit_name", Material.NAME_TAG))
+ .name("&aEdit Name")
+ .lore(Arrays.asList("&7Current: &f" + gamemode.getDisplayName(), "&eClick to edit"))
+ .build();
+ ItemStack toggle = new ItemBuilder(gamemode.isEnabled()
+ ? ConfigUtil.material(plugin, "ui.icons.toggle_enabled", Material.LIME_DYE)
+ : ConfigUtil.material(plugin, "ui.icons.toggle_disabled", Material.GRAY_DYE))
+ .name(gamemode.isEnabled() ? "&aEnabled" : "&cDisabled")
+ .lore(Arrays.asList("&eClick to toggle"))
+ .build();
+ ItemStack icon = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.set_icon", Material.ITEM_FRAME))
+ .name("&aSet Icon From Hand")
+ .lore(Arrays.asList("&7Hold item in hand"))
+ .build();
+ ItemStack kit = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.copy_kit", Material.CHEST))
+ .name("&aCopy My Inventory as Kit")
+ .lore(Arrays.asList("&7Includes armor and effects"))
+ .build();
+ ItemStack arenas = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.edit_arenas", Material.OAK_SIGN))
+ .name("&aEdit Allowed Arenas")
+ .lore(Arrays.asList("&7Toggle arenas"))
+ .build();
+ ItemStack settings = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.settings", Material.CLOCK))
+ .name("&aSettings")
+ .lore(Arrays.asList("&7Edit duel rules for this mode"))
+ .build();
+ ItemStack back = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.back", Material.BARRIER)).name("&cBack").build();
+
+ setItem(11, name, e -> {
+ SoundUtil.play(player, plugin, "click");
+ plugin.sendMessage(player, "&eType a new display name in chat.");
+ plugin.getChatInputManager().prompt(player, input -> {
+ gamemode.setDisplayName(input);
+ new GamemodeEditGui(plugin, player, gamemode).open();
+ });
+ });
+ setItem(13, toggle, e -> {
+ gamemode.setEnabled(!gamemode.isEnabled());
+ SoundUtil.play(player, plugin, "success");
+ new GamemodeEditGui(plugin, player, gamemode).open();
+ });
+ setItem(15, icon, e -> {
+ ItemStack hand = player.getInventory().getItemInMainHand();
+ if (hand == null || hand.getType() == Material.AIR) {
+ SoundUtil.play(player, plugin, "error");
+ plugin.sendMessage(player, "&cHold a valid item in your main hand.");
+ return;
+ }
+ gamemode.setIconItem(hand);
+ SoundUtil.play(player, plugin, "success");
+ new GamemodeEditGui(plugin, player, gamemode).open();
+ });
+ setItem(29, kit, e -> {
+ gamemode.setKit(Kit.fromPlayer(player));
+ SoundUtil.play(player, plugin, "success");
+ new GamemodeEditGui(plugin, player, gamemode).open();
+ });
+ setItem(31, arenas, e -> {
+ SoundUtil.play(player, plugin, "click");
+ new ArenaSelectGui(plugin, player, gamemode).open();
+ });
+ setItem(33, settings, e -> {
+ SoundUtil.play(player, plugin, "click");
+ new GamemodeSettingsGui(plugin, player, gamemode).open();
+ });
+ setItem(49, back, e -> new GamemodeListGui(plugin, player, GamemodeListGui.Mode.EDIT).open());
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/GamemodeListGui.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/GamemodeListGui.java
new file mode 100644
index 0000000..213709e
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/GamemodeListGui.java
@@ -0,0 +1,138 @@
+package com.starpractice.gui;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.Gamemode;
+import com.starpractice.util.ConfigUtil;
+import com.starpractice.util.GuiUtil;
+import com.starpractice.util.ItemBuilder;
+import com.starpractice.util.SoundUtil;
+import com.starpractice.util.IconUtil;
+import java.util.Arrays;
+import java.util.List;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+
+public class GamemodeListGui extends AbstractGui {
+ public enum Mode { EDIT, REMOVE }
+
+ private final StarPracticePlugin plugin;
+ private final Mode mode;
+ private final int page;
+
+ public GamemodeListGui(StarPracticePlugin plugin, Player player, Mode mode) {
+ this(plugin, player, mode, 0);
+ }
+
+ public GamemodeListGui(StarPracticePlugin plugin, Player player, Mode mode, int page) {
+ super(player, 54, plugin.getConfig().getString("ui.titles.gamemodes"));
+ this.plugin = plugin;
+ this.mode = mode;
+ this.page = page;
+ }
+
+ @Override
+ protected void draw(Inventory inventory) {
+ fillBackground(GuiUtil.backgroundItem(plugin));
+ List modes = plugin.getGamemodeManager().getAll();
+ int totalPages = (int) Math.ceil(modes.size() / 45.0);
+ int start = page * 45;
+ for (int i = 0; i < 45; i++) {
+ int index = start + i;
+ if (index >= modes.size()) {
+ break;
+ }
+ Gamemode mode = modes.get(index);
+ ItemStack item = IconUtil.gamemodeIcon(mode,
+ Arrays.asList("&7ID: &f" + mode.getId(), "&7Enabled: &f" + mode.isEnabled(), actionLabel()));
+ int slot = i;
+ setItem(slot, item, e -> handleClick(mode));
+ }
+
+ ItemStack add = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.add", Material.LIME_WOOL)).name("&aAdd Gamemode").build();
+ ItemStack edit = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.edit", Material.ANVIL))
+ .name("&eEdit Mode")
+ .lore(Arrays.asList(mode == Mode.EDIT ? "&aSelected" : "&7Click to select"))
+ .build();
+ ItemStack remove = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.remove", Material.RED_WOOL))
+ .name("&cRemove Mode")
+ .lore(Arrays.asList(mode == Mode.REMOVE ? "&aSelected" : "&7Click to select"))
+ .build();
+ if (mode == Mode.EDIT) {
+ org.bukkit.inventory.meta.ItemMeta meta = edit.getItemMeta();
+ if (meta != null) {
+ meta.addEnchant(org.bukkit.enchantments.Enchantment.UNBREAKING, 1, true);
+ meta.addItemFlags(org.bukkit.inventory.ItemFlag.HIDE_ENCHANTS);
+ edit.setItemMeta(meta);
+ }
+ } else {
+ org.bukkit.inventory.meta.ItemMeta meta = remove.getItemMeta();
+ if (meta != null) {
+ meta.addEnchant(org.bukkit.enchantments.Enchantment.UNBREAKING, 1, true);
+ meta.addItemFlags(org.bukkit.inventory.ItemFlag.HIDE_ENCHANTS);
+ remove.setItemMeta(meta);
+ }
+ }
+ setItem(45, edit, e -> {
+ SoundUtil.play(player, plugin, "click");
+ new GamemodeListGui(plugin, player, Mode.EDIT, page).open();
+ });
+ setItem(46, remove, e -> {
+ SoundUtil.play(player, plugin, "click");
+ new GamemodeListGui(plugin, player, Mode.REMOVE, page).open();
+ });
+ setItem(47, add, e -> {
+ SoundUtil.play(player, plugin, "click");
+ player.closeInventory();
+ plugin.sendMessage(player, "&eType the gamemode name in chat.");
+ plugin.getChatInputManager().prompt(player, input -> {
+ String name = input.trim();
+ if (name.isEmpty()) {
+ name = "mode";
+ }
+ String id = plugin.getGamemodeManager().generateId(name);
+ Gamemode newMode = new Gamemode(id);
+ newMode.setDisplayName(name);
+ plugin.getGamemodeManager().add(newMode);
+ new GamemodeListGui(plugin, player, Mode.EDIT).open();
+ });
+ });
+
+ if (page > 0) {
+ ItemStack prev = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.prev_page", Material.ARROW)).name("&ePrevious Page").build();
+ setItem(51, prev, e -> new GamemodeListGui(plugin, player, mode, page - 1).open());
+ }
+ if (page + 1 < totalPages) {
+ ItemStack next = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.next_page", Material.ARROW)).name("&eNext Page").build();
+ setItem(52, next, e -> new GamemodeListGui(plugin, player, mode, page + 1).open());
+ }
+ ItemStack back = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.back", Material.BARRIER)).name("&cBack").build();
+ setItem(53, back, e -> new MainAdminGui(plugin, player).open());
+ }
+
+ private String actionLabel() {
+ return switch (mode) {
+ case EDIT -> "&eClick to edit";
+ case REMOVE -> "&cClick to delete";
+ default -> "&7";
+ };
+ }
+
+ private void handleClick(Gamemode gamemode) {
+ if (mode == Mode.EDIT) {
+ SoundUtil.play(player, plugin, "click");
+ new GamemodeEditGui(plugin, player, gamemode).open();
+ return;
+ }
+ if (mode == Mode.REMOVE) {
+ SoundUtil.play(player, plugin, "click");
+ new ConfirmDeleteGui(plugin, player, () -> {
+ plugin.getGamemodeManager().remove(gamemode.getId());
+ plugin.sendMessage(player, "&cGamemode removed.");
+ new GamemodeListGui(plugin, player, Mode.REMOVE, page).open();
+ }, () -> new GamemodeListGui(plugin, player, Mode.REMOVE, page).open()).open();
+ return;
+ }
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/GamemodeRulesGui.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/GamemodeRulesGui.java
new file mode 100644
index 0000000..8b337cf
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/GamemodeRulesGui.java
@@ -0,0 +1,81 @@
+package com.starpractice.gui;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.Gamemode;
+import com.starpractice.util.ConfigUtil;
+import com.starpractice.util.GuiUtil;
+import com.starpractice.util.ItemBuilder;
+import com.starpractice.util.SoundUtil;
+import java.util.Arrays;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+
+public class GamemodeRulesGui extends AbstractGui {
+ private final StarPracticePlugin plugin;
+ private final Gamemode gamemode;
+
+ public GamemodeRulesGui(StarPracticePlugin plugin, Player player, Gamemode gamemode) {
+ super(player, 27, plugin.getConfig().getString("ui.titles.gamemode_rules"));
+ this.plugin = plugin;
+ this.gamemode = gamemode;
+ }
+
+ @Override
+ protected void draw(Inventory inventory) {
+ fillBackground(GuiUtil.backgroundItem(plugin));
+ ItemStack blockBreak = new ItemBuilder(gamemode.isBlockBreak() ? Material.LIME_WOOL : Material.RED_WOOL)
+ .name("&aBlock Breaking")
+ .lore(Arrays.asList(gamemode.isBlockBreak() ? "&aEnabled" : "&cDisabled", "&eClick to toggle"))
+ .build();
+ ItemStack blockPlace = new ItemBuilder(gamemode.isBlockPlace() ? Material.LIME_WOOL : Material.RED_WOOL)
+ .name("&aBlock Placing")
+ .lore(Arrays.asList(gamemode.isBlockPlace() ? "&aEnabled" : "&cDisabled", "&eClick to toggle"))
+ .build();
+ ItemStack naturalRegen = new ItemBuilder(gamemode.isNaturalRegen() ? Material.LIME_WOOL : Material.RED_WOOL)
+ .name("&aNatural Regeneration")
+ .lore(Arrays.asList(gamemode.isNaturalRegen() ? "&aEnabled" : "&cDisabled", "&eClick to toggle"))
+ .build();
+ ItemStack onlyBreakPlaced = new ItemBuilder(gamemode.isOnlyBreakPlaced() ? Material.LIME_WOOL : Material.RED_WOOL)
+ .name("&aOnly Break Placed Blocks")
+ .lore(Arrays.asList(gamemode.isOnlyBreakPlaced() ? "&aEnabled" : "&cDisabled", "&eClick to toggle"))
+ .build();
+ ItemStack lootDrops = new ItemBuilder(gamemode.isLootDrops() ? Material.LIME_WOOL : Material.RED_WOOL)
+ .name("&aLoot Drops")
+ .lore(Arrays.asList(gamemode.isLootDrops() ? "&aEnabled" : "&cDisabled", "&eClick to toggle"))
+ .build();
+ ItemStack back = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.back", Material.BARRIER)).name("&cBack").build();
+
+ setItem(10, blockBreak, e -> {
+ boolean next = !gamemode.isBlockBreak();
+ gamemode.setBlockBreak(next);
+ if (next) {
+ gamemode.setOnlyBreakPlaced(false);
+ }
+ SoundUtil.play(player, plugin, "success");
+ new GamemodeRulesGui(plugin, player, gamemode).open();
+ });
+ setItem(12, blockPlace, e -> {
+ gamemode.setBlockPlace(!gamemode.isBlockPlace());
+ SoundUtil.play(player, plugin, "success");
+ new GamemodeRulesGui(plugin, player, gamemode).open();
+ });
+ setItem(14, naturalRegen, e -> {
+ gamemode.setNaturalRegen(!gamemode.isNaturalRegen());
+ SoundUtil.play(player, plugin, "success");
+ new GamemodeRulesGui(plugin, player, gamemode).open();
+ });
+ setItem(16, onlyBreakPlaced, e -> {
+ gamemode.setOnlyBreakPlaced(!gamemode.isOnlyBreakPlaced());
+ SoundUtil.play(player, plugin, "success");
+ new GamemodeRulesGui(plugin, player, gamemode).open();
+ });
+ setItem(22, lootDrops, e -> {
+ gamemode.setLootDrops(!gamemode.isLootDrops());
+ SoundUtil.play(player, plugin, "success");
+ new GamemodeRulesGui(plugin, player, gamemode).open();
+ });
+ setItem(26, back, e -> new GamemodeSettingsGui(plugin, player, gamemode).open());
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/GamemodeSettingsGui.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/GamemodeSettingsGui.java
new file mode 100644
index 0000000..6fc996b
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/GamemodeSettingsGui.java
@@ -0,0 +1,72 @@
+package com.starpractice.gui;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.Gamemode;
+import com.starpractice.util.ConfigUtil;
+import com.starpractice.util.GuiUtil;
+import com.starpractice.util.ItemBuilder;
+import com.starpractice.util.SoundUtil;
+import java.util.Arrays;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+
+public class GamemodeSettingsGui extends AbstractGui {
+ private final StarPracticePlugin plugin;
+ private final Gamemode gamemode;
+
+ public GamemodeSettingsGui(StarPracticePlugin plugin, Player player, Gamemode gamemode) {
+ super(player, 27, plugin.getConfig().getString("ui.titles.gamemode_settings"));
+ this.plugin = plugin;
+ this.gamemode = gamemode;
+ }
+
+ @Override
+ protected void draw(Inventory inventory) {
+ fillBackground(GuiUtil.backgroundItem(plugin));
+ ItemStack saturation = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.full_saturation", Material.GOLDEN_APPLE))
+ .name("&aFull Saturation")
+ .lore(Arrays.asList(gamemode.isFullSaturation() ? "&aEnabled" : "&cDisabled", "&eClick to toggle"))
+ .build();
+ ItemStack rules = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.rules", Material.BOOK))
+ .name("&aRules")
+ .lore(Arrays.asList("&7Edit rule toggles"))
+ .build();
+ ItemStack prepot = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.prepot", Material.SPLASH_POTION))
+ .name("&aPrepot")
+ .lore(Arrays.asList(gamemode.isPrepotEnabled() ? "&aEnabled" : "&cDisabled", "&eLeft click to toggle", "&eRight click to edit"))
+ .build();
+ ItemStack health = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.health_display", Material.REDSTONE))
+ .name("&aHealth Display")
+ .lore(Arrays.asList(gamemode.isHealthDisplay() ? "&aEnabled" : "&cDisabled", "&eClick to toggle"))
+ .build();
+ ItemStack back = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.back", Material.BARRIER)).name("&cBack").build();
+
+ setItem(10, saturation, e -> {
+ gamemode.setFullSaturation(!gamemode.isFullSaturation());
+ SoundUtil.play(player, plugin, "success");
+ new GamemodeSettingsGui(plugin, player, gamemode).open();
+ });
+ setItem(12, rules, e -> {
+ SoundUtil.play(player, plugin, "click");
+ new GamemodeRulesGui(plugin, player, gamemode).open();
+ });
+ setItem(14, prepot, e -> {
+ if (e.isRightClick()) {
+ SoundUtil.play(player, plugin, "click");
+ new PrepotEditGui(plugin, player, gamemode).open();
+ return;
+ }
+ gamemode.setPrepotEnabled(!gamemode.isPrepotEnabled());
+ SoundUtil.play(player, plugin, "success");
+ new GamemodeSettingsGui(plugin, player, gamemode).open();
+ });
+ setItem(16, health, e -> {
+ gamemode.setHealthDisplay(!gamemode.isHealthDisplay());
+ SoundUtil.play(player, plugin, "success");
+ new GamemodeSettingsGui(plugin, player, gamemode).open();
+ });
+ setItem(22, back, e -> new GamemodeEditGui(plugin, player, gamemode).open());
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/GuiManager.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/GuiManager.java
new file mode 100644
index 0000000..7835e41
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/GuiManager.java
@@ -0,0 +1,41 @@
+package com.starpractice.gui;
+
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.event.inventory.InventoryDragEvent;
+
+public class GuiManager implements Listener {
+ private final com.starpractice.StarPracticePlugin plugin;
+
+ public GuiManager(com.starpractice.StarPracticePlugin plugin) {
+ this.plugin = plugin;
+ }
+
+ @EventHandler
+ public void onClick(InventoryClickEvent event) {
+ if (event.getView().getTopInventory().getHolder() instanceof AbstractGui gui) {
+ if (!(event.getWhoClicked() instanceof org.bukkit.entity.Player player)
+ || !gui.isOwner(player)
+ || event.getView().getTopInventory() != gui.getInventory()) {
+ event.setCancelled(true);
+ return;
+ }
+ gui.onClick(event);
+ }
+ }
+
+ @EventHandler
+ public void onDrag(InventoryDragEvent event) {
+ if (event.getView().getTopInventory().getHolder() instanceof AbstractGui gui) {
+ if (!(event.getWhoClicked() instanceof org.bukkit.entity.Player player)
+ || !gui.isOwner(player)
+ || event.getView().getTopInventory() != gui.getInventory()) {
+ event.setCancelled(true);
+ return;
+ }
+ gui.onDrag(event);
+ }
+ }
+
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/KitEditorGamemodeGui.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/KitEditorGamemodeGui.java
new file mode 100644
index 0000000..e592b9c
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/KitEditorGamemodeGui.java
@@ -0,0 +1,69 @@
+package com.starpractice.gui;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.Gamemode;
+import com.starpractice.util.ConfigUtil;
+import com.starpractice.util.GuiUtil;
+import com.starpractice.util.IconUtil;
+import com.starpractice.util.ItemBuilder;
+import com.starpractice.util.SoundUtil;
+import java.util.Arrays;
+import java.util.List;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+
+public class KitEditorGamemodeGui extends AbstractGui {
+ private final StarPracticePlugin plugin;
+ private final int page;
+
+ public KitEditorGamemodeGui(StarPracticePlugin plugin, Player player) {
+ this(plugin, player, 0);
+ }
+
+ public KitEditorGamemodeGui(StarPracticePlugin plugin, Player player, int page) {
+ super(player, 54, plugin.getConfig().getString("ui.titles.kit_editor", "&8Kit Editor"));
+ this.plugin = plugin;
+ this.page = page;
+ }
+
+ @Override
+ public void open() {
+ plugin.getKitEditorSessionManager().enter(player);
+ super.open();
+ }
+
+ @Override
+ protected void draw(Inventory inventory) {
+ fillBackground(GuiUtil.backgroundItem(plugin));
+ List modes = plugin.getGamemodeManager().getAll();
+ int totalPages = (int) Math.ceil(modes.size() / 45.0);
+ int start = page * 45;
+ for (int i = 0; i < 45; i++) {
+ int index = start + i;
+ if (index >= modes.size()) {
+ break;
+ }
+ Gamemode mode = modes.get(index);
+ ItemStack item = IconUtil.gamemodeIcon(mode,
+ Arrays.asList("&7ID: &f" + mode.getId(), "&eClick to edit loadouts"));
+ int slot = i;
+ setItem(slot, item, e -> {
+ SoundUtil.play(player, plugin, "click");
+ new KitEditorLoadoutGui(plugin, player, mode).open();
+ });
+ }
+
+ if (page > 0) {
+ ItemStack prev = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.prev_page", Material.ARROW)).name("&ePrevious Page").build();
+ setItem(51, prev, e -> new KitEditorGamemodeGui(plugin, player, page - 1).open());
+ }
+ if (page + 1 < totalPages) {
+ ItemStack next = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.next_page", Material.ARROW)).name("&eNext Page").build();
+ setItem(52, next, e -> new KitEditorGamemodeGui(plugin, player, page + 1).open());
+ }
+ ItemStack back = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.back", Material.BARRIER)).name("&cBack").build();
+ setItem(53, back, e -> player.closeInventory());
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/KitEditorLoadoutGui.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/KitEditorLoadoutGui.java
new file mode 100644
index 0000000..c0c20cb
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/KitEditorLoadoutGui.java
@@ -0,0 +1,92 @@
+package com.starpractice.gui;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.Gamemode;
+import com.starpractice.model.Kit;
+import com.starpractice.util.ConfigUtil;
+import com.starpractice.util.GuiUtil;
+import com.starpractice.util.ItemBuilder;
+import com.starpractice.util.SoundUtil;
+import java.util.Arrays;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.bukkit.enchantments.Enchantment;
+import org.bukkit.inventory.ItemFlag;
+
+public class KitEditorLoadoutGui extends AbstractGui {
+ private final StarPracticePlugin plugin;
+ private final Gamemode gamemode;
+
+ public KitEditorLoadoutGui(StarPracticePlugin plugin, Player player, Gamemode gamemode) {
+ super(player, 27, plugin.getConfig().getString("ui.titles.kit_loadouts", "&8Kit Loadouts"));
+ this.plugin = plugin;
+ this.gamemode = gamemode;
+ }
+
+ @Override
+ public void open() {
+ plugin.getKitEditorSessionManager().enter(player);
+ super.open();
+ }
+
+ @Override
+ protected void draw(Inventory inventory) {
+ fillBackground(GuiUtil.backgroundItem(plugin));
+ int selected = plugin.getPlayerKitManager().getSelectedSlot(player.getUniqueId(), gamemode.getId());
+ setItem(2, buildBedrockEditButton(1), e -> openLayout(1));
+ setItem(4, buildBedrockEditButton(2), e -> openLayout(2));
+ setItem(6, buildBedrockEditButton(3), e -> openLayout(3));
+ setItem(11, buildBook(1, selected), e -> handleClick(1, e.isRightClick()));
+ setItem(13, buildBook(2, selected), e -> handleClick(2, e.isRightClick()));
+ setItem(15, buildBook(3, selected), e -> handleClick(3, e.isRightClick()));
+
+ ItemStack back = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.back", Material.BARRIER)).name("&cBack").build();
+ setItem(22, back, e -> new KitEditorGamemodeGui(plugin, player).open());
+ }
+
+ private ItemStack buildBook(int slot, int selected) {
+ Kit kit = plugin.getPlayerKitManager().getLoadout(player.getUniqueId(), gamemode.getId(), slot);
+ ItemStack book = new ItemBuilder(Material.BOOK)
+ .name("&aInventory " + slot)
+ .lore(Arrays.asList(
+ kit == null ? "&cNo loadout saved" : "&aLoadout saved",
+ "&eLeft click to select",
+ "&eRight click to edit"
+ ))
+ .build();
+ if (slot == selected) {
+ ItemMeta meta = book.getItemMeta();
+ if (meta != null) {
+ meta.addEnchant(Enchantment.UNBREAKING, 1, true);
+ meta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
+ book.setItemMeta(meta);
+ }
+ }
+ return book;
+ }
+
+ private void handleClick(int slot, boolean rightClick) {
+ if (rightClick) {
+ openLayout(slot);
+ return;
+ }
+ plugin.getPlayerKitManager().setSelectedSlot(player.getUniqueId(), gamemode.getId(), slot);
+ SoundUtil.play(player, plugin, "success");
+ new KitEditorLoadoutGui(plugin, player, gamemode).open();
+ }
+
+ private ItemStack buildBedrockEditButton(int slot) {
+ return new ItemBuilder(Material.KNOWLEDGE_BOOK)
+ .name("&aEdit Inventory " + slot)
+ .lore(Arrays.asList("&eBedrock friendly edit button", "&eClick to edit layout"))
+ .build();
+ }
+
+ private void openLayout(int slot) {
+ SoundUtil.play(player, plugin, "click");
+ new KitLayoutGui(plugin, player, gamemode, slot).open();
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/KitLayoutGui.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/KitLayoutGui.java
new file mode 100644
index 0000000..429ba0e
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/KitLayoutGui.java
@@ -0,0 +1,399 @@
+package com.starpractice.gui;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.Gamemode;
+import com.starpractice.model.Kit;
+import com.starpractice.util.ConfigUtil;
+import com.starpractice.util.GuiUtil;
+import com.starpractice.util.ItemBuilder;
+import com.starpractice.util.SoundUtil;
+import java.util.ArrayList;
+import java.util.List;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.event.inventory.InventoryDragEvent;
+import org.bukkit.event.inventory.InventoryAction;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.potion.PotionEffect;
+
+public class KitLayoutGui extends AbstractGui {
+ private final StarPracticePlugin plugin;
+ private final Gamemode gamemode;
+ private final int slot;
+ private List effects;
+ private Kit defaultKit;
+ private int selectedSlot = -1;
+ private final org.bukkit.NamespacedKey selectedKey;
+ private final org.bukkit.NamespacedKey placeholderKey;
+ private final org.bukkit.NamespacedKey addedEnchantKey;
+
+ public KitLayoutGui(StarPracticePlugin plugin, Player player, Gamemode gamemode, int slot) {
+ super(player, 54, plugin.getConfig().getString("ui.titles.kit_layout", "&8Edit Kit"));
+ this.plugin = plugin;
+ this.gamemode = gamemode;
+ this.slot = slot;
+ this.selectedKey = new org.bukkit.NamespacedKey(plugin, "kit_swap_selected");
+ this.placeholderKey = new org.bukkit.NamespacedKey(plugin, "kit_swap_placeholder");
+ this.addedEnchantKey = new org.bukkit.NamespacedKey(plugin, "kit_swap_added_enchant");
+ }
+
+ @Override
+ public void open() {
+ plugin.getKitEditorSessionManager().enter(player);
+ super.open();
+ }
+
+ @Override
+ protected void draw(Inventory inventory) {
+ fillBackground(GuiUtil.backgroundItem(plugin));
+ defaultKit = plugin.getPlayerKitManager().createDefaultLoadout(gamemode);
+ Kit base = plugin.getPlayerKitManager().getLoadout(player.getUniqueId(), gamemode.getId(), slot);
+ if (base == null) {
+ base = defaultKit;
+ }
+ effects = new ArrayList<>(base.getEffects());
+ applyKitToInventory(inventory, base);
+ decorateEditableSlots(inventory);
+
+ ItemStack save = new ItemBuilder(Material.LIME_DYE).name("&aSave").lore(List.of("&7Save this loadout")).build();
+ ItemStack revert = new ItemBuilder(Material.CHEST).name("&eRevert to Default").lore(List.of("&7Reset to default kit")).build();
+ ItemStack cancel = new ItemBuilder(Material.BARRIER).name("&cCancel").lore(List.of("&7Discard changes")).build();
+
+ setItem(51, save, e -> {
+ Kit kit = buildKitFromInventory(inventory, effects);
+ plugin.getPlayerKitManager().setLoadout(player.getUniqueId(), gamemode.getId(), slot, kit);
+ SoundUtil.play(player, plugin, "success");
+ new KitEditorLoadoutGui(plugin, player, gamemode).open();
+ });
+ setItem(52, revert, e -> {
+ resetToDefault(inventory);
+ SoundUtil.play(player, plugin, "click");
+ });
+ setItem(53, cancel, e -> {
+ SoundUtil.play(player, plugin, "click");
+ new KitEditorLoadoutGui(plugin, player, gamemode).open();
+ });
+ }
+
+ @Override
+ public void onClick(InventoryClickEvent event) {
+ if (event.getView().getTopInventory().getHolder() != this) {
+ return;
+ }
+ if (event.getClickedInventory() == null) {
+ event.setCancelled(true);
+ if (event.getCursor() != null && event.getCursor().getType() != Material.AIR) {
+ resetToDefault(event.getInventory());
+ event.setCursor(null);
+ }
+ return;
+ }
+ InventoryAction action = event.getAction();
+ if (isAction(action, "SWAP_OFFHAND")
+ || isAction(action, "HOTBAR_SWAP")
+ || isAction(action, "HOTBAR_MOVE_AND_READD")) {
+ event.setCancelled(true);
+ return;
+ }
+ int raw = event.getRawSlot();
+ if (raw < size) {
+ if (isAction(action, "DROP_ONE_SLOT") || isAction(action, "DROP_ALL_SLOT")
+ || isAction(action, "DROP_ONE_CURSOR") || isAction(action, "DROP_ALL_CURSOR")) {
+ event.setCancelled(true);
+ return;
+ }
+ if (event.isShiftClick()) {
+ event.setCancelled(true);
+ return;
+ }
+ if (isEditableSlot(raw)) {
+ event.setCancelled(true);
+ if (!handleSwapClick(event.getInventory(), raw)) {
+ return;
+ }
+ decorateEditableSlots(event.getInventory());
+ return;
+ }
+ event.setCancelled(true);
+ java.util.function.Consumer clickAction = actions.get(raw);
+ if (clickAction != null) {
+ clickAction.accept(event);
+ }
+ return;
+ }
+ event.setCancelled(true);
+ }
+
+ @Override
+ public void onDrag(InventoryDragEvent event) {
+ if (event.getView().getTopInventory().getHolder() != this) {
+ return;
+ }
+ ItemStack cursor = event.getOldCursor();
+ for (int raw : event.getRawSlots()) {
+ if (raw >= size) {
+ event.setCancelled(true);
+ return;
+ }
+ if (!isEditableSlot(raw)) {
+ event.setCancelled(true);
+ return;
+ }
+ if (isArmorSlot(raw) && cursor != null && cursor.getType() != Material.AIR && !isValidArmorItem(raw, cursor)) {
+ event.setCancelled(true);
+ return;
+ }
+ }
+ }
+
+ private boolean isEditableSlot(int slot) {
+ if (slot >= 0 && slot <= 35) {
+ return true;
+ }
+ return slot >= 45 && slot <= 49;
+ }
+
+ private boolean isArmorSlot(int slot) {
+ return slot >= 45 && slot <= 48;
+ }
+
+ private boolean isValidArmorItem(int slot, ItemStack item) {
+ String name = item.getType().name();
+ return switch (slot) {
+ case 45 -> name.endsWith("_HELMET") || name.equals("CARVED_PUMPKIN") || name.equals("PLAYER_HEAD")
+ || name.equals("PLAYER_WALL_HEAD") || name.equals("TURTLE_HELMET");
+ case 46 -> name.endsWith("_CHESTPLATE") || name.equals("ELYTRA");
+ case 47 -> name.endsWith("_LEGGINGS");
+ case 48 -> name.endsWith("_BOOTS");
+ default -> true;
+ };
+ }
+
+ private boolean isAction(InventoryAction action, String name) {
+ return action != null && action.name().equals(name);
+ }
+
+ private void applyKitToInventory(Inventory inventory, Kit kit) {
+ ItemStack[] contents = kit.getContents();
+ for (int i = 0; i < 36; i++) {
+ inventory.setItem(i, contents[i]);
+ }
+ ItemStack[] armor = kit.getArmor();
+ for (int i = 0; i < 4; i++) {
+ inventory.setItem(45 + i, armor[i]);
+ }
+ inventory.setItem(49, kit.getOffhand());
+ }
+
+ private void resetToDefault(Inventory inventory) {
+ defaultKit = plugin.getPlayerKitManager().createDefaultLoadout(gamemode);
+ effects = new ArrayList<>(defaultKit.getEffects());
+ applyKitToInventory(inventory, defaultKit);
+ selectedSlot = -1;
+ decorateEditableSlots(inventory);
+ }
+
+ private boolean handleSwapClick(Inventory inventory, int rawSlot) {
+ if (selectedSlot == -1) {
+ selectedSlot = rawSlot;
+ decorateEditableSlots(inventory);
+ playSwapSelectSound();
+ return false;
+ }
+ if (selectedSlot == rawSlot) {
+ selectedSlot = -1;
+ decorateEditableSlots(inventory);
+ playSwapSelectSound();
+ return false;
+ }
+ ItemStack first = normalizeSwapItem(inventory.getItem(selectedSlot));
+ ItemStack second = normalizeSwapItem(inventory.getItem(rawSlot));
+ if (isArmorSlot(rawSlot) && second != null && !isValidArmorItem(rawSlot, second)) {
+ SoundUtil.play(player, plugin, "error");
+ return false;
+ }
+ if (isArmorSlot(selectedSlot) && first != null && !isValidArmorItem(selectedSlot, first)) {
+ SoundUtil.play(player, plugin, "error");
+ return false;
+ }
+ setEditableItem(inventory, selectedSlot, second);
+ setEditableItem(inventory, rawSlot, first);
+ selectedSlot = -1;
+ decorateEditableSlots(inventory);
+ playSwapSuccessSound();
+ return true;
+ }
+
+ private void decorateEditableSlots(Inventory inventory) {
+ for (int slotIndex = 0; slotIndex < size; slotIndex++) {
+ if (!isEditableSlot(slotIndex)) {
+ continue;
+ }
+ ItemStack item = inventory.getItem(slotIndex);
+ setEditableItem(inventory, slotIndex, normalizeSwapItem(item));
+ }
+ }
+
+ private void setEditableItem(Inventory inventory, int slotIndex, ItemStack item) {
+ boolean selected = slotIndex == selectedSlot;
+ ItemStack display;
+ if (item == null || item.getType() == Material.AIR) {
+ display = buildPlaceholder(selected);
+ } else {
+ display = applySwapLore(item, selected);
+ }
+ inventory.setItem(slotIndex, display);
+ }
+
+ private ItemStack buildPlaceholder(boolean selected) {
+ ItemStack pane = new ItemBuilder(Material.LIGHT_GRAY_STAINED_GLASS_PANE)
+ .name("&7")
+ .lore(List.of("&6Click to swap!"))
+ .build();
+ org.bukkit.inventory.meta.ItemMeta meta = pane.getItemMeta();
+ if (meta != null) {
+ meta.getPersistentDataContainer().set(placeholderKey, org.bukkit.persistence.PersistentDataType.BYTE, (byte) 1);
+ if (selected) {
+ meta.getPersistentDataContainer().set(selectedKey, org.bukkit.persistence.PersistentDataType.BYTE, (byte) 1);
+ meta.addEnchant(org.bukkit.enchantments.Enchantment.UNBREAKING, 1, true);
+ meta.addItemFlags(org.bukkit.inventory.ItemFlag.HIDE_ENCHANTS);
+ meta.getPersistentDataContainer().set(addedEnchantKey, org.bukkit.persistence.PersistentDataType.BYTE, (byte) 1);
+ } else {
+ meta.getPersistentDataContainer().remove(selectedKey);
+ meta.removeEnchant(org.bukkit.enchantments.Enchantment.UNBREAKING);
+ meta.getPersistentDataContainer().remove(addedEnchantKey);
+ }
+ pane.setItemMeta(meta);
+ }
+ return pane;
+ }
+
+ private ItemStack applySwapLore(ItemStack original, boolean selected) {
+ ItemStack item = original.clone();
+ org.bukkit.inventory.meta.ItemMeta meta = item.getItemMeta();
+ if (meta == null) {
+ return item;
+ }
+ List lore = meta.getLore();
+ if (lore == null) {
+ lore = new ArrayList<>();
+ }
+ String line = com.starpractice.util.Text.color("&6Click to swap!");
+ if (!lore.contains(line)) {
+ lore.add(line);
+ }
+ meta.setLore(lore);
+ if (selected) {
+ meta.getPersistentDataContainer().set(selectedKey, org.bukkit.persistence.PersistentDataType.BYTE, (byte) 1);
+ if (meta.getEnchants().isEmpty()) {
+ meta.addEnchant(org.bukkit.enchantments.Enchantment.UNBREAKING, 1, true);
+ meta.addItemFlags(org.bukkit.inventory.ItemFlag.HIDE_ENCHANTS);
+ meta.getPersistentDataContainer().set(addedEnchantKey, org.bukkit.persistence.PersistentDataType.BYTE, (byte) 1);
+ }
+ } else {
+ meta.getPersistentDataContainer().remove(selectedKey);
+ if (meta.getPersistentDataContainer().has(addedEnchantKey, org.bukkit.persistence.PersistentDataType.BYTE)) {
+ meta.removeEnchant(org.bukkit.enchantments.Enchantment.UNBREAKING);
+ meta.getPersistentDataContainer().remove(addedEnchantKey);
+ }
+ }
+ item.setItemMeta(meta);
+ return item;
+ }
+
+ private ItemStack normalizeSwapItem(ItemStack item) {
+ if (item == null || item.getType() == Material.AIR) {
+ return null;
+ }
+ org.bukkit.inventory.meta.ItemMeta meta = item.getItemMeta();
+ if (meta != null && meta.getPersistentDataContainer().has(placeholderKey, org.bukkit.persistence.PersistentDataType.BYTE)) {
+ return null;
+ }
+ return stripSwapMeta(item);
+ }
+
+ private ItemStack stripSwapMeta(ItemStack item) {
+ ItemStack clone = item.clone();
+ org.bukkit.inventory.meta.ItemMeta meta = clone.getItemMeta();
+ if (meta == null) {
+ return clone;
+ }
+ List lore = meta.getLore();
+ if (lore != null) {
+ String line = com.starpractice.util.Text.color("&6Click to swap!");
+ lore.removeIf(line::equals);
+ meta.setLore(lore.isEmpty() ? null : lore);
+ }
+ if (meta.getPersistentDataContainer().has(selectedKey, org.bukkit.persistence.PersistentDataType.BYTE)) {
+ meta.getPersistentDataContainer().remove(selectedKey);
+ }
+ if (meta.getPersistentDataContainer().has(addedEnchantKey, org.bukkit.persistence.PersistentDataType.BYTE)) {
+ meta.removeEnchant(org.bukkit.enchantments.Enchantment.UNBREAKING);
+ meta.getPersistentDataContainer().remove(addedEnchantKey);
+ }
+ meta.getPersistentDataContainer().remove(placeholderKey);
+ clone.setItemMeta(meta);
+ return clone;
+ }
+
+ private void playSwapSelectSound() {
+ String soundName = plugin.getConfig().getString("kitEditor.swapSelectSound", "ENTITY_ITEM_BREAK");
+ playSwapSound(soundName, 1.0f, 1.0f);
+ }
+
+ private void playSwapSuccessSound() {
+ String soundName = plugin.getConfig().getString("kitEditor.swapSuccessSound", "ITEM_BOOK_PAGE_TURN");
+ playSwapSound(soundName, 1.0f, 1.0f);
+ }
+
+ private void playSwapSound(String soundName, float volume, float pitch) {
+ org.bukkit.Sound sound;
+ try {
+ sound = org.bukkit.Sound.valueOf(soundName);
+ } catch (IllegalArgumentException e) {
+ return;
+ }
+ player.playSound(player.getLocation(), sound, volume, pitch);
+ }
+
+ private Kit buildKitFromInventory(Inventory inventory, List effects) {
+ ItemStack[] contents = new ItemStack[36];
+ for (int i = 0; i < 36; i++) {
+ ItemStack item = inventory.getItem(i);
+ if (item == null || item.getType() == Material.AIR || isPlaceholder(item)) {
+ contents[i] = null;
+ continue;
+ }
+ contents[i] = stripSwapMeta(item);
+ }
+ ItemStack[] armor = new ItemStack[4];
+ for (int i = 0; i < 4; i++) {
+ ItemStack item = inventory.getItem(45 + i);
+ if (item == null || item.getType() == Material.AIR || isPlaceholder(item)) {
+ armor[i] = null;
+ continue;
+ }
+ armor[i] = stripSwapMeta(item);
+ }
+ ItemStack offhand = inventory.getItem(49);
+ if (offhand != null && offhand.getType() != Material.AIR && !isPlaceholder(offhand)) {
+ offhand = stripSwapMeta(offhand);
+ } else {
+ offhand = null;
+ }
+ return new Kit(contents, armor, offhand, new ArrayList<>(effects));
+ }
+
+ private boolean isPlaceholder(ItemStack item) {
+ if (item == null) {
+ return false;
+ }
+ org.bukkit.inventory.meta.ItemMeta meta = item.getItemMeta();
+ if (meta == null) {
+ return false;
+ }
+ return meta.getPersistentDataContainer().has(placeholderKey, org.bukkit.persistence.PersistentDataType.BYTE);
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/MainAdminGui.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/MainAdminGui.java
new file mode 100644
index 0000000..4bf7e44
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/MainAdminGui.java
@@ -0,0 +1,52 @@
+package com.starpractice.gui;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.util.ConfigUtil;
+import com.starpractice.util.GuiUtil;
+import com.starpractice.util.ItemBuilder;
+import com.starpractice.util.SoundUtil;
+import java.util.Arrays;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+
+public class MainAdminGui extends AbstractGui {
+ private final StarPracticePlugin plugin;
+
+ public MainAdminGui(StarPracticePlugin plugin, Player player) {
+ super(player, 27, plugin.getConfig().getString("ui.titles.admin"));
+ this.plugin = plugin;
+ }
+
+ @Override
+ protected void draw(Inventory inventory) {
+ fillBackground(GuiUtil.backgroundItem(plugin));
+ ItemStack modes = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.admin_gamemodes", Material.DIAMOND_SWORD))
+ .name("&aGamemodes")
+ .lore(Arrays.asList("&7Add, edit, or remove gamemodes"))
+ .build();
+ ItemStack arenas = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.admin_arenas", Material.GRASS_BLOCK))
+ .name("&aArenas")
+ .lore(Arrays.asList("&7Add, edit, or remove arenas"))
+ .build();
+ ItemStack spawn = new ItemBuilder(ConfigUtil.material(plugin, "ui.icons.admin_spawn", Material.RESPAWN_ANCHOR))
+ .name("&aSet Practice Spawn")
+ .lore(Arrays.asList("&7Click to set current location"))
+ .build();
+
+ setItem(11, modes, e -> {
+ SoundUtil.play(player, plugin, "click");
+ new GamemodeListGui(plugin, player, GamemodeListGui.Mode.EDIT).open();
+ });
+ setItem(13, arenas, e -> {
+ SoundUtil.play(player, plugin, "click");
+ new ArenaListGui(plugin, player, ArenaListGui.Mode.EDIT).open();
+ });
+ setItem(15, spawn, e -> {
+ SoundUtil.play(player, plugin, "success");
+ plugin.getHotbarManager().setSpawnData(new com.starpractice.model.SpawnData(player.getLocation()));
+ plugin.sendMessage(player, "&aPractice spawn set.");
+ });
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/PartyGamemodeGui.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/PartyGamemodeGui.java
new file mode 100644
index 0000000..5bb0d70
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/PartyGamemodeGui.java
@@ -0,0 +1,39 @@
+package com.starpractice.gui;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.Gamemode;
+import com.starpractice.model.PartyMatch;
+import com.starpractice.util.GuiUtil;
+import com.starpractice.util.IconUtil;
+import com.starpractice.util.SoundUtil;
+import java.util.Arrays;
+import java.util.List;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+
+public class PartyGamemodeGui extends AbstractGui {
+ private final StarPracticePlugin plugin;
+ private final PartyMatch.Mode mode;
+
+ public PartyGamemodeGui(StarPracticePlugin plugin, Player player, PartyMatch.Mode mode) {
+ super(player, 27, plugin.getConfig().getString("ui.titles.duel_gamemode"));
+ this.plugin = plugin;
+ this.mode = mode;
+ }
+
+ @Override
+ protected void draw(Inventory inventory) {
+ fillBackground(GuiUtil.backgroundItem(plugin));
+ List modes = plugin.getGamemodeManager().getEnabled();
+ for (int i = 0; i < Math.min(27, modes.size()); i++) {
+ Gamemode gm = modes.get(i);
+ ItemStack item = IconUtil.gamemodeIcon(gm, Arrays.asList("&7Click to select"));
+ int slot = i;
+ setItem(slot, item, e -> {
+ SoundUtil.play(player, plugin, "click");
+ new PartyRoundsGui(plugin, player, mode, gm).open();
+ });
+ }
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/PartyModeGui.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/PartyModeGui.java
new file mode 100644
index 0000000..9cafd14
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/PartyModeGui.java
@@ -0,0 +1,49 @@
+package com.starpractice.gui;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.PartyMatch;
+import com.starpractice.util.GuiUtil;
+import com.starpractice.util.ItemBuilder;
+import com.starpractice.util.SoundUtil;
+import java.util.Arrays;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+
+public class PartyModeGui extends AbstractGui {
+ private final StarPracticePlugin plugin;
+
+ public PartyModeGui(StarPracticePlugin plugin, Player player) {
+ super(player, 27, "&8Party Play");
+ this.plugin = plugin;
+ }
+
+ @Override
+ protected void draw(Inventory inventory) {
+ fillBackground(GuiUtil.backgroundItem(plugin));
+ ItemStack one = new ItemBuilder(Material.IRON_SWORD)
+ .name("&a1v1")
+ .lore(Arrays.asList("&7Requires 2 players"))
+ .build();
+ ItemStack two = new ItemBuilder(Material.DIAMOND_SWORD)
+ .name("&a2v2")
+ .lore(Arrays.asList("&7Requires 4 players"))
+ .build();
+ ItemStack ffa = new ItemBuilder(Material.GOLDEN_APPLE)
+ .name("&aFFA")
+ .lore(Arrays.asList("&7Requires 2 players"))
+ .build();
+ ItemStack back = new ItemBuilder(Material.BARRIER).name("&cBack").build();
+
+ setItem(11, one, e -> openGamemode(PartyMatch.Mode.ONE_V_ONE));
+ setItem(13, two, e -> openGamemode(PartyMatch.Mode.TWO_V_TWO));
+ setItem(15, ffa, e -> openGamemode(PartyMatch.Mode.FFA));
+ setItem(26, back, e -> player.closeInventory());
+ }
+
+ private void openGamemode(PartyMatch.Mode mode) {
+ SoundUtil.play(player, plugin, "click");
+ new PartyGamemodeGui(plugin, player, mode).open();
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/PartyRoundsGui.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/PartyRoundsGui.java
new file mode 100644
index 0000000..d14f0be
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/PartyRoundsGui.java
@@ -0,0 +1,63 @@
+package com.starpractice.gui;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.Gamemode;
+import com.starpractice.model.Party;
+import com.starpractice.model.PartyMatch;
+import com.starpractice.util.GuiUtil;
+import com.starpractice.util.ItemBuilder;
+import com.starpractice.util.SoundUtil;
+import java.util.Arrays;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+
+public class PartyRoundsGui extends AbstractGui {
+ private final StarPracticePlugin plugin;
+ private final PartyMatch.Mode mode;
+ private final Gamemode gamemode;
+
+ public PartyRoundsGui(StarPracticePlugin plugin, Player player, PartyMatch.Mode mode, Gamemode gamemode) {
+ super(player, 27, plugin.getConfig().getString("ui.titles.duel_rounds"));
+ this.plugin = plugin;
+ this.mode = mode;
+ this.gamemode = gamemode;
+ }
+
+ @Override
+ protected void draw(Inventory inventory) {
+ fillBackground(GuiUtil.backgroundItem(plugin));
+ setRoundItem(18, Material.GREEN_WOOL, 1);
+ setRoundItem(19, Material.LIME_WOOL, 2);
+ setRoundItem(20, Material.YELLOW_WOOL, 3);
+ setRoundItem(21, Material.ORANGE_WOOL, 4);
+ setRoundItem(22, Material.RED_WOOL, 5);
+ setRoundItem(23, Material.PINK_WOOL, 10);
+ setRoundItem(24, Material.MAGENTA_WOOL, 15);
+ setRoundItem(25, Material.PURPLE_WOOL, 20);
+ setRoundItem(26, Material.BLACK_WOOL, 25);
+ }
+
+ private void setRoundItem(int slot, Material material, int rounds) {
+ int requiredWins = rounds / 2 + 1;
+ ItemStack item = new ItemBuilder(material)
+ .name("&aRounds: " + rounds)
+ .lore(Arrays.asList("&7First to " + requiredWins + " wins", "&7Click to start"))
+ .build();
+ setItem(slot, item, e -> {
+ Party party = plugin.getPartyManager().getParty(player.getUniqueId());
+ if (party == null) {
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.party-none", "&cYou are not in a party."));
+ return;
+ }
+ if (!party.getLeader().equals(player.getUniqueId())) {
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.party-not-leader", "&cOnly the party leader can do that."));
+ return;
+ }
+ SoundUtil.play(player, plugin, "success");
+ player.closeInventory();
+ plugin.getPartyMatchManager().startMatch(party, mode, gamemode, rounds);
+ });
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/PrepotEditGui.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/PrepotEditGui.java
new file mode 100644
index 0000000..b7c1c0a
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/PrepotEditGui.java
@@ -0,0 +1,152 @@
+package com.starpractice.gui;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.Gamemode;
+import com.starpractice.model.PrepotData;
+import com.starpractice.util.GuiUtil;
+import com.starpractice.util.ItemBuilder;
+import com.starpractice.util.SoundUtil;
+import java.util.Arrays;
+import java.util.List;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.potion.PotionEffectType;
+
+public class PrepotEditGui extends AbstractGui {
+ private static final List EFFECTS = Arrays.asList(
+ PotionEffectType.STRENGTH,
+ PotionEffectType.SPEED,
+ PotionEffectType.FIRE_RESISTANCE,
+ PotionEffectType.INVISIBILITY,
+ PotionEffectType.REGENERATION,
+ PotionEffectType.SLOWNESS,
+ PotionEffectType.WEAKNESS,
+ PotionEffectType.SLOW_FALLING,
+ PotionEffectType.WATER_BREATHING
+ );
+
+ private final StarPracticePlugin plugin;
+ private final Gamemode gamemode;
+
+ public PrepotEditGui(StarPracticePlugin plugin, Player player, Gamemode gamemode) {
+ super(player, 54, plugin.getConfig().getString("ui.titles.prepot_edit"));
+ this.plugin = plugin;
+ this.gamemode = gamemode;
+ }
+
+ @Override
+ protected void draw(Inventory inventory) {
+ fillBackground(GuiUtil.backgroundItem(plugin));
+ for (int i = 0; i < EFFECTS.size(); i++) {
+ PotionEffectType type = EFFECTS.get(i);
+ PrepotData data = gamemode.getPrepotData(type);
+ String keyName = type.getKey().getKey();
+ ItemStack item = new ItemBuilder(iconFor(type))
+ .name("&a" + formatName(keyName))
+ .lore(Arrays.asList(
+ data.isEnabled() ? "&aEnabled" : "&cDisabled",
+ "&7Amplifier: &f" + data.getAmplifier(),
+ "&7Duration: &f" + data.getDurationSeconds() + "s",
+ "&eLeft click to toggle",
+ "&eRight click to set amplifier",
+ "&eShift right click to set duration"
+ ))
+ .build();
+ int slot = i;
+ setItem(slot, item, e -> {
+ if (e.isRightClick() && e.isShiftClick()) {
+ SoundUtil.play(player, plugin, "click");
+ player.closeInventory();
+ plugin.sendMessage(player, "&eEnter duration in seconds for " + formatName(keyName) + ":");
+ plugin.getChatInputManager().prompt(player, input -> {
+ Integer value = parseInt(input);
+ if (value == null) {
+ plugin.sendMessage(player, "&cInvalid number.");
+ } else {
+ data.setDurationSeconds(value);
+ SoundUtil.play(player, plugin, "success");
+ }
+ new PrepotEditGui(plugin, player, gamemode).open();
+ });
+ return;
+ }
+ if (e.isRightClick()) {
+ SoundUtil.play(player, plugin, "click");
+ player.closeInventory();
+ plugin.sendMessage(player, "&eEnter amplifier (0 = level I) for " + formatName(keyName) + ":");
+ plugin.getChatInputManager().prompt(player, input -> {
+ Integer value = parseInt(input);
+ if (value == null) {
+ plugin.sendMessage(player, "&cInvalid number.");
+ } else {
+ data.setAmplifier(value);
+ SoundUtil.play(player, plugin, "success");
+ }
+ new PrepotEditGui(plugin, player, gamemode).open();
+ });
+ return;
+ }
+ data.setEnabled(!data.isEnabled());
+ SoundUtil.play(player, plugin, "success");
+ new PrepotEditGui(plugin, player, gamemode).open();
+ });
+ }
+
+ ItemStack back = new ItemBuilder(com.starpractice.util.ConfigUtil.material(plugin, "ui.icons.back", Material.BARRIER)).name("&cBack").build();
+ setItem(53, back, e -> new GamemodeEditGui(plugin, player, gamemode).open());
+ }
+
+ private Integer parseInt(String input) {
+ try {
+ return Integer.parseInt(input.trim());
+ } catch (NumberFormatException e) {
+ return null;
+ }
+ }
+
+ private String formatName(String name) {
+ String lower = name.toLowerCase().replace("_", " ");
+ String[] parts = lower.split(" ");
+ StringBuilder out = new StringBuilder();
+ for (String part : parts) {
+ if (part.isEmpty()) {
+ continue;
+ }
+ out.append(Character.toUpperCase(part.charAt(0))).append(part.substring(1)).append(' ');
+ }
+ return out.toString().trim();
+ }
+
+ private Material iconFor(PotionEffectType type) {
+ if (type.equals(PotionEffectType.STRENGTH)) {
+ return Material.IRON_SWORD;
+ }
+ if (type.equals(PotionEffectType.SPEED)) {
+ return Material.SUGAR;
+ }
+ if (type.equals(PotionEffectType.FIRE_RESISTANCE)) {
+ return Material.MAGMA_CREAM;
+ }
+ if (type.equals(PotionEffectType.INVISIBILITY)) {
+ return Material.ENDER_EYE;
+ }
+ if (type.equals(PotionEffectType.REGENERATION)) {
+ return Material.GHAST_TEAR;
+ }
+ if (type.equals(PotionEffectType.SLOWNESS)) {
+ return Material.SLIME_BALL;
+ }
+ if (type.equals(PotionEffectType.WEAKNESS)) {
+ return Material.FERMENTED_SPIDER_EYE;
+ }
+ if (type.equals(PotionEffectType.SLOW_FALLING)) {
+ return Material.FEATHER;
+ }
+ if (type.equals(PotionEffectType.WATER_BREATHING)) {
+ return Material.PUFFERFISH;
+ }
+ return Material.POTION;
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/QueueGui.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/QueueGui.java
new file mode 100644
index 0000000..3816de9
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/QueueGui.java
@@ -0,0 +1,61 @@
+package com.starpractice.gui;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.Gamemode;
+import com.starpractice.util.GuiUtil;
+import com.starpractice.util.IconUtil;
+import com.starpractice.util.SoundUtil;
+import java.util.Arrays;
+import java.util.List;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+
+public class QueueGui extends AbstractGui {
+ private final StarPracticePlugin plugin;
+
+ public QueueGui(StarPracticePlugin plugin, Player player) {
+ super(player, 27, plugin.getConfig().getString("ui.titles.queue"));
+ this.plugin = plugin;
+ }
+
+ @Override
+ protected void draw(Inventory inventory) {
+ fillBackground(GuiUtil.backgroundItem(plugin));
+ List modes = plugin.getGamemodeManager().getEnabled();
+ for (int i = 0; i < Math.min(27, modes.size()); i++) {
+ Gamemode mode = modes.get(i);
+ int inQueue = plugin.getQueueManager().getQueueSize(mode.getId());
+ int inMatch = countInMatch(mode.getId());
+ ItemStack item = IconUtil.gamemodeIcon(mode, Arrays.asList(
+ "&7Click to queue",
+ "&aPlayers in queue: &e" + inQueue,
+ "&cPlayers in a match: &e" + inMatch
+ ));
+ int slot = i;
+ setItem(slot, item, e -> {
+ SoundUtil.play(player, plugin, "click");
+ plugin.getQueueManager().joinQueue(player, mode);
+ player.closeInventory();
+ });
+ }
+ }
+
+ private int countInMatch(String gamemodeId) {
+ int count = 0;
+ java.util.Set seen = new java.util.HashSet<>();
+ for (Player online : plugin.getServer().getOnlinePlayers()) {
+ com.starpractice.model.DuelMatch match = plugin.getMatchManager().getMatch(online);
+ if (match == null || !gamemodeId.equals(match.getGamemodeId())) {
+ continue;
+ }
+ if (seen.add(match.getPlayer1())) {
+ count++;
+ }
+ if (seen.add(match.getPlayer2())) {
+ count++;
+ }
+ }
+ return count;
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/SettingsGui.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/SettingsGui.java
new file mode 100644
index 0000000..2367a33
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/gui/SettingsGui.java
@@ -0,0 +1,57 @@
+package com.starpractice.gui;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.PlayerSettings;
+import com.starpractice.util.GuiUtil;
+import com.starpractice.util.ItemBuilder;
+import com.starpractice.util.SoundUtil;
+import java.util.Arrays;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+
+public class SettingsGui extends AbstractGui {
+ private final StarPracticePlugin plugin;
+
+ public SettingsGui(StarPracticePlugin plugin, Player player) {
+ super(player, 9, "Settings");
+ this.plugin = plugin;
+ }
+
+ @Override
+ protected void draw(Inventory inventory) {
+ fillBackground(GuiUtil.backgroundItem(plugin));
+ PlayerSettings settings = plugin.getSettingsManager().getSettings(player.getUniqueId());
+
+ setItem(3, buildToggleItem("Duel Requests", settings.isDuelRequests()), e -> {
+ settings.setDuelRequests(!settings.isDuelRequests());
+ plugin.getSettingsManager().update(player.getUniqueId(), settings);
+ SoundUtil.play(player, plugin, "click");
+ new SettingsGui(plugin, player).open();
+ });
+
+ setItem(4, buildToggleItem("Party Invites", settings.isPartyInvites()), e -> {
+ settings.setPartyInvites(!settings.isPartyInvites());
+ plugin.getSettingsManager().update(player.getUniqueId(), settings);
+ SoundUtil.play(player, plugin, "click");
+ new SettingsGui(plugin, player).open();
+ });
+
+ setItem(5, buildToggleItem("Friend Requests", settings.isFriendRequests()), e -> {
+ settings.setFriendRequests(!settings.isFriendRequests());
+ plugin.getSettingsManager().update(player.getUniqueId(), settings);
+ SoundUtil.play(player, plugin, "click");
+ new SettingsGui(plugin, player).open();
+ });
+ }
+
+ private ItemStack buildToggleItem(String name, boolean enabled) {
+ Material material = enabled ? Material.LIME_WOOL : Material.RED_WOOL;
+ String status = enabled ? "&aON" : "&cOFF";
+ return new ItemBuilder(material)
+ .name("&f" + name)
+ .lore(Arrays.asList("&7Status: " + status, "&7Click to toggle"))
+ .build();
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/listener/PlayerListener.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/listener/PlayerListener.java
new file mode 100644
index 0000000..79a6415
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/listener/PlayerListener.java
@@ -0,0 +1,672 @@
+package com.starpractice.listener;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.DuelMatch;
+import com.starpractice.model.Gamemode;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.block.BlockBreakEvent;
+import org.bukkit.event.block.BlockDamageEvent;
+import org.bukkit.event.block.BlockPlaceEvent;
+import org.bukkit.event.entity.EntityDamageByEntityEvent;
+import org.bukkit.event.entity.EntityPickupItemEvent;
+import org.bukkit.event.player.PlayerExpChangeEvent;
+import org.bukkit.event.entity.EntityRegainHealthEvent;
+import org.bukkit.event.entity.PlayerDeathEvent;
+import org.bukkit.event.player.AsyncPlayerChatEvent;
+import org.bukkit.event.player.PlayerChangedWorldEvent;
+import org.bukkit.event.player.PlayerCommandPreprocessEvent;
+import org.bukkit.event.player.PlayerInteractEvent;
+import org.bukkit.event.player.PlayerJoinEvent;
+import org.bukkit.event.player.PlayerMoveEvent;
+import org.bukkit.event.player.PlayerQuitEvent;
+import org.bukkit.event.player.PlayerRespawnEvent;
+import org.bukkit.event.player.PlayerTeleportEvent;
+import org.bukkit.event.inventory.InventoryCloseEvent;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.event.inventory.InventoryDragEvent;
+import org.bukkit.event.player.PlayerDropItemEvent;
+import org.bukkit.event.player.PlayerInteractEntityEvent;
+import org.bukkit.event.entity.ProjectileLaunchEvent;
+
+public class PlayerListener implements Listener {
+ private final StarPracticePlugin plugin;
+
+ public PlayerListener(StarPracticePlugin plugin) {
+ this.plugin = plugin;
+ }
+
+ @EventHandler
+ public void onChat(AsyncPlayerChatEvent event) {
+ if (event.isCancelled()) {
+ return;
+ }
+ if (plugin.getChatInputManager().isPrompting(event.getPlayer())) {
+ return;
+ }
+ if (!plugin.getConfig().getBoolean("chat.duelOnly.enabled", true)) {
+ return;
+ }
+ Player sender = event.getPlayer();
+ DuelMatch match = plugin.getMatchManager().getMatch(sender);
+ boolean spectating = plugin.getSpectateManager().isSpectating(sender);
+ String arenaId = null;
+ if (match == null && spectating) {
+ arenaId = plugin.getSpectateManager().getSpectatorArenaId(sender);
+ match = plugin.getMatchManager().getMatchByArena(arenaId);
+ }
+ if (match != null) {
+ arenaId = match.getArenaId();
+ }
+ if (match != null || spectating) {
+ java.util.Set recipients = event.getRecipients();
+ final java.util.UUID p1 = match != null ? match.getPlayer1() : null;
+ final java.util.UUID p2 = match != null ? match.getPlayer2() : null;
+ final String arena = arenaId;
+ recipients.removeIf(target -> {
+ java.util.UUID uuid = target.getUniqueId();
+ if (p1 != null && p1.equals(uuid)) {
+ return false;
+ }
+ if (p2 != null && p2.equals(uuid)) {
+ return false;
+ }
+ String targetArena = plugin.getSpectateManager().getSpectatorArenaId(target);
+ return arena == null || !arena.equals(targetArena);
+ });
+ return;
+ }
+ java.util.Set recipients = event.getRecipients();
+ recipients.removeIf(target -> plugin.getMatchManager().isInMatch(target)
+ || plugin.getSpectateManager().isSpectating(target));
+ }
+
+ @EventHandler
+ public void onJoin(PlayerJoinEvent event) {
+ Player player = event.getPlayer();
+ String joinMessage = event.getJoinMessage();
+ event.setJoinMessage(null);
+ java.util.UUID uuid = player.getUniqueId();
+ plugin.getQueueManager().removePlayer(uuid);
+ plugin.getMatchManager().clearRuntimeState(uuid);
+ if (plugin.getConfig().getBoolean("features.parties.enabled", true)) {
+ plugin.getPartyMatchManager().clearRuntimeState(uuid);
+ }
+ plugin.getSpectateManager().clearRuntimeState(uuid);
+ com.starpractice.util.TablistUtil.forget(uuid);
+ if (plugin.getMatchManager().consumePendingReturn(player)) {
+ plugin.getHotbarManager().sendToSpawn(player);
+ plugin.getMatchManager().refreshAllVisibility();
+ return;
+ }
+ if (plugin.getConfig().getBoolean("spawnOnJoin.enabled", true)) {
+ plugin.getHotbarManager().sendToSpawn(player);
+ plugin.getMatchManager().refreshAllVisibility();
+ broadcastSystemMessage(joinMessage);
+ return;
+ }
+ plugin.getHotbarManager().handleWorldUpdate(player);
+ plugin.getMatchManager().refreshAllVisibility();
+ broadcastSystemMessage(joinMessage);
+ }
+
+ @EventHandler
+ public void onQuit(PlayerQuitEvent event) {
+ Player player = event.getPlayer();
+ com.starpractice.util.TablistUtil.forget(player.getUniqueId());
+ if (plugin.getKitEditorSessionManager().isInSession(player)) {
+ plugin.getKitEditorSessionManager().exit(player);
+ }
+ plugin.getQueueManager().removePlayer(player.getUniqueId());
+ plugin.getDuelRequestManager().removeAllFor(player);
+ if (plugin.getConfig().getBoolean("features.friends.enabled", true)) {
+ plugin.getFriendManager().removeAllRequestsFor(player);
+ }
+ if (plugin.getConfig().getBoolean("features.parties.enabled", true)) {
+ plugin.getPartyManager().removeAllRequestsFor(player);
+ }
+ if (plugin.getMatchManager().isInMatch(player)) {
+ plugin.getMatchManager().markPendingReturn(player.getUniqueId());
+ plugin.getMatchManager().forfeitOnQuit(player);
+ }
+ if (plugin.getConfig().getBoolean("features.parties.enabled", true)
+ && plugin.getPartyMatchManager().isInMatch(player)) {
+ plugin.getPartyMatchManager().forfeit(player);
+ }
+ if (plugin.getConfig().getBoolean("features.parties.enabled", true)) {
+ plugin.getPartyManager().forceLeave(player);
+ }
+ if (plugin.getSpectateManager().isSpectating(player)) {
+ plugin.getSpectateManager().leave(player);
+ }
+ plugin.getHotbarManager().restoreIfStored(player);
+ }
+
+ @EventHandler
+ public void onDeath(PlayerDeathEvent event) {
+ String deathMessage = event.getDeathMessage();
+ event.setDeathMessage(null);
+ Gamemode mode = null;
+ DuelMatch duelMatch = plugin.getMatchManager().getMatch(event.getEntity());
+ if (duelMatch != null) {
+ mode = plugin.getGamemodeManager().getById(duelMatch.getGamemodeId());
+ } else if (plugin.getConfig().getBoolean("features.parties.enabled", true)
+ && plugin.getPartyMatchManager().isInMatch(event.getEntity())) {
+ com.starpractice.model.PartyMatch partyMatch = plugin.getPartyMatchManager().getMatch(event.getEntity());
+ if (partyMatch != null) {
+ mode = plugin.getGamemodeManager().getById(partyMatch.getGamemodeId());
+ }
+ }
+ if (mode != null && !mode.isLootDrops()) {
+ event.getDrops().clear();
+ event.setDroppedExp(0);
+ }
+ plugin.getMatchManager().handleDeath(event.getEntity());
+ if (plugin.getConfig().getBoolean("features.parties.enabled", true)
+ && plugin.getPartyMatchManager().isInMatch(event.getEntity())) {
+ plugin.getPartyMatchManager().handleDeath(event.getEntity());
+ }
+ broadcastSystemMessage(deathMessage);
+ }
+
+ @EventHandler
+ public void onRespawn(PlayerRespawnEvent event) {
+ Player player = event.getPlayer();
+ if (!plugin.getMatchManager().isInMatch(player)) {
+ return;
+ }
+ org.bukkit.Location target = plugin.getMatchManager().consumePendingSpectator(player);
+ if (target != null) {
+ event.setRespawnLocation(target);
+ }
+ plugin.getScheduler().runAtEntity(player, () -> {
+ player.setGameMode(org.bukkit.GameMode.SPECTATOR);
+ if (target != null) {
+ player.teleport(target);
+ }
+ plugin.getScheduler().runLaterAtEntity(player, 1L, () -> {
+ if (player.getGameMode() != org.bukkit.GameMode.SPECTATOR) {
+ plugin.getHotbarManager().sendToSpawn(player);
+ }
+ });
+ });
+ }
+
+ @EventHandler
+ public void onMove(PlayerMoveEvent event) {
+ if (plugin.getMatchManager().isFrozen(event.getPlayer())
+ || (plugin.getConfig().getBoolean("features.parties.enabled", true)
+ && plugin.getPartyMatchManager().isFrozen(event.getPlayer()))) {
+ if (event.getFrom().getBlockX() != event.getTo().getBlockX()
+ || event.getFrom().getBlockY() != event.getTo().getBlockY()
+ || event.getFrom().getBlockZ() != event.getTo().getBlockZ()) {
+ event.setCancelled(true);
+ }
+ }
+ if (event.getFrom().getBlockX() == event.getTo().getBlockX()
+ && event.getFrom().getBlockY() == event.getTo().getBlockY()
+ && event.getFrom().getBlockZ() == event.getTo().getBlockZ()) {
+ return;
+ }
+ Player player = event.getPlayer();
+ DuelMatch duelMatch = plugin.getMatchManager().getMatch(player);
+ com.starpractice.model.PartyMatch partyMatch = null;
+ if (plugin.getConfig().getBoolean("features.parties.enabled", true)) {
+ partyMatch = plugin.getPartyMatchManager().getMatch(player);
+ }
+ boolean duelActive = duelMatch != null && duelMatch.getState() == DuelMatch.State.ACTIVE;
+ boolean partyActive = partyMatch != null && partyMatch.getState() == com.starpractice.model.PartyMatch.State.ACTIVE;
+ boolean matchActive = duelActive || partyActive;
+ com.starpractice.model.Arena arena = getArenaForPlayer(player);
+ if (arena == null || arena.getCorner1() == null || arena.getCorner2() == null) {
+ return;
+ }
+ boolean isSpectating = plugin.getSpectateManager().isSpectating(player)
+ || player.getGameMode() == org.bukkit.GameMode.SPECTATOR
+ || plugin.getMatchManager().isLegacyDuelSpectator(player)
+ || (partyMatch != null && player.getGameMode() == org.bukkit.GameMode.SPECTATOR);
+ if (!isInsideArena(player.getLocation(), arena)) {
+ if (isSpectating) {
+ org.bukkit.Location target = arena.getSpectatorSpawn();
+ if (target != null) {
+ plugin.getScheduler().runAtEntity(player, () -> player.teleport(target));
+ }
+ return;
+ }
+ if (!matchActive) {
+ return;
+ }
+ if (duelMatch != null) {
+ plugin.getMatchManager().handleEscape(player, arena);
+ } else if (partyMatch != null) {
+ plugin.getPartyMatchManager().handleEscape(player, arena);
+ }
+ }
+ }
+
+ @EventHandler
+ public void onDamage(EntityDamageByEntityEvent event) {
+ if (event.getDamager() instanceof Player attacker
+ && (plugin.getSpectateManager().isSpectating(attacker)
+ || plugin.getMatchManager().isLegacyDuelSpectator(attacker))) {
+ event.setCancelled(true);
+ return;
+ }
+ if (!(event.getEntity() instanceof Player)) {
+ return;
+ }
+ Player victim = (Player) event.getEntity();
+ if (plugin.getSpectateManager().isSpectating(victim) || plugin.getMatchManager().isLegacyDuelSpectator(victim)) {
+ event.setCancelled(true);
+ return;
+ }
+ if (plugin.getMatchManager().isFrozen(victim)
+ || (plugin.getConfig().getBoolean("features.parties.enabled", true)
+ && plugin.getPartyMatchManager().isFrozen(victim))) {
+ event.setCancelled(true);
+ return;
+ }
+ if (event.getDamager() instanceof Player attacker) {
+ if (plugin.getSpectateManager().isSpectating(attacker) || plugin.getMatchManager().isLegacyDuelSpectator(attacker)) {
+ event.setCancelled(true);
+ return;
+ }
+ if (plugin.getConfig().getBoolean("features.parties.enabled", true)
+ && plugin.getPartyMatchManager().isInMatch(attacker)
+ && plugin.getPartyMatchManager().isInMatch(victim)) {
+ com.starpractice.model.PartyMatch match = plugin.getPartyMatchManager().getMatch(attacker);
+ if (match != null && match.getMode() == com.starpractice.model.PartyMatch.Mode.TWO_V_TWO) {
+ Integer attackerTeam = match.getTeam().get(attacker.getUniqueId());
+ Integer victimTeam = match.getTeam().get(victim.getUniqueId());
+ if (attackerTeam != null && attackerTeam.equals(victimTeam)) {
+ event.setCancelled(true);
+ return;
+ }
+ }
+ }
+ if (plugin.getMatchManager().isFrozen(attacker)
+ || (plugin.getConfig().getBoolean("features.parties.enabled", true)
+ && plugin.getPartyMatchManager().isFrozen(attacker))) {
+ event.setCancelled(true);
+ }
+ }
+ }
+
+ @EventHandler
+ public void onPickup(EntityPickupItemEvent event) {
+ if (event.getEntity() instanceof Player player
+ && (plugin.getSpectateManager().isSpectating(player) || plugin.getMatchManager().isLegacyDuelSpectator(player)
+ || plugin.getKitEditorSessionManager().isInSession(player))) {
+ event.setCancelled(true);
+ }
+ }
+
+ @EventHandler
+ public void onExp(PlayerExpChangeEvent event) {
+ Player player = event.getPlayer();
+ if (plugin.getSpectateManager().isLegacySpectator(player)
+ || plugin.getMatchManager().isLegacyDuelSpectator(player)) {
+ event.setAmount(0);
+ player.setExp(0.0f);
+ player.setLevel(0);
+ player.setTotalExperience(0);
+ }
+ }
+
+ @EventHandler
+ public void onDrop(PlayerDropItemEvent event) {
+ if (plugin.getSpectateManager().isSpectating(event.getPlayer())
+ || plugin.getMatchManager().isLegacyDuelSpectator(event.getPlayer())
+ || plugin.getKitEditorSessionManager().isInSession(event.getPlayer())) {
+ event.setCancelled(true);
+ }
+ }
+
+ @EventHandler
+ public void onCommand(PlayerCommandPreprocessEvent event) {
+ if (plugin.getKitEditorSessionManager().isInSession(event.getPlayer())) {
+ event.setCancelled(true);
+ plugin.sendMessage(event.getPlayer(), "&cClose the kit editor before using commands.");
+ return;
+ }
+ boolean inRestrictedState = plugin.getSpectateManager().isSpectating(event.getPlayer())
+ || plugin.getMatchManager().isLegacyDuelSpectator(event.getPlayer())
+ || plugin.getMatchManager().isInMatch(event.getPlayer())
+ || (plugin.getConfig().getBoolean("features.parties.enabled", true)
+ && plugin.getPartyMatchManager().isInMatch(event.getPlayer()));
+ if (inRestrictedState) {
+ if (event.getPlayer().hasPermission(plugin.getAdminPermission())) {
+ return;
+ }
+ if (!isSpectatorCommandAllowed(event.getMessage())) {
+ event.setCancelled(true);
+ plugin.sendMessage(event.getPlayer(), "&cYou cannot use that command during a match.");
+ }
+ }
+ }
+
+ private boolean isSpectatorCommandAllowed(String message) {
+ if (message == null || message.isEmpty()) {
+ return false;
+ }
+ String cmd = message.trim();
+ if (cmd.startsWith("/")) {
+ cmd = cmd.substring(1);
+ }
+ if (cmd.isEmpty()) {
+ return false;
+ }
+ String root = cmd.split("\\s+")[0].toLowerCase();
+ for (String allowed : plugin.getConfig().getStringList("spectator.allowedCommands")) {
+ if (allowed == null || allowed.isEmpty()) {
+ continue;
+ }
+ String a = allowed.trim().toLowerCase();
+ if (a.startsWith("/")) {
+ a = a.substring(1);
+ }
+ if (a.isEmpty()) {
+ continue;
+ }
+ if (root.equals(a)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @EventHandler
+ public void onInventoryClose(InventoryCloseEvent event) {
+ if (!(event.getPlayer() instanceof Player player)) {
+ return;
+ }
+ if (!com.starpractice.manager.KitEditorSessionManager.isKitEditorHolder(event.getInventory().getHolder())) {
+ return;
+ }
+ plugin.getScheduler().runLaterAtEntity(player, 1L, () -> {
+ if (!plugin.getKitEditorSessionManager().isInSession(player)) {
+ return;
+ }
+ if (com.starpractice.manager.KitEditorSessionManager.isKitEditorHolder(
+ player.getOpenInventory().getTopInventory().getHolder())) {
+ return;
+ }
+ plugin.getKitEditorSessionManager().exit(player);
+ });
+ }
+
+ @EventHandler
+ public void onBlockDamage(BlockDamageEvent event) {
+ Player player = event.getPlayer();
+ if (plugin.getSpectateManager().isSpectating(player)
+ || plugin.getMatchManager().isLegacyDuelSpectator(player)) {
+ event.setCancelled(true);
+ if (plugin.getSpectateManager().isLegacySpectator(player)
+ || plugin.getMatchManager().isLegacyDuelSpectator(player)) {
+ player.sendMessage(com.starpractice.util.Text.color("&cYou cannot break blocks while spectating."));
+ player.sendBlockChange(event.getBlock().getLocation(), event.getBlock().getBlockData());
+ }
+ }
+ }
+
+ @EventHandler
+ public void onBreak(BlockBreakEvent event) {
+ Player player = event.getPlayer();
+ if (plugin.getMatchManager().isFrozen(player)
+ || (plugin.getConfig().getBoolean("features.parties.enabled", true)
+ && plugin.getPartyMatchManager().isFrozen(player))) {
+ event.setCancelled(true);
+ return;
+ }
+ if (plugin.getSpectateManager().isSpectating(player)
+ || plugin.getMatchManager().isLegacyDuelSpectator(player)) {
+ event.setCancelled(true);
+ if (plugin.getSpectateManager().isLegacySpectator(player)
+ || plugin.getMatchManager().isLegacyDuelSpectator(player)) {
+ player.sendMessage(com.starpractice.util.Text.color("&cYou cannot break blocks while spectating."));
+ player.sendBlockChange(event.getBlock().getLocation(), event.getBlock().getBlockData());
+ }
+ return;
+ }
+ boolean inPartyMatch = plugin.getConfig().getBoolean("features.parties.enabled", true)
+ && plugin.getPartyMatchManager().isInMatch(player);
+ if (!plugin.getMatchManager().isInMatch(player) && !inPartyMatch) {
+ return;
+ }
+ Gamemode mode;
+ String arenaId;
+ DuelMatch match = plugin.getMatchManager().getMatch(player);
+ if (match != null) {
+ mode = plugin.getGamemodeManager().getById(match.getGamemodeId());
+ arenaId = match.getArenaId();
+ } else {
+ com.starpractice.model.PartyMatch partyMatch = plugin.getPartyMatchManager().getMatch(player);
+ if (partyMatch == null) {
+ return;
+ }
+ mode = plugin.getGamemodeManager().getById(partyMatch.getGamemodeId());
+ arenaId = partyMatch.getArenaId();
+ }
+ if (mode == null) {
+ return;
+ }
+ if (mode.isOnlyBreakPlaced()) {
+ boolean allowed = match != null
+ ? plugin.getMatchManager().isPlacedBlock(arenaId, event.getBlock().getLocation())
+ : plugin.getPartyMatchManager().isPlacedBlock(arenaId, event.getBlock().getLocation());
+ if (!allowed) {
+ event.setCancelled(true);
+ }
+ return;
+ }
+ if (!mode.isBlockBreak()) {
+ event.setCancelled(true);
+ }
+ }
+
+ @EventHandler
+ public void onPlace(BlockPlaceEvent event) {
+ if (plugin.getSpectateManager().isSpectating(event.getPlayer())
+ || plugin.getMatchManager().isLegacyDuelSpectator(event.getPlayer())) {
+ event.setCancelled(true);
+ return;
+ }
+ Player player = event.getPlayer();
+ if (plugin.getMatchManager().isFrozen(player)
+ || (plugin.getConfig().getBoolean("features.parties.enabled", true)
+ && plugin.getPartyMatchManager().isFrozen(player))) {
+ event.setCancelled(true);
+ return;
+ }
+ boolean inPartyMatch = plugin.getConfig().getBoolean("features.parties.enabled", true)
+ && plugin.getPartyMatchManager().isInMatch(player);
+ if (!plugin.getMatchManager().isInMatch(player) && !inPartyMatch) {
+ return;
+ }
+ Gamemode mode;
+ String arenaId;
+ DuelMatch match = plugin.getMatchManager().getMatch(player);
+ if (match != null) {
+ mode = plugin.getGamemodeManager().getById(match.getGamemodeId());
+ arenaId = match.getArenaId();
+ } else {
+ com.starpractice.model.PartyMatch partyMatch = plugin.getPartyMatchManager().getMatch(player);
+ if (partyMatch == null) {
+ return;
+ }
+ mode = plugin.getGamemodeManager().getById(partyMatch.getGamemodeId());
+ arenaId = partyMatch.getArenaId();
+ }
+ if (mode == null) {
+ return;
+ }
+ if (!mode.isBlockPlace()) {
+ event.setCancelled(true);
+ return;
+ }
+ if (match != null) {
+ plugin.getMatchManager().recordPlacedBlock(arenaId, event.getBlockPlaced().getLocation());
+ } else {
+ plugin.getPartyMatchManager().recordPlacedBlock(arenaId, event.getBlockPlaced().getLocation());
+ }
+ }
+
+ @EventHandler
+ public void onRegen(EntityRegainHealthEvent event) {
+ if (!(event.getEntity() instanceof Player)) {
+ return;
+ }
+ Player player = (Player) event.getEntity();
+ boolean inPartyMatch = plugin.getConfig().getBoolean("features.parties.enabled", true)
+ && plugin.getPartyMatchManager().isInMatch(player);
+ if (!plugin.getMatchManager().isInMatch(player) && !inPartyMatch) {
+ return;
+ }
+ Gamemode mode;
+ DuelMatch match = plugin.getMatchManager().getMatch(player);
+ if (match != null) {
+ mode = plugin.getGamemodeManager().getById(match.getGamemodeId());
+ } else {
+ com.starpractice.model.PartyMatch partyMatch = plugin.getPartyMatchManager().getMatch(player);
+ if (partyMatch == null) {
+ return;
+ }
+ mode = plugin.getGamemodeManager().getById(partyMatch.getGamemodeId());
+ }
+ if (mode == null) {
+ return;
+ }
+ if (!mode.isNaturalRegen() && event.getRegainReason() == EntityRegainHealthEvent.RegainReason.SATIATED) {
+ event.setCancelled(true);
+ }
+ }
+
+ @EventHandler
+ public void onInteract(PlayerInteractEvent event) {
+ Player player = event.getPlayer();
+ if (plugin.getSpectateManager().isSpectating(player)
+ || plugin.getMatchManager().isLegacyDuelSpectator(player)) {
+ event.setCancelled(true);
+ return;
+ }
+ if (plugin.getMatchManager().isFrozen(player)
+ || (plugin.getConfig().getBoolean("features.parties.enabled", true)
+ && plugin.getPartyMatchManager().isFrozen(player))) {
+ event.setCancelled(true);
+ return;
+ }
+ if (plugin.getHotbarManager().isHotbarItem(event.getItem())) {
+ event.setCancelled(true);
+ player.performCommand("queue");
+ }
+ }
+
+ @EventHandler
+ public void onInteractEntity(PlayerInteractEntityEvent event) {
+ if (plugin.getSpectateManager().isSpectating(event.getPlayer())
+ || plugin.getMatchManager().isLegacyDuelSpectator(event.getPlayer())) {
+ event.setCancelled(true);
+ }
+ }
+
+ @EventHandler
+ public void onInventoryClick(InventoryClickEvent event) {
+ if (event.getWhoClicked() instanceof Player player
+ && (plugin.getSpectateManager().isSpectating(player) || plugin.getMatchManager().isLegacyDuelSpectator(player))) {
+ event.setCancelled(true);
+ }
+ }
+
+ @EventHandler
+ public void onInventoryDrag(InventoryDragEvent event) {
+ if (event.getWhoClicked() instanceof Player player
+ && (plugin.getSpectateManager().isSpectating(player) || plugin.getMatchManager().isLegacyDuelSpectator(player))) {
+ event.setCancelled(true);
+ }
+ }
+
+ @EventHandler
+ public void onWorldChange(PlayerChangedWorldEvent event) {
+ plugin.getHotbarManager().handleWorldUpdate(event.getPlayer());
+ }
+
+ @EventHandler
+ public void onTeleport(PlayerTeleportEvent event) {
+ plugin.getHotbarManager().handleWorldUpdate(event.getPlayer());
+ }
+
+ @EventHandler
+ public void onProjectileLaunch(ProjectileLaunchEvent event) {
+ if (!(event.getEntity().getShooter() instanceof Player player)) {
+ return;
+ }
+ if (plugin.getMatchManager().isFrozen(player)
+ || (plugin.getConfig().getBoolean("features.parties.enabled", true)
+ && plugin.getPartyMatchManager().isFrozen(player))) {
+ event.setCancelled(true);
+ }
+ }
+
+
+ private com.starpractice.model.Arena getArenaForPlayer(Player player) {
+ DuelMatch match = plugin.getMatchManager().getMatch(player);
+ if (match != null) {
+ return plugin.getArenaManager().getById(match.getArenaId());
+ }
+ if (plugin.getConfig().getBoolean("features.parties.enabled", true)
+ && plugin.getPartyMatchManager().isInMatch(player)) {
+ com.starpractice.model.PartyMatch party = plugin.getPartyMatchManager().getMatch(player);
+ if (party != null) {
+ return plugin.getArenaManager().getById(party.getArenaId());
+ }
+ }
+ if (plugin.getSpectateManager().isSpectating(player)) {
+ String arenaId = plugin.getSpectateManager().getSpectatorArenaId(player);
+ if (arenaId != null) {
+ return plugin.getArenaManager().getById(arenaId);
+ }
+ }
+ return null;
+ }
+
+ private boolean isInsideArena(org.bukkit.Location loc, com.starpractice.model.Arena arena) {
+ if (loc == null || arena.getCorner1() == null || arena.getCorner2() == null) {
+ return true;
+ }
+ if (loc.getWorld() == null || arena.getCorner1().getWorld() == null) {
+ return true;
+ }
+ if (!loc.getWorld().getName().equals(arena.getCorner1().getWorld().getName())) {
+ return false;
+ }
+ int minX = Math.min(arena.getCorner1().getBlockX(), arena.getCorner2().getBlockX());
+ int minY = Math.min(arena.getCorner1().getBlockY(), arena.getCorner2().getBlockY());
+ int minZ = Math.min(arena.getCorner1().getBlockZ(), arena.getCorner2().getBlockZ());
+ int maxX = Math.max(arena.getCorner1().getBlockX(), arena.getCorner2().getBlockX());
+ int maxY = Math.max(arena.getCorner1().getBlockY(), arena.getCorner2().getBlockY());
+ int maxZ = Math.max(arena.getCorner1().getBlockZ(), arena.getCorner2().getBlockZ());
+ int x = loc.getBlockX();
+ int y = loc.getBlockY();
+ int z = loc.getBlockZ();
+ return x >= minX && x <= maxX && y >= minY && y <= maxY && z >= minZ && z <= maxZ;
+ }
+
+ private void broadcastSystemMessage(String message) {
+ if (message == null || message.isEmpty()) {
+ return;
+ }
+ for (Player online : plugin.getServer().getOnlinePlayers()) {
+ if (plugin.getMatchManager().isInMatch(online)
+ || plugin.getMatchManager().isLegacyDuelSpectator(online)
+ || plugin.getSpectateManager().isSpectating(online)
+ || (plugin.getConfig().getBoolean("features.parties.enabled", true)
+ && plugin.getPartyMatchManager().isInMatch(online))) {
+ continue;
+ }
+ online.sendMessage(message);
+ }
+ plugin.getServer().getConsoleSender().sendMessage(message);
+ }
+
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/ArenaManager.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/ArenaManager.java
new file mode 100644
index 0000000..1ccf777
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/ArenaManager.java
@@ -0,0 +1,121 @@
+package com.starpractice.manager;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.Arena;
+import com.starpractice.model.Gamemode;
+import com.starpractice.util.WorldEditAdapter;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ThreadLocalRandom;
+import org.bukkit.Location;
+
+public class ArenaManager {
+ private final StarPracticePlugin plugin;
+ private final WorldEditAdapter worldEdit;
+ private final Map arenas = new LinkedHashMap<>();
+
+ public ArenaManager(StarPracticePlugin plugin, WorldEditAdapter worldEdit) {
+ this.plugin = plugin;
+ this.worldEdit = worldEdit;
+ }
+
+ public void load(List list) {
+ arenas.clear();
+ for (Arena arena : list) {
+ arena.setInUse(false);
+ arenas.put(arena.getId(), arena);
+ }
+ }
+
+ public List getAll() {
+ return new ArrayList<>(arenas.values());
+ }
+
+ public Arena getById(String id) {
+ return arenas.get(id);
+ }
+
+ public void add(Arena arena) {
+ arenas.put(arena.getId(), arena);
+ }
+
+ public void remove(String id) {
+ arenas.remove(id);
+ }
+
+ public boolean exists(String id) {
+ return arenas.containsKey(id);
+ }
+
+ public String generateId(String base) {
+ String idBase = base.toLowerCase().replace(" ", "").replaceAll("[^a-z0-9_]", "");
+ if (idBase.isEmpty()) {
+ idBase = "arena";
+ }
+ String id = idBase;
+ int i = 1;
+ while (exists(id)) {
+ id = idBase + i;
+ i++;
+ }
+ return id;
+ }
+
+ public Arena findAvailableArena(Gamemode gamemode) {
+ return findAvailableArena(gamemode, false);
+ }
+
+ public Arena findAvailableArena(Gamemode gamemode, boolean requireCenter) {
+ List allowed = new ArrayList<>(gamemode.getAllowedArenas());
+ List candidates = new ArrayList<>();
+ for (Arena arena : arenas.values()) {
+ if (!arena.isEnabled() || arena.isInUse()) {
+ continue;
+ }
+ if (!allowed.isEmpty() && !allowed.contains(arena.getId())) {
+ continue;
+ }
+ if (!isArenaReady(arena)) {
+ continue;
+ }
+ if (requireCenter && arena.getCenterSpawn() == null) {
+ continue;
+ }
+ candidates.add(arena);
+ }
+ if (candidates.isEmpty()) {
+ return null;
+ }
+ return candidates.get(ThreadLocalRandom.current().nextInt(candidates.size()));
+ }
+
+ public boolean isArenaReady(Arena arena) {
+ Location spawn1 = arena.getSpawn1();
+ Location spawn2 = arena.getSpawn2();
+ if (spawn1 == null || spawn2 == null) {
+ return false;
+ }
+ if (arena.getCorner1() == null || arena.getCorner2() == null) {
+ return false;
+ }
+ if (!worldEdit.isAvailable()) {
+ return false;
+ }
+ return worldEdit.getSnapshotFile(arena).exists();
+ }
+
+ public boolean isFullyConfigured(Arena arena) {
+ if (arena.getSpawn1() == null || arena.getSpawn2() == null || arena.getSpectatorSpawn() == null) {
+ return false;
+ }
+ if (arena.getCorner1() == null || arena.getCorner2() == null) {
+ return false;
+ }
+ if (!worldEdit.isAvailable()) {
+ return false;
+ }
+ return worldEdit.getSnapshotFile(arena).exists();
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/DuelRequestManager.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/DuelRequestManager.java
new file mode 100644
index 0000000..3f653a2
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/DuelRequestManager.java
@@ -0,0 +1,211 @@
+package com.starpractice.manager;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.Arena;
+import com.starpractice.model.DuelRequest;
+import com.starpractice.model.Gamemode;
+import com.starpractice.util.Text;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import net.md_5.bungee.api.chat.ClickEvent;
+import net.md_5.bungee.api.chat.ComponentBuilder;
+import net.md_5.bungee.api.chat.HoverEvent;
+import net.md_5.bungee.api.chat.TextComponent;
+import org.bukkit.entity.Player;
+
+public class DuelRequestManager {
+ private final StarPracticePlugin plugin;
+ private final Map> pending = new HashMap<>();
+
+ public DuelRequestManager(StarPracticePlugin plugin) {
+ this.plugin = plugin;
+ }
+
+ public void sendRequest(Player requester, Player target, Gamemode gamemode, int totalRounds) {
+ if (!plugin.getSettingsManager().getSettings(target.getUniqueId()).isDuelRequests()) {
+ plugin.sendMessage(requester, plugin.getConfig().getString("messages.duel-request-disabled", "&cThat player has duel requests disabled."));
+ return;
+ }
+ if (plugin.getMatchManager().isInMatch(requester) || plugin.getSpectateManager().isSpectating(requester)) {
+ plugin.sendMessage(requester, "&cYou cannot duel right now.");
+ return;
+ }
+ if (plugin.getMatchManager().isInMatch(target) || plugin.getSpectateManager().isSpectating(target)) {
+ plugin.sendMessage(requester, plugin.getConfig().getString("messages.duel-request-busy", "&cThat player is busy."));
+ return;
+ }
+ DuelRequest request = new DuelRequest(requester.getUniqueId(), target.getUniqueId(), gamemode.getId(), totalRounds, System.currentTimeMillis());
+ pending.computeIfAbsent(target.getUniqueId(), key -> new HashMap<>()).put(requester.getUniqueId(), request);
+
+ String sentMsg = plugin.getConfig().getString("messages.duel-request-sent", "&aSent duel request to &f%player%&a.");
+ plugin.sendMessage(requester, sentMsg.replace("%player%", target.getName()));
+
+ sendRequestMessage(target, requester, gamemode, request.getRequiredWins());
+ try {
+ target.playSound(target.getLocation(), org.bukkit.Sound.BLOCK_NOTE_BLOCK_BELL, 1.0f, 1.0f);
+ } catch (IllegalArgumentException ignored) {
+ }
+
+ int timeoutSeconds = plugin.getConfig().getInt("duel.requestTimeoutSeconds", 30);
+ if (timeoutSeconds > 0) {
+ plugin.getScheduler().runLaterGlobal(timeoutSeconds * 20L, () -> expireRequest(requester.getUniqueId(), target.getUniqueId()));
+ }
+ }
+
+ public DuelRequest getRequest(Player target, Player requester) {
+ if (target == null || requester == null) {
+ return null;
+ }
+ Map map = pending.get(target.getUniqueId());
+ if (map == null) {
+ return null;
+ }
+ return map.get(requester.getUniqueId());
+ }
+
+ public List getPendingRequesterNames(Player target) {
+ Map map = pending.get(target.getUniqueId());
+ if (map == null) {
+ return new ArrayList<>();
+ }
+ List names = new ArrayList<>();
+ for (UUID uuid : map.keySet()) {
+ Player player = plugin.getServer().getPlayer(uuid);
+ if (player != null && player.isOnline()) {
+ names.add(player.getName());
+ }
+ }
+ return names;
+ }
+
+ public void accept(Player target, Player requester) {
+ DuelRequest request = getRequest(target, requester);
+ if (request == null) {
+ plugin.sendMessage(target, plugin.getConfig().getString("messages.duel-request-none", "&cNo pending duel request from that player."));
+ return;
+ }
+ removeRequest(requester.getUniqueId(), target.getUniqueId());
+ if (requester == null || !requester.isOnline()) {
+ plugin.sendMessage(target, plugin.getConfig().getString("messages.duel-request-offline", "&cThat player is offline."));
+ return;
+ }
+ if (plugin.getMatchManager().isInMatch(target) || plugin.getSpectateManager().isSpectating(target)
+ || plugin.getMatchManager().isInMatch(requester) || plugin.getSpectateManager().isSpectating(requester)) {
+ plugin.sendMessage(target, plugin.getConfig().getString("messages.duel-request-busy", "&cThat player is busy."));
+ return;
+ }
+
+ Gamemode gamemode = plugin.getGamemodeManager().getById(request.getGamemodeId());
+ if (gamemode == null || !gamemode.isEnabled()) {
+ plugin.sendMessage(target, plugin.getConfig().getString("messages.duel-request-mode-disabled", "&cThat gamemode is unavailable."));
+ return;
+ }
+ Arena arena = plugin.getArenaManager().findAvailableArena(gamemode);
+ if (arena == null) {
+ plugin.sendMessage(target, plugin.getConfig().getString("messages.no-arenas"));
+ return;
+ }
+
+ String acceptMsg = plugin.getConfig().getString("messages.duel-request-accepted", "&aYou accepted the duel request from &f%player%&a.");
+ plugin.sendMessage(target, acceptMsg.replace("%player%", requester.getName()));
+ plugin.sendMessage(requester, acceptMsg.replace("%player%", target.getName()));
+
+ plugin.getMatchManager().startSeries(gamemode, arena, requester, target, request.getTotalRounds(), false);
+ }
+
+ public void deny(Player target, Player requester) {
+ DuelRequest request = getRequest(target, requester);
+ if (request == null) {
+ plugin.sendMessage(target, plugin.getConfig().getString("messages.duel-request-none", "&cNo pending duel request from that player."));
+ return;
+ }
+ removeRequest(requester.getUniqueId(), target.getUniqueId());
+ String denyMsg = plugin.getConfig().getString("messages.duel-request-denied", "&eYou denied the duel request from &f%player%&e.");
+ plugin.sendMessage(target, denyMsg.replace("%player%", requester != null ? requester.getName() : "player"));
+ if (requester != null && requester.isOnline()) {
+ plugin.sendMessage(requester, denyMsg.replace("%player%", target.getName()));
+ }
+ }
+
+ public void removeAllFor(Player player) {
+ UUID uuid = player.getUniqueId();
+ Map incoming = pending.remove(uuid);
+ if (incoming != null) {
+ for (UUID requester : incoming.keySet()) {
+ Player requesterPlayer = plugin.getServer().getPlayer(requester);
+ if (requesterPlayer != null && requesterPlayer.isOnline()) {
+ String msg = plugin.getConfig().getString("messages.duel-request-cancelled", "&eYour duel request to &f%player%&e was cancelled.");
+ plugin.sendMessage(requesterPlayer, msg.replace("%player%", player.getName()));
+ }
+ }
+ }
+ for (UUID target : new ArrayList<>(pending.keySet())) {
+ Map map = pending.get(target);
+ if (map == null) {
+ continue;
+ }
+ map.remove(uuid);
+ if (map.isEmpty()) {
+ pending.remove(target);
+ }
+ }
+ }
+
+ private void removeRequest(UUID requester, UUID target) {
+ Map map = pending.get(target);
+ if (map == null) {
+ return;
+ }
+ map.remove(requester);
+ if (map.isEmpty()) {
+ pending.remove(target);
+ }
+ }
+
+ private void expireRequest(UUID requester, UUID target) {
+ Map map = pending.get(target);
+ if (map == null) {
+ return;
+ }
+ DuelRequest request = map.remove(requester);
+ if (map.isEmpty()) {
+ pending.remove(target);
+ }
+ if (request == null) {
+ return;
+ }
+ Player requesterPlayer = plugin.getServer().getPlayer(requester);
+ Player targetPlayer = plugin.getServer().getPlayer(target);
+ String msg = plugin.getConfig().getString("messages.duel-request-expired", "&eYour duel request to &f%player%&e expired.");
+ if (requesterPlayer != null && requesterPlayer.isOnline() && targetPlayer != null) {
+ plugin.sendMessage(requesterPlayer, msg.replace("%player%", targetPlayer.getName()));
+ }
+ }
+
+ private void sendRequestMessage(Player target, Player requester, Gamemode gamemode, int requiredWins) {
+ String prefix = plugin.getConfig().getString("messages.prefix", "&eStarPractice &7");
+ String base = plugin.getConfig().getString(
+ "messages.duel-request-received",
+ "&a%player% has challenged you in &f%mode%&a (first to %wins%)."
+ );
+ base = base.replace("%player%", requester.getName())
+ .replace("%mode%", gamemode.getDisplayName())
+ .replace("%wins%", String.valueOf(requiredWins));
+
+ TextComponent message = new TextComponent(TextComponent.fromLegacyText(Text.color(prefix + base + " ")));
+ TextComponent accept = new TextComponent(Text.color("&a[&a✔&a &aA&aC&aC&aE&aP&aT&a]"));
+ accept.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/duel accept " + requester.getName()));
+ accept.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(Text.color("&aClick to accept")).create()));
+ TextComponent deny = new TextComponent(Text.color("&c[&c✖&c &cD&cE&cN&cY&c]"));
+ deny.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/duel deny " + requester.getName()));
+ deny.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(Text.color("&cClick to deny")).create()));
+ message.addExtra(accept);
+ message.addExtra(new TextComponent(" "));
+ message.addExtra(deny);
+ target.spigot().sendMessage(message);
+ }
+}
+
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/FriendManager.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/FriendManager.java
new file mode 100644
index 0000000..4b86815
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/FriendManager.java
@@ -0,0 +1,185 @@
+package com.starpractice.manager;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.FriendRequest;
+import com.starpractice.util.Text;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import net.md_5.bungee.api.chat.ClickEvent;
+import net.md_5.bungee.api.chat.ComponentBuilder;
+import net.md_5.bungee.api.chat.HoverEvent;
+import net.md_5.bungee.api.chat.TextComponent;
+import org.bukkit.entity.Player;
+
+public class FriendManager {
+ private final StarPracticePlugin plugin;
+ private final Map> friends = new HashMap<>();
+ private final Map> pending = new HashMap<>();
+
+ public FriendManager(StarPracticePlugin plugin) {
+ this.plugin = plugin;
+ }
+
+ public void load(Map> data) {
+ friends.clear();
+ pending.clear();
+ if (data != null) {
+ friends.putAll(data);
+ }
+ }
+
+ public void clearAll() {
+ friends.clear();
+ pending.clear();
+ }
+
+ public Map> exportData() {
+ return new HashMap<>(friends);
+ }
+
+ public boolean areFriends(UUID a, UUID b) {
+ return friends.getOrDefault(a, new HashSet<>()).contains(b);
+ }
+
+ public void addFriend(UUID a, UUID b) {
+ friends.computeIfAbsent(a, key -> new HashSet<>()).add(b);
+ friends.computeIfAbsent(b, key -> new HashSet<>()).add(a);
+ persist();
+ }
+
+ public void removeFriend(UUID a, UUID b) {
+ friends.getOrDefault(a, new HashSet<>()).remove(b);
+ friends.getOrDefault(b, new HashSet<>()).remove(a);
+ persist();
+ }
+
+ public List getFriendNames(Player player) {
+ List names = new ArrayList<>();
+ for (UUID uuid : friends.getOrDefault(player.getUniqueId(), new HashSet<>())) {
+ Player online = plugin.getServer().getPlayer(uuid);
+ if (online != null && online.isOnline()) {
+ names.add(online.getName());
+ }
+ }
+ return names;
+ }
+
+ public void sendRequest(Player requester, Player target) {
+ if (!plugin.getConfig().getBoolean("features.friends.enabled", true)) {
+ plugin.sendMessage(requester, plugin.getConfig().getString("messages.friend-feature-disabled", "&cFriends are disabled on this server."));
+ return;
+ }
+ if (!plugin.getSettingsManager().getSettings(target.getUniqueId()).isFriendRequests()) {
+ plugin.sendMessage(requester, plugin.getConfig().getString("messages.friend-requests-disabled", "&cThat player has friend requests disabled."));
+ return;
+ }
+ if (areFriends(requester.getUniqueId(), target.getUniqueId())) {
+ plugin.sendMessage(requester, plugin.getConfig().getString("messages.friend-already", "&eYou are already friends with &f%player%&e.").replace("%player%", target.getName()));
+ return;
+ }
+ if (hasPending(target.getUniqueId(), requester.getUniqueId())) {
+ plugin.sendMessage(requester, plugin.getConfig().getString("messages.friend-pending", "&eThat player already has a pending request from you."));
+ return;
+ }
+ pending.computeIfAbsent(target.getUniqueId(), key -> new HashMap<>())
+ .put(requester.getUniqueId(), new FriendRequest(requester.getUniqueId(), target.getUniqueId(), System.currentTimeMillis()));
+
+ plugin.sendMessage(requester, plugin.getConfig().getString("messages.friend-request-sent", "&aFriend request sent to &f%player%&a.").replace("%player%", target.getName()));
+ sendRequestMessage(target, requester);
+ try {
+ target.playSound(target.getLocation(), org.bukkit.Sound.BLOCK_NOTE_BLOCK_GUITAR, 1.0f, 1.0f);
+ } catch (IllegalArgumentException ignored) {
+ }
+ }
+
+ public void accept(Player target, Player requester) {
+ if (!hasPending(target.getUniqueId(), requester.getUniqueId())) {
+ plugin.sendMessage(target, plugin.getConfig().getString("messages.friend-request-none", "&cNo pending friend request from that player."));
+ return;
+ }
+ removePending(target.getUniqueId(), requester.getUniqueId());
+ addFriend(target.getUniqueId(), requester.getUniqueId());
+ String msg = plugin.getConfig().getString("messages.friend-request-accepted", "&aYou are now friends with &f%player%&a.");
+ plugin.sendMessage(target, msg.replace("%player%", requester.getName()));
+ if (requester.isOnline()) {
+ plugin.sendMessage(requester, msg.replace("%player%", target.getName()));
+ }
+ }
+
+ public void deny(Player target, Player requester) {
+ if (!hasPending(target.getUniqueId(), requester.getUniqueId())) {
+ plugin.sendMessage(target, plugin.getConfig().getString("messages.friend-request-none", "&cNo pending friend request from that player."));
+ return;
+ }
+ removePending(target.getUniqueId(), requester.getUniqueId());
+ String msg = plugin.getConfig().getString("messages.friend-request-denied", "&eYou denied the friend request from &f%player%&e.");
+ plugin.sendMessage(target, msg.replace("%player%", requester.getName()));
+ if (requester.isOnline()) {
+ plugin.sendMessage(requester, msg.replace("%player%", target.getName()));
+ }
+ }
+
+ public void remove(Player player, Player target) {
+ if (!areFriends(player.getUniqueId(), target.getUniqueId())) {
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.friend-not-found", "&cThat player is not your friend."));
+ return;
+ }
+ removeFriend(player.getUniqueId(), target.getUniqueId());
+ String msg = plugin.getConfig().getString("messages.friend-removed", "&eYou removed &f%player%&e from your friends.");
+ plugin.sendMessage(player, msg.replace("%player%", target.getName()));
+ if (target.isOnline()) {
+ plugin.sendMessage(target, msg.replace("%player%", player.getName()));
+ }
+ }
+
+ public void removeAllRequestsFor(Player player) {
+ pending.remove(player.getUniqueId());
+ for (Map map : new ArrayList<>(pending.values())) {
+ map.remove(player.getUniqueId());
+ }
+ }
+
+ private void persist() {
+ plugin.getStorageManager().saveFriends(exportData());
+ }
+
+ private boolean hasPending(UUID target, UUID requester) {
+ Map map = pending.get(target);
+ return map != null && map.containsKey(requester);
+ }
+
+ private void removePending(UUID target, UUID requester) {
+ Map map = pending.get(target);
+ if (map == null) {
+ return;
+ }
+ map.remove(requester);
+ if (map.isEmpty()) {
+ pending.remove(target);
+ }
+ }
+
+ private void sendRequestMessage(Player target, Player requester) {
+ String prefix = plugin.getConfig().getString("messages.prefix", "&eStarPractice &7");
+ String base = plugin.getConfig().getString("messages.friend-request-received", "&a%player% sent you a friend request.");
+ base = base.replace("%player%", requester.getName());
+
+ TextComponent message = new TextComponent(TextComponent.fromLegacyText(Text.color(prefix + base + " ")));
+ TextComponent accept = new TextComponent(Text.color("&a[&a✔&a &aA&aC&aC&aE&aP&aT&a]"));
+ accept.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/friend accept " + requester.getName()));
+ accept.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(Text.color("&aClick to accept")).create()));
+ TextComponent deny = new TextComponent(Text.color("&c[&c✖&c &cD&cE&cN&cY&c]"));
+ deny.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/friend deny " + requester.getName()));
+ deny.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(Text.color("&cClick to deny")).create()));
+ message.addExtra(accept);
+ message.addExtra(new TextComponent(" "));
+ message.addExtra(deny);
+ target.spigot().sendMessage(message);
+ }
+}
+
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/GamemodeManager.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/GamemodeManager.java
new file mode 100644
index 0000000..aab71f7
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/GamemodeManager.java
@@ -0,0 +1,68 @@
+package com.starpractice.manager;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.Gamemode;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+public class GamemodeManager {
+ private final StarPracticePlugin plugin;
+ private final Map gamemodes = new LinkedHashMap<>();
+
+ public GamemodeManager(StarPracticePlugin plugin) {
+ this.plugin = plugin;
+ }
+
+ public void load(List list) {
+ gamemodes.clear();
+ for (Gamemode mode : list) {
+ gamemodes.put(mode.getId(), mode);
+ }
+ }
+
+ public Gamemode getById(String id) {
+ return gamemodes.get(id);
+ }
+
+ public List getAll() {
+ return new ArrayList<>(gamemodes.values());
+ }
+
+ public List getEnabled() {
+ List list = new ArrayList<>();
+ for (Gamemode mode : gamemodes.values()) {
+ if (mode.isEnabled()) {
+ list.add(mode);
+ }
+ }
+ return list;
+ }
+
+ public void add(Gamemode gamemode) {
+ gamemodes.put(gamemode.getId(), gamemode);
+ }
+
+ public void remove(String id) {
+ gamemodes.remove(id);
+ }
+
+ public boolean exists(String id) {
+ return gamemodes.containsKey(id);
+ }
+
+ public String generateId(String base) {
+ String idBase = base.toLowerCase().replace(" ", "").replaceAll("[^a-z0-9_]", "");
+ if (idBase.isEmpty()) {
+ idBase = "mode";
+ }
+ String id = idBase;
+ int i = 1;
+ while (exists(id)) {
+ id = idBase + i;
+ i++;
+ }
+ return id;
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/HotbarManager.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/HotbarManager.java
new file mode 100644
index 0000000..1f11e7c
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/HotbarManager.java
@@ -0,0 +1,123 @@
+package com.starpractice.manager;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.InventorySnapshot;
+import com.starpractice.model.SpawnData;
+import com.starpractice.util.ItemBuilder;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import org.bukkit.Material;
+import org.bukkit.NamespacedKey;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.bukkit.persistence.PersistentDataType;
+
+public class HotbarManager {
+ private final StarPracticePlugin plugin;
+ private final Map stored = new HashMap<>();
+ private SpawnData spawnData = new SpawnData(null);
+ private final NamespacedKey hotbarKey;
+
+ public HotbarManager(StarPracticePlugin plugin) {
+ this.plugin = plugin;
+ this.hotbarKey = new NamespacedKey(plugin, "hotbar-item");
+ }
+
+ public void setSpawnData(SpawnData spawnData) {
+ this.spawnData = spawnData == null ? new SpawnData(null) : spawnData;
+ }
+
+ public SpawnData getSpawnData() {
+ return spawnData;
+ }
+
+ public void applyIfEligible(Player player, boolean force) {
+ if (!plugin.getConfig().getBoolean("spawnHotbar.enabled", false)) {
+ return;
+ }
+ if (plugin.getMatchManager().isInMatch(player) || plugin.getSpectateManager().isSpectating(player)) {
+ return;
+ }
+ if (spawnData.getLocation() == null || spawnData.getLocation().getWorld() == null) {
+ return;
+ }
+ if (!player.getWorld().getName().equalsIgnoreCase(spawnData.getLocation().getWorld().getName())) {
+ return;
+ }
+ if (!stored.containsKey(player.getUniqueId())) {
+ stored.put(player.getUniqueId(), InventorySnapshot.fromPlayer(player));
+ }
+ if (!force && !plugin.getConfig().getBoolean("spawnHotbar.enforceAlways", false)) {
+ return;
+ }
+ setHotbar(player);
+ }
+
+ public void handleWorldUpdate(Player player) {
+ if (spawnData.getLocation() == null || spawnData.getLocation().getWorld() == null) {
+ return;
+ }
+ if (player.getWorld().getName().equalsIgnoreCase(spawnData.getLocation().getWorld().getName())) {
+ applyIfEligible(player, true);
+ } else {
+ restoreIfStored(player);
+ }
+ }
+
+ public void restoreIfStored(Player player) {
+ InventorySnapshot snapshot = stored.remove(player.getUniqueId());
+ if (snapshot != null) {
+ snapshot.apply(player);
+ }
+ }
+
+ public void sendToSpawn(Player player) {
+ if (spawnData.getLocation() == null) {
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.spawn-not-set"));
+ return;
+ }
+ plugin.getScheduler().runAtEntity(player, () -> {
+ player.setGameMode(org.bukkit.GameMode.SURVIVAL);
+ player.getInventory().clear();
+ player.getInventory().setArmorContents(null);
+ player.getInventory().setItemInOffHand(null);
+ player.setHealth(player.getMaxHealth());
+ player.setFoodLevel(20);
+ player.setSaturation(20.0f);
+ player.updateInventory();
+ player.teleport(spawnData.getLocation());
+ applyIfEligible(player, true);
+ });
+ }
+
+ public boolean isHotbarItem(ItemStack item) {
+ if (item == null) {
+ return false;
+ }
+ ItemMeta meta = item.getItemMeta();
+ if (meta == null) {
+ return false;
+ }
+ return meta.getPersistentDataContainer().has(hotbarKey, PersistentDataType.BYTE);
+ }
+
+ private void setHotbar(Player player) {
+ Material material = Material.matchMaterial(plugin.getConfig().getString("spawnHotbar.item.material", "IRON_SWORD"));
+ if (material == null) {
+ material = Material.IRON_SWORD;
+ }
+ String name = plugin.getConfig().getString("spawnHotbar.item.name", "&aQueue");
+ int slot = plugin.getConfig().getInt("spawnHotbar.item.slot", 0);
+ ItemStack item = new ItemBuilder(material).name(name).build();
+ ItemMeta meta = item.getItemMeta();
+ if (meta != null) {
+ meta.getPersistentDataContainer().set(hotbarKey, PersistentDataType.BYTE, (byte) 1);
+ item.setItemMeta(meta);
+ }
+ player.getInventory().clear();
+ player.getInventory().setItem(slot, item);
+ player.updateInventory();
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/KitEditorSessionManager.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/KitEditorSessionManager.java
new file mode 100644
index 0000000..5ab4379
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/KitEditorSessionManager.java
@@ -0,0 +1,67 @@
+package com.starpractice.manager;
+
+import com.starpractice.model.InventorySnapshot;
+import com.starpractice.util.ItemBuilder;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.InventoryHolder;
+import org.bukkit.inventory.ItemStack;
+
+public class KitEditorSessionManager {
+ private final Map snapshots = new HashMap<>();
+ private final Set active = new HashSet<>();
+ private final ItemStack maskPane;
+ private final ItemStack[] maskedContents;
+ private final ItemStack[] maskedArmor;
+
+ public KitEditorSessionManager() {
+ this.maskPane = new ItemBuilder(Material.RED_STAINED_GLASS_PANE)
+ .name("&cCurrently Editing a Kit")
+ .build();
+ this.maskedContents = new ItemStack[36];
+ this.maskedArmor = new ItemStack[4];
+ for (int i = 0; i < maskedContents.length; i++) {
+ maskedContents[i] = maskPane;
+ }
+ for (int i = 0; i < maskedArmor.length; i++) {
+ maskedArmor[i] = maskPane;
+ }
+ }
+
+ public void enter(Player player) {
+ if (player == null || active.contains(player.getUniqueId())) {
+ return;
+ }
+ snapshots.put(player.getUniqueId(), InventorySnapshot.fromPlayer(player));
+ active.add(player.getUniqueId());
+ player.getInventory().setContents(maskedContents.clone());
+ player.getInventory().setArmorContents(maskedArmor.clone());
+ player.getInventory().setItemInOffHand(maskPane);
+ }
+
+ public void exit(Player player) {
+ if (player == null) {
+ return;
+ }
+ InventorySnapshot snapshot = snapshots.remove(player.getUniqueId());
+ active.remove(player.getUniqueId());
+ if (snapshot != null) {
+ snapshot.apply(player);
+ }
+ }
+
+ public boolean isInSession(Player player) {
+ return player != null && active.contains(player.getUniqueId());
+ }
+
+ public static boolean isKitEditorHolder(InventoryHolder holder) {
+ return holder instanceof com.starpractice.gui.KitEditorGamemodeGui
+ || holder instanceof com.starpractice.gui.KitEditorLoadoutGui
+ || holder instanceof com.starpractice.gui.KitLayoutGui;
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/MatchManager.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/MatchManager.java
new file mode 100644
index 0000000..585cdb9
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/MatchManager.java
@@ -0,0 +1,942 @@
+package com.starpractice.manager;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.Arena;
+import com.starpractice.model.DuelMatch;
+import com.starpractice.model.Gamemode;
+import com.starpractice.model.PrepotData;
+import com.starpractice.util.TablistUtil;
+import com.starpractice.util.Text;
+import com.starpractice.util.WorldEditAdapter;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import org.bukkit.GameMode;
+import org.bukkit.Location;
+import org.bukkit.NamespacedKey;
+import org.bukkit.Sound;
+import org.bukkit.entity.Item;
+import org.bukkit.entity.Player;
+import org.bukkit.potion.PotionEffect;
+import org.bukkit.potion.PotionEffectType;
+
+public class MatchManager {
+ private final StarPracticePlugin plugin;
+ private final WorldEditAdapter worldEdit;
+ private final Map matches = new HashMap<>();
+ private final Set frozen = new HashSet<>();
+ private final Set pendingReturn = new HashSet<>();
+ private final Map> placedBlocks = new HashMap<>();
+ private final Map pendingSpectator = new HashMap<>();
+ private final Set legacyDuelSpectators = new HashSet<>();
+ private final Set healthDisplays = new HashSet<>();
+ private final Set activeHealthLoops = new HashSet<>();
+
+ public MatchManager(StarPracticePlugin plugin, WorldEditAdapter worldEdit) {
+ this.plugin = plugin;
+ this.worldEdit = worldEdit;
+ }
+
+ public boolean isInMatch(Player player) {
+ return matches.containsKey(player.getUniqueId());
+ }
+
+ public DuelMatch getMatch(Player player) {
+ return matches.get(player.getUniqueId());
+ }
+
+ public DuelMatch getMatchByArena(String arenaId) {
+ if (arenaId == null) {
+ return null;
+ }
+ for (DuelMatch match : new HashSet<>(matches.values())) {
+ if (arenaId.equals(match.getArenaId())) {
+ return match;
+ }
+ }
+ return null;
+ }
+
+ public boolean isFrozen(Player player) {
+ return frozen.contains(player.getUniqueId());
+ }
+
+ public boolean isLegacyDuelSpectator(Player player) {
+ return legacyDuelSpectators.contains(player.getUniqueId());
+ }
+
+ public void startSeries(Gamemode gamemode, Arena arena, Player p1, Player p2, int rounds) {
+ startSeries(gamemode, arena, p1, p2, rounds, false);
+ }
+
+ public void startSeries(Gamemode gamemode, Arena arena, Player p1, Player p2, int rounds, boolean fromQueue) {
+ plugin.getQueueManager().removePlayer(p1.getUniqueId());
+ plugin.getQueueManager().removePlayer(p2.getUniqueId());
+ arena.setInUse(true);
+ DuelMatch match = new DuelMatch(p1.getUniqueId(), p2.getUniqueId(), arena.getId(), gamemode.getId(), Math.max(1, rounds));
+ matches.put(p1.getUniqueId(), match);
+ matches.put(p2.getUniqueId(), match);
+ placedBlocks.remove(arena.getId());
+ pendingReturn.remove(p1.getUniqueId());
+ pendingReturn.remove(p2.getUniqueId());
+
+ applyDuelVisibility(match);
+
+ String title = fromQueue ? "&6Match Found" : "&6Duel Accepted!";
+ runStartAnimation(p1, title);
+ runStartAnimation(p2, title);
+
+ plugin.getScheduler().runLaterAtEntity(p1, 40L, () -> {
+ if (!isInMatch(p1)) {
+ return;
+ }
+ plugin.getHotbarManager().restoreIfStored(p1);
+ preparePlayer(p1, arena.getSpawn1(), gamemode);
+ applyPostTeleportBlindness(p1);
+ frozen.add(p1.getUniqueId());
+ legacyDuelSpectators.remove(p1.getUniqueId());
+ });
+ plugin.getScheduler().runLaterAtEntity(p2, 40L, () -> {
+ if (!isInMatch(p2)) {
+ return;
+ }
+ plugin.getHotbarManager().restoreIfStored(p2);
+ preparePlayer(p2, arena.getSpawn2(), gamemode);
+ applyPostTeleportBlindness(p2);
+ frozen.add(p2.getUniqueId());
+ legacyDuelSpectators.remove(p2.getUniqueId());
+ });
+ plugin.getScheduler().runLaterAtEntity(p1, 40L, () -> startCountdown(match, gamemode, p1, p2));
+ plugin.getScheduler().runLaterAtEntity(p1, 45L, () -> applyDuelVisibility(match));
+ }
+
+ public void recordPlacedBlock(String arenaId, Location location) {
+ if (arenaId == null || location == null || location.getWorld() == null) {
+ return;
+ }
+ placedBlocks.computeIfAbsent(arenaId, key -> new HashSet<>()).add(blockKey(location));
+ }
+
+ public boolean isPlacedBlock(String arenaId, Location location) {
+ if (arenaId == null || location == null || location.getWorld() == null) {
+ return false;
+ }
+ Set set = placedBlocks.get(arenaId);
+ if (set == null) {
+ return false;
+ }
+ return set.contains(blockKey(location));
+ }
+
+ public void clearPlacedBlocks(String arenaId) {
+ if (arenaId != null) {
+ placedBlocks.remove(arenaId);
+ }
+ }
+
+ private void preparePlayer(Player player, Location spawn, Gamemode gamemode) {
+ if (spawn != null) {
+ player.teleport(spawn);
+ }
+ player.getActivePotionEffects().forEach(effect -> player.removePotionEffect(effect.getType()));
+ player.setFireTicks(0);
+ player.setHealth(player.getMaxHealth());
+ player.setFoodLevel(20);
+ player.setSaturation(gamemode.isFullSaturation() ? 20.0f : 0.0f);
+ player.setGameMode(GameMode.SURVIVAL);
+ com.starpractice.model.Kit kit = plugin.getPlayerKitManager().resolveKit(player, gamemode);
+ if (kit != null) {
+ kit.apply(player);
+ }
+ }
+
+ private void startCountdown(DuelMatch match, Gamemode gamemode, Player p1, Player p2) {
+ int seconds = plugin.getConfig().getInt("countdown.seconds", 5);
+ Sound sound;
+ try {
+ sound = Sound.valueOf(plugin.getConfig().getString("countdown.sound", "UI_BUTTON_CLICK"));
+ } catch (IllegalArgumentException e) {
+ sound = Sound.UI_BUTTON_CLICK;
+ }
+ float volume = (float) plugin.getConfig().getDouble("countdown.volume", 1.0);
+ float pitch = (float) plugin.getConfig().getDouble("countdown.pitch", 1.0);
+ final Sound finalSound = sound;
+ final float finalVolume = volume;
+ final float finalPitch = pitch;
+
+ for (int i = seconds; i >= 1; i--) {
+ int delay = (seconds - i) * 20;
+ int count = i;
+ plugin.getScheduler().runLaterAtEntity(p1, delay, () -> {
+ if (!isInMatch(p1)) {
+ return;
+ }
+ p1.sendTitle(Text.color("&e" + count), "", 0, 20, 0);
+ p1.playSound(p1.getLocation(), finalSound, finalVolume, finalPitch);
+ });
+ plugin.getScheduler().runLaterAtEntity(p2, delay, () -> {
+ if (!isInMatch(p2)) {
+ return;
+ }
+ p2.sendTitle(Text.color("&e" + count), "", 0, 20, 0);
+ p2.playSound(p2.getLocation(), finalSound, finalVolume, finalPitch);
+ });
+ }
+
+ plugin.getScheduler().runLaterAtEntity(p1, seconds * 20L, () -> startFight(match, gamemode, p1, p2));
+ }
+
+ private void startFight(DuelMatch match, Gamemode gamemode, Player p1, Player p2) {
+ if (match.getState() != DuelMatch.State.COUNTDOWN) {
+ return;
+ }
+ frozen.remove(p1.getUniqueId());
+ frozen.remove(p2.getUniqueId());
+ match.setState(DuelMatch.State.ACTIVE);
+ String startMsg = plugin.getConfig().getString("messages.duel-start", "&aFight!");
+ p1.sendTitle(Text.color(startMsg), "", 0, 40, 10);
+ p2.sendTitle(Text.color(startMsg), "", 0, 40, 10);
+ p1.playSound(p1.getLocation(), Sound.ENTITY_ENDER_DRAGON_GROWL, 1.0f, 1.0f);
+ p2.playSound(p2.getLocation(), Sound.ENTITY_ENDER_DRAGON_GROWL, 1.0f, 1.0f);
+ playPrepotEffects(p1, gamemode);
+ playPrepotEffects(p2, gamemode);
+ if (gamemode.isHealthDisplay()) {
+ healthDisplays.add(match.getArenaId());
+ scheduleHealthUpdate(match.getArenaId());
+ }
+ }
+
+ private boolean applyPrepots(Player player, Gamemode gamemode) {
+ if (!gamemode.isPrepotEnabled()) {
+ return false;
+ }
+ boolean applied = false;
+ for (Map.Entry entry : gamemode.getPrepotEffects().entrySet()) {
+ PrepotData data = entry.getValue();
+ if (!data.isEnabled() || data.getDurationSeconds() <= 0) {
+ continue;
+ }
+ PotionEffectType type = PotionEffectType.getByKey(NamespacedKey.minecraft(entry.getKey()));
+ if (type == null) {
+ continue;
+ }
+ player.addPotionEffect(new PotionEffect(type, data.getDurationSeconds() * 20, data.getAmplifier(), true, true, true));
+ applied = true;
+ }
+ return applied;
+ }
+
+ private void playPrepotEffects(Player player, Gamemode gamemode) {
+ boolean applied = applyPrepots(player, gamemode);
+ if (applied) {
+ player.playSound(player.getLocation(), Sound.ENTITY_SPLASH_POTION_BREAK, 1.0f, 1.0f);
+ }
+ }
+
+ public void handleDeath(Player dead) {
+ DuelMatch match = matches.get(dead.getUniqueId());
+ if (match == null) {
+ return;
+ }
+ Location deathLoc = dead.getLocation();
+ Player winner = plugin.getServer().getPlayer(match.getPlayer1().equals(dead.getUniqueId()) ? match.getPlayer2() : match.getPlayer1());
+ if (winner == null) {
+ endMatchWithoutWinner(match, dead, deathLoc);
+ return;
+ }
+ handleRoundEnd(winner, dead, false, deathLoc);
+ }
+
+ public void forfeit(Player player) {
+ DuelMatch match = matches.get(player.getUniqueId());
+ if (match == null) {
+ return;
+ }
+ Player winner = plugin.getServer().getPlayer(match.getPlayer1().equals(player.getUniqueId()) ? match.getPlayer2() : match.getPlayer1());
+ if (winner == null) {
+ endMatchWithoutWinner(match, player, null);
+ return;
+ }
+ handleForfeitMatch(winner, player);
+ }
+
+ private void handleForfeitMatch(Player winner, Player loser) {
+ DuelMatch match = matches.get(winner.getUniqueId());
+ if (match == null || match.getState() == DuelMatch.State.ENDING) {
+ return;
+ }
+ match.setState(DuelMatch.State.ENDING);
+ if (match.isRed(winner.getUniqueId())) {
+ match.incrementRedScore();
+ } else {
+ match.incrementBlueScore();
+ }
+ String winTitle = plugin.getConfig().getString("messages.duel-win-title");
+ String loseTitle = plugin.getConfig().getString("messages.duel-lose-title");
+ String scoreLine = "&c" + match.getRedScore() + " &7- &9" + match.getBlueScore();
+ winner.sendTitle(Text.color(winTitle), Text.color(scoreLine), 10, 60, 10);
+ loser.sendTitle(Text.color(loseTitle), Text.color(scoreLine), 10, 60, 10);
+ playEndSounds(winner, loser);
+ plugin.sendMessage(loser, plugin.getConfig().getString("messages.duel-forfeit"));
+ Arena arena = plugin.getArenaManager().getById(match.getArenaId());
+ pendingSpectator.put(loser.getUniqueId(), arena != null ? arena.getSpectatorSpawn() : null);
+ playDefeatEffects(loser, arena, null);
+ plugin.getScheduler().runLaterAtEntity(winner, 100L, () -> finishMatch(winner, loser, arena, match));
+ }
+
+ public void forfeitOnQuit(Player quitter) {
+ DuelMatch match = matches.get(quitter.getUniqueId());
+ if (match == null || match.getState() == DuelMatch.State.ENDING) {
+ return;
+ }
+ UUID winnerId = match.getPlayer1().equals(quitter.getUniqueId()) ? match.getPlayer2() : match.getPlayer1();
+ Player winner = plugin.getServer().getPlayer(winnerId);
+ Arena arena = plugin.getArenaManager().getById(match.getArenaId());
+ match.setState(DuelMatch.State.ENDING);
+
+ if (match.isRed(winnerId)) {
+ match.incrementRedScore();
+ } else {
+ match.incrementBlueScore();
+ }
+
+ matches.remove(quitter.getUniqueId());
+ matches.remove(winnerId);
+ frozen.remove(quitter.getUniqueId());
+ frozen.remove(winnerId);
+ pendingSpectator.remove(quitter.getUniqueId());
+ pendingSpectator.remove(winnerId);
+ activeHealthLoops.remove(match.getArenaId());
+ restoreVisibility(match);
+
+ if (winner != null) {
+ String winTitle = plugin.getConfig().getString("messages.duel-win-title");
+ String scoreLine = "&c" + match.getRedScore() + " &7- &9" + match.getBlueScore();
+ winner.sendTitle(Text.color(winTitle), Text.color(scoreLine), 10, 60, 10);
+ playVictorySound(winner);
+ plugin.getScheduler().runLaterAtEntity(winner, 100L, () -> finishMatchWinnerOnly(winner, arena, match));
+ } else {
+ finishMatchWinnerOnly(null, arena, match);
+ }
+ }
+
+ public void markPendingReturn(UUID uuid) {
+ pendingReturn.add(uuid);
+ }
+
+ public boolean consumePendingReturn(Player player) {
+ return pendingReturn.remove(player.getUniqueId());
+ }
+
+ public Location consumePendingSpectator(Player player) {
+ return pendingSpectator.remove(player.getUniqueId());
+ }
+
+ public void clearRuntimeState(UUID playerId) {
+ if (playerId == null) {
+ return;
+ }
+ matches.remove(playerId);
+ frozen.remove(playerId);
+ pendingReturn.remove(playerId);
+ pendingSpectator.remove(playerId);
+ legacyDuelSpectators.remove(playerId);
+ }
+
+ private void handleRoundEnd(Player winner, Player loser, boolean forfeit, Location deathLoc) {
+ DuelMatch match = matches.get(winner.getUniqueId());
+ if (match == null || match.getState() == DuelMatch.State.ENDING) {
+ return;
+ }
+
+ if (match.isRed(winner.getUniqueId())) {
+ match.incrementRedScore();
+ } else {
+ match.incrementBlueScore();
+ }
+
+ String winTitle = plugin.getConfig().getString("messages.duel-win-title");
+ String loseTitle = plugin.getConfig().getString("messages.duel-lose-title");
+ String scoreLine = "&c" + match.getRedScore() + " &7- &9" + match.getBlueScore();
+
+ winner.sendTitle(Text.color(winTitle), Text.color(scoreLine), 10, 60, 10);
+ loser.sendTitle(Text.color(loseTitle), Text.color(scoreLine), 10, 60, 10);
+ playEndSounds(winner, loser);
+
+ if (forfeit) {
+ plugin.sendMessage(loser, plugin.getConfig().getString("messages.duel-forfeit"));
+ }
+
+ Arena arena = plugin.getArenaManager().getById(match.getArenaId());
+ pendingSpectator.put(loser.getUniqueId(), deathLoc != null ? deathLoc : (arena != null ? arena.getSpectatorSpawn() : null));
+ playDefeatEffects(loser, arena, deathLoc);
+
+ if (match.getRedScore() >= match.getRequiredWins() || match.getBlueScore() >= match.getRequiredWins()) {
+ match.setState(DuelMatch.State.ENDING);
+ plugin.getScheduler().runLaterAtEntity(winner, 100L, () -> finishMatch(winner, loser, arena, match));
+ return;
+ }
+
+ match.setState(DuelMatch.State.COUNTDOWN);
+ if (arena != null) {
+ scheduleRoundReset(arena, () -> startNextRound(match, arena));
+ return;
+ }
+ plugin.getScheduler().runLaterAtEntity(winner, 60L, () -> startNextRound(match, arena));
+ }
+
+ private void startNextRound(DuelMatch match, Arena arena) {
+ Player p1 = plugin.getServer().getPlayer(match.getPlayer1());
+ Player p2 = plugin.getServer().getPlayer(match.getPlayer2());
+ if (p1 == null || p2 == null) {
+ return;
+ }
+ Gamemode gamemode = plugin.getGamemodeManager().getById(match.getGamemodeId());
+ if (gamemode == null) {
+ return;
+ }
+ legacyDuelSpectators.remove(p1.getUniqueId());
+ legacyDuelSpectators.remove(p2.getUniqueId());
+ resetPlayerFromSpectator(p1);
+ resetPlayerFromSpectator(p2);
+ runStartAnimation(p1, "&6Next Match...");
+ runStartAnimation(p2, "&6Next Match...");
+ Runnable startRound = () -> {
+ if (!isInMatch(p1) || !isInMatch(p2)) {
+ return;
+ }
+ clearArenaEntities(arena);
+ frozen.add(p1.getUniqueId());
+ frozen.add(p2.getUniqueId());
+ legacyDuelSpectators.remove(p1.getUniqueId());
+ legacyDuelSpectators.remove(p2.getUniqueId());
+ preparePlayer(p1, arena.getSpawn1(), gamemode);
+ preparePlayer(p2, arena.getSpawn2(), gamemode);
+ applyPostTeleportBlindness(p1);
+ applyPostTeleportBlindness(p2);
+ startCountdown(match, gamemode, p1, p2);
+ applyDuelVisibility(match);
+ };
+ plugin.getScheduler().runLaterAtEntity(p1, 40L, () -> {
+ if (arena != null && worldEdit.isAvailable() && plugin.getConfig().getBoolean("arena.regenerateAfterDuel", true)) {
+ Location region = arena.getCorner1() != null ? arena.getCorner1() : arena.getSpawn1();
+ if (region != null) {
+ plugin.getScheduler().runAtLocation(region, () -> {
+ worldEdit.restoreSnapshot(arena);
+ startRound.run();
+ });
+ return;
+ }
+ }
+ startRound.run();
+ });
+ }
+
+ private void resetPlayerFromSpectator(Player player) {
+ plugin.getScheduler().runAtEntity(player, () -> {
+ player.setAllowFlight(false);
+ player.setFlying(false);
+ if (player.getGameMode() != GameMode.SURVIVAL) {
+ player.setGameMode(GameMode.SURVIVAL);
+ }
+ showToAll(player);
+ });
+ }
+
+ private void runStartAnimation(Player player, String title) {
+ plugin.getScheduler().runAtEntity(player, () -> {
+ player.sendTitle(Text.color(title), "", 0, 40, 10);
+ applyStartBlindness(player);
+ Sound sound;
+ try {
+ sound = Sound.valueOf(plugin.getConfig().getString("startAnimation.sound", "ENTITY_EVOKER_PREPARE_ATTACK"));
+ } catch (IllegalArgumentException e) {
+ sound = Sound.ENTITY_EVOKER_PREPARE_ATTACK;
+ }
+ float volume = (float) plugin.getConfig().getDouble("startAnimation.volume", 1.0);
+ float pitch = (float) plugin.getConfig().getDouble("startAnimation.pitch", 1.0);
+ player.playSound(player.getLocation(), sound, volume, pitch);
+ });
+ }
+
+ private void applyStartBlindness(Player player) {
+ player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 40, 1, true, false, false));
+ }
+
+ private void applyPostTeleportBlindness(Player player) {
+ player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 40, 1, true, false, false));
+ }
+
+ private void scheduleRoundReset(Arena arena, Runnable afterReset) {
+ clearPlacedBlocks(arena.getId());
+ clearArenaEntities(arena);
+ if (plugin.getConfig().getBoolean("arena.regenerateAfterDuel", true)
+ && worldEdit.isAvailable()
+ && arena != null) {
+ Location region = arena.getCorner1() != null ? arena.getCorner1() : arena.getSpawn1();
+ if (region != null) {
+ plugin.getScheduler().runAtLocation(region, () -> {
+ worldEdit.restoreSnapshot(arena);
+ plugin.getScheduler().runLaterGlobal(1L, afterReset);
+ });
+ return;
+ }
+ }
+ plugin.getScheduler().runLaterGlobal(1L, afterReset);
+ }
+
+ private void playEndSounds(Player winner, Player loser) {
+ Sound victory;
+ try {
+ victory = Sound.valueOf(plugin.getConfig().getString("duel.endVictorySound", "UI_TOAST_CHALLENGE_COMPLETE"));
+ } catch (IllegalArgumentException e) {
+ victory = Sound.UI_TOAST_CHALLENGE_COMPLETE;
+ }
+ Sound defeat;
+ try {
+ defeat = Sound.valueOf(plugin.getConfig().getString("duel.endDefeatSound", "ENTITY_WARDEN_DEATH"));
+ } catch (IllegalArgumentException e) {
+ defeat = Sound.ENTITY_WARDEN_DEATH;
+ }
+ float vVolume = (float) plugin.getConfig().getDouble("duel.endVictoryVolume", 1.0);
+ float vPitch = (float) plugin.getConfig().getDouble("duel.endVictoryPitch", 1.0);
+ float dVolume = (float) plugin.getConfig().getDouble("duel.endDefeatVolume", 1.0);
+ float dPitch = (float) plugin.getConfig().getDouble("duel.endDefeatPitch", 1.0);
+ winner.playSound(winner.getLocation(), victory, vVolume, vPitch);
+ loser.playSound(loser.getLocation(), defeat, dVolume, dPitch);
+ }
+
+ private void playVictorySound(Player winner) {
+ Sound victory;
+ try {
+ victory = Sound.valueOf(plugin.getConfig().getString("duel.endVictorySound", "UI_TOAST_CHALLENGE_COMPLETE"));
+ } catch (IllegalArgumentException e) {
+ victory = Sound.UI_TOAST_CHALLENGE_COMPLETE;
+ }
+ float vVolume = (float) plugin.getConfig().getDouble("duel.endVictoryVolume", 1.0);
+ float vPitch = (float) plugin.getConfig().getDouble("duel.endVictoryPitch", 1.0);
+ winner.playSound(winner.getLocation(), victory, vVolume, vPitch);
+ }
+
+ private void playDefeatEffects(Player loser, Arena arena, Location deathLoc) {
+ Sound sound;
+ try {
+ sound = Sound.valueOf(plugin.getConfig().getString("duel.defeatSound", "ENTITY_PLAYER_HURT"));
+ } catch (IllegalArgumentException e) {
+ sound = Sound.ENTITY_PLAYER_HURT;
+ }
+ float volume = (float) plugin.getConfig().getDouble("duel.defeatVolume", 1.0);
+ float pitch = (float) plugin.getConfig().getDouble("duel.defeatPitch", 1.0);
+ Location targetLoc = deathLoc != null ? deathLoc : (arena != null ? arena.getSpectatorSpawn() : null);
+ final Sound finalSound = sound;
+ final float finalVolume = volume;
+ final float finalPitch = pitch;
+ plugin.getScheduler().runLaterAtEntity(loser, 1L, () -> {
+ try {
+ loser.spigot().respawn();
+ } catch (Exception ignored) {
+ }
+ plugin.getScheduler().runLaterAtEntity(loser, 1L, () -> {
+ loser.setGameMode(GameMode.SPECTATOR);
+ if (targetLoc != null) {
+ loser.teleport(targetLoc);
+ }
+ loser.playSound(loser.getLocation(), finalSound, finalVolume, finalPitch);
+ DuelMatch match = matches.get(loser.getUniqueId());
+ if (match != null) {
+ Player p1 = plugin.getServer().getPlayer(match.getPlayer1());
+ Player p2 = plugin.getServer().getPlayer(match.getPlayer2());
+ java.util.List spec = new java.util.ArrayList<>();
+ if (loser.getGameMode() == GameMode.SPECTATOR) {
+ spec.add(loser);
+ }
+ if (p1 != null) {
+ TablistUtil.updateSpectators(p1, spec);
+ }
+ if (p2 != null) {
+ TablistUtil.updateSpectators(p2, spec);
+ }
+ }
+ if (loser.getGameMode() != GameMode.SPECTATOR) {
+ pendingSpectator.remove(loser.getUniqueId());
+ plugin.sendMessage(loser, "&cYou cannot spectate the match.");
+ plugin.getHotbarManager().sendToSpawn(loser);
+ }
+ });
+ });
+ }
+
+ private void finishMatch(Player winner, Player loser, Arena arena, DuelMatch match) {
+ matches.remove(winner.getUniqueId());
+ matches.remove(loser.getUniqueId());
+ frozen.remove(winner.getUniqueId());
+ frozen.remove(loser.getUniqueId());
+ legacyDuelSpectators.remove(winner.getUniqueId());
+ legacyDuelSpectators.remove(loser.getUniqueId());
+ healthDisplays.remove(match.getArenaId());
+ activeHealthLoops.remove(match.getArenaId());
+ pendingSpectator.remove(winner.getUniqueId());
+ pendingSpectator.remove(loser.getUniqueId());
+ showToAll(winner);
+ showToAll(loser);
+
+ restoreVisibility(match);
+
+ plugin.getHotbarManager().sendToSpawn(winner);
+ plugin.getHotbarManager().sendToSpawn(loser);
+ if (arena != null) {
+ plugin.getSpectateManager().endSpectatorsForArena(arena.getId());
+ }
+
+ if (!plugin.getConfig().getBoolean("arena.regenerateAfterDuel", true)) {
+ if (arena != null) {
+ clearPlacedBlocks(arena.getId());
+ clearArenaEntities(arena);
+ arena.setInUse(false);
+ }
+ return;
+ }
+
+ if (arena != null && worldEdit.isAvailable()) {
+ Location region = arena.getCorner1() != null ? arena.getCorner1() : arena.getSpawn1();
+ if (region != null) {
+ plugin.getScheduler().runAtLocation(region, () -> {
+ boolean restored = worldEdit.restoreSnapshot(arena);
+ if (!restored) {
+ plugin.getLogger().warning("Failed to restore arena snapshot for " + arena.getId());
+ }
+ clearPlacedBlocks(arena.getId());
+ clearArenaEntities(arena);
+ arena.setInUse(false);
+ });
+ return;
+ }
+ }
+
+ if (arena != null) {
+ clearPlacedBlocks(arena.getId());
+ clearArenaEntities(arena);
+ arena.setInUse(false);
+ }
+ }
+
+ private void finishMatchWinnerOnly(Player winner, Arena arena, DuelMatch match) {
+ healthDisplays.remove(match.getArenaId());
+ activeHealthLoops.remove(match.getArenaId());
+ if (winner != null) {
+ TablistUtil.clearHealth(winner);
+ TablistUtil.disablePrivateTablist(winner);
+ plugin.getHotbarManager().sendToSpawn(winner);
+ }
+ if (arena != null) {
+ plugin.getSpectateManager().endSpectatorsForArena(arena.getId());
+ }
+
+ if (!plugin.getConfig().getBoolean("arena.regenerateAfterDuel", true)) {
+ if (arena != null) {
+ clearPlacedBlocks(arena.getId());
+ clearArenaEntities(arena);
+ arena.setInUse(false);
+ }
+ return;
+ }
+
+ if (arena != null && worldEdit.isAvailable()) {
+ Location region = arena.getCorner1() != null ? arena.getCorner1() : arena.getSpawn1();
+ if (region != null) {
+ plugin.getScheduler().runAtLocation(region, () -> {
+ boolean restored = worldEdit.restoreSnapshot(arena);
+ if (!restored) {
+ plugin.getLogger().warning("Failed to restore arena snapshot for " + arena.getId());
+ }
+ clearPlacedBlocks(arena.getId());
+ clearArenaEntities(arena);
+ arena.setInUse(false);
+ });
+ return;
+ }
+ }
+
+ if (arena != null) {
+ clearPlacedBlocks(arena.getId());
+ clearArenaEntities(arena);
+ arena.setInUse(false);
+ }
+ }
+
+ private void endMatchWithoutWinner(DuelMatch match, Player loser, Location deathLoc) {
+ if (match.getState() == DuelMatch.State.ENDING) {
+ return;
+ }
+ match.setState(DuelMatch.State.ENDING);
+ Arena arena = plugin.getArenaManager().getById(match.getArenaId());
+ if (loser != null) {
+ pendingSpectator.put(loser.getUniqueId(), deathLoc != null ? deathLoc : (arena != null ? arena.getSpectatorSpawn() : null));
+ playDefeatEffects(loser, arena, deathLoc);
+ plugin.getScheduler().runLaterAtEntity(loser, 100L, () -> {
+ matches.remove(loser.getUniqueId());
+ if (match.getPlayer1().equals(loser.getUniqueId())) {
+ matches.remove(match.getPlayer2());
+ } else {
+ matches.remove(match.getPlayer1());
+ }
+ frozen.remove(loser.getUniqueId());
+ legacyDuelSpectators.remove(loser.getUniqueId());
+ healthDisplays.remove(match.getArenaId());
+ activeHealthLoops.remove(match.getArenaId());
+ pendingSpectator.remove(loser.getUniqueId());
+ showToAll(loser);
+ restoreVisibility(match);
+ plugin.getHotbarManager().sendToSpawn(loser);
+ if (arena != null) {
+ plugin.getSpectateManager().endSpectatorsForArena(arena.getId());
+ }
+ if (arena != null && worldEdit.isAvailable()) {
+ Location region = arena.getCorner1() != null ? arena.getCorner1() : arena.getSpawn1();
+ if (region != null) {
+ plugin.getScheduler().runAtLocation(region, () -> {
+ boolean restored = worldEdit.restoreSnapshot(arena);
+ if (!restored) {
+ plugin.getLogger().warning("Failed to restore arena snapshot for " + arena.getId());
+ }
+ clearPlacedBlocks(arena.getId());
+ clearArenaEntities(arena);
+ arena.setInUse(false);
+ });
+ return;
+ }
+ }
+ if (arena != null) {
+ clearPlacedBlocks(arena.getId());
+ clearArenaEntities(arena);
+ arena.setInUse(false);
+ }
+ });
+ }
+ }
+
+ private void clearArenaEntities(Arena arena) {
+ if (arena.getCorner1() == null || arena.getCorner2() == null) {
+ return;
+ }
+ Location c1 = arena.getCorner1();
+ Location c2 = arena.getCorner2();
+ if (c1.getWorld() == null) {
+ return;
+ }
+ int minX = Math.min(c1.getBlockX(), c2.getBlockX());
+ int minY = Math.min(c1.getBlockY(), c2.getBlockY());
+ int minZ = Math.min(c1.getBlockZ(), c2.getBlockZ());
+ int maxX = Math.max(c1.getBlockX(), c2.getBlockX());
+ int maxY = Math.max(c1.getBlockY(), c2.getBlockY());
+ int maxZ = Math.max(c1.getBlockZ(), c2.getBlockZ());
+
+ org.bukkit.util.BoundingBox box = org.bukkit.util.BoundingBox.of(
+ new org.bukkit.util.Vector(minX, minY, minZ),
+ new org.bukkit.util.Vector(maxX + 1, maxY + 1, maxZ + 1)
+ );
+ for (org.bukkit.entity.Entity entity : c1.getWorld().getNearbyEntities(box)) {
+ if (entity instanceof Player) {
+ continue;
+ }
+ entity.remove();
+ }
+ }
+
+ private long blockKey(Location location) {
+ return packBlock(location.getBlockX(), location.getBlockY(), location.getBlockZ());
+ }
+
+ private long packBlock(int x, int y, int z) {
+ return ((long) (x & 0x3FFFFFF) << 38) | ((long) (z & 0x3FFFFFF) << 12) | (y & 0xFFF);
+ }
+
+ public void refreshVisibilityForArena(String arenaId) {
+ if (arenaId == null) {
+ return;
+ }
+ for (DuelMatch match : new HashSet<>(matches.values())) {
+ if (arenaId.equals(match.getArenaId())) {
+ applyDuelVisibility(match);
+ applySpectatorVisibility(match);
+ return;
+ }
+ }
+ }
+
+ private void applyDuelVisibility(DuelMatch match) {
+ Player p1 = plugin.getServer().getPlayer(match.getPlayer1());
+ Player p2 = plugin.getServer().getPlayer(match.getPlayer2());
+ if (p1 == null || p2 == null) {
+ return;
+ }
+ List spectators = plugin.getSpectateManager().getSpectatorsForArena(match.getArenaId());
+ List specForTab = new java.util.ArrayList<>(spectators);
+ if (p1.getGameMode() == GameMode.SPECTATOR) {
+ specForTab.add(p1);
+ }
+ if (p2.getGameMode() == GameMode.SPECTATOR) {
+ specForTab.add(p2);
+ }
+ for (Player viewer : new Player[] { p1, p2 }) {
+ plugin.getScheduler().runAtEntity(viewer, () -> {
+ TablistUtil.enablePrivateTablist(viewer);
+ TablistUtil.updateSpectators(viewer, specForTab);
+ if (healthDisplays.contains(match.getArenaId())) {
+ java.util.List targets = new java.util.ArrayList<>();
+ targets.add(p1);
+ targets.add(p2);
+ TablistUtil.updateHealth(viewer, targets);
+ }
+ boolean viewerIsSpec = viewer.getGameMode() == GameMode.SPECTATOR || legacyDuelSpectators.contains(viewer.getUniqueId());
+ for (Player online : plugin.getServer().getOnlinePlayers()) {
+ boolean isP1 = online.getUniqueId().equals(p1.getUniqueId());
+ boolean isP2 = online.getUniqueId().equals(p2.getUniqueId());
+ boolean onlineIsSpec = online.getGameMode() == GameMode.SPECTATOR || legacyDuelSpectators.contains(online.getUniqueId());
+ if (viewerIsSpec) {
+ boolean isSpectator = spectators.contains(online) || onlineIsSpec;
+ if (isP1 || isP2 || isSpectator) {
+ viewer.showPlayer(plugin, online);
+ } else {
+ viewer.hidePlayer(plugin, online);
+ }
+ } else {
+ boolean showP1 = isP1 && !onlineIsSpec;
+ boolean showP2 = isP2 && !onlineIsSpec;
+ if (showP1 || showP2) {
+ viewer.showPlayer(plugin, online);
+ } else {
+ viewer.hidePlayer(plugin, online);
+ }
+ }
+ }
+ });
+ }
+ }
+
+ private void applySpectatorVisibility(DuelMatch match) {
+ List spectators = plugin.getSpectateManager().getSpectatorsForArena(match.getArenaId());
+ if (spectators.isEmpty()) {
+ return;
+ }
+ Player p1 = plugin.getServer().getPlayer(match.getPlayer1());
+ Player p2 = plugin.getServer().getPlayer(match.getPlayer2());
+ for (Player spectator : spectators) {
+ plugin.getScheduler().runAtEntity(spectator, () -> {
+ TablistUtil.enablePrivateTablist(spectator);
+ TablistUtil.updateSpectators(spectator, spectators);
+ if (healthDisplays.contains(match.getArenaId()) && p1 != null && p2 != null) {
+ java.util.List targets = new java.util.ArrayList<>();
+ targets.add(p1);
+ targets.add(p2);
+ TablistUtil.updateHealth(spectator, targets);
+ }
+ for (Player online : plugin.getServer().getOnlinePlayers()) {
+ boolean isP1 = p1 != null && online.getUniqueId().equals(p1.getUniqueId());
+ boolean isP2 = p2 != null && online.getUniqueId().equals(p2.getUniqueId());
+ boolean isSpectator = spectators.contains(online);
+ if (isP1 || isP2 || isSpectator) {
+ spectator.showPlayer(plugin, online);
+ } else {
+ spectator.hidePlayer(plugin, online);
+ }
+ }
+ });
+ }
+ }
+
+ private void restoreVisibility(DuelMatch match) {
+ Player p1 = plugin.getServer().getPlayer(match.getPlayer1());
+ Player p2 = plugin.getServer().getPlayer(match.getPlayer2());
+ if (p1 == null || p2 == null) {
+ return;
+ }
+ for (Player viewer : new Player[] { p1, p2 }) {
+ plugin.getScheduler().runAtEntity(viewer, () -> {
+ for (Player online : plugin.getServer().getOnlinePlayers()) {
+ viewer.showPlayer(plugin, online);
+ }
+ TablistUtil.clearHealth(viewer);
+ TablistUtil.disablePrivateTablist(viewer);
+ });
+ }
+ }
+
+ private void showToAll(Player player) {
+ for (Player online : plugin.getServer().getOnlinePlayers()) {
+ online.showPlayer(plugin, player);
+ }
+ TablistUtil.clearHealth(player);
+ TablistUtil.disablePrivateTablist(player);
+ }
+
+ public void refreshAllVisibility() {
+ java.util.Set unique = new java.util.HashSet<>(matches.values());
+ for (DuelMatch match : unique) {
+ applyDuelVisibility(match);
+ }
+ }
+
+ public void handleEscape(Player player, Arena arena) {
+ DuelMatch match = matches.get(player.getUniqueId());
+ if (match == null || match.getState() == DuelMatch.State.ENDING) {
+ return;
+ }
+ String msg = Text.color("&7&o" + player.getName() + " tried to escape the map");
+ java.util.Set recipients = new java.util.HashSet<>();
+ Player p1 = plugin.getServer().getPlayer(match.getPlayer1());
+ Player p2 = plugin.getServer().getPlayer(match.getPlayer2());
+ if (p1 != null) {
+ recipients.add(p1);
+ }
+ if (p2 != null) {
+ recipients.add(p2);
+ }
+ recipients.addAll(plugin.getSpectateManager().getSpectatorsForArena(match.getArenaId()));
+ for (Player target : recipients) {
+ target.sendMessage(msg);
+ }
+ plugin.getScheduler().runAtEntity(player, () -> player.setHealth(0.0));
+ }
+
+ private void scheduleHealthUpdate(String arenaId) {
+ if (arenaId == null || !healthDisplays.contains(arenaId) || !activeHealthLoops.add(arenaId)) {
+ return;
+ }
+ runHealthUpdateTick(arenaId);
+ }
+
+ private void runHealthUpdateTick(String arenaId) {
+ if (arenaId == null || !healthDisplays.contains(arenaId)) {
+ activeHealthLoops.remove(arenaId);
+ return;
+ }
+ DuelMatch match = getMatchByArena(arenaId);
+ if (match == null || match.getState() == DuelMatch.State.ENDING) {
+ healthDisplays.remove(arenaId);
+ activeHealthLoops.remove(arenaId);
+ return;
+ }
+ Player p1 = plugin.getServer().getPlayer(match.getPlayer1());
+ Player p2 = plugin.getServer().getPlayer(match.getPlayer2());
+ if (p1 == null || p2 == null) {
+ healthDisplays.remove(arenaId);
+ activeHealthLoops.remove(arenaId);
+ return;
+ }
+ java.util.List viewers = new java.util.ArrayList<>();
+ viewers.add(p1);
+ viewers.add(p2);
+ viewers.addAll(plugin.getSpectateManager().getSpectatorsForArena(match.getArenaId()));
+ java.util.List targets = new java.util.ArrayList<>();
+ targets.add(p1);
+ targets.add(p2);
+ for (Player viewer : viewers) {
+ TablistUtil.updateHealth(viewer, targets);
+ }
+ plugin.getScheduler().runLaterGlobal(10L, () -> runHealthUpdateTick(arenaId));
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/PartyManager.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/PartyManager.java
new file mode 100644
index 0000000..99813b9
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/PartyManager.java
@@ -0,0 +1,377 @@
+package com.starpractice.manager;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.Party;
+import com.starpractice.model.PartyInvite;
+import com.starpractice.util.Text;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import net.md_5.bungee.api.chat.ClickEvent;
+import net.md_5.bungee.api.chat.ComponentBuilder;
+import net.md_5.bungee.api.chat.HoverEvent;
+import net.md_5.bungee.api.chat.TextComponent;
+import org.bukkit.entity.Player;
+
+public class PartyManager {
+ private final StarPracticePlugin plugin;
+ private final Map byMember = new HashMap<>();
+ private final Map> pending = new HashMap<>();
+
+ public PartyManager(StarPracticePlugin plugin) {
+ this.plugin = plugin;
+ }
+
+ public Party getParty(UUID uuid) {
+ return byMember.get(uuid);
+ }
+
+ public boolean isLeader(UUID uuid) {
+ Party party = byMember.get(uuid);
+ return party != null && party.getLeader().equals(uuid);
+ }
+
+ public void invite(Player inviter, Player target) {
+ if (!plugin.getConfig().getBoolean("features.parties.enabled", true)) {
+ plugin.sendMessage(inviter, plugin.getConfig().getString("messages.party-feature-disabled", "&cParties are disabled on this server."));
+ return;
+ }
+ if (plugin.getMatchManager().isInMatch(inviter) || plugin.getPartyMatchManager().isInMatch(inviter)) {
+ plugin.sendMessage(inviter, plugin.getConfig().getString("messages.party-in-duel", "&cYou cannot do that while in a duel."));
+ return;
+ }
+ if (plugin.getMatchManager().isInMatch(target) || plugin.getPartyMatchManager().isInMatch(target)) {
+ plugin.sendMessage(inviter, plugin.getConfig().getString("messages.party-target-in-duel", "&cThat player is in a duel."));
+ return;
+ }
+ if (!plugin.getSettingsManager().getSettings(target.getUniqueId()).isPartyInvites()) {
+ plugin.sendMessage(inviter, plugin.getConfig().getString("messages.party-invite-disabled", "&cThat player has party invites disabled."));
+ return;
+ }
+ if (!isLeader(inviter.getUniqueId())) {
+ Party party = getParty(inviter.getUniqueId());
+ if (party == null) {
+ party = new Party(inviter.getUniqueId());
+ registerParty(party);
+ plugin.getQueueManager().removePlayer(inviter.getUniqueId());
+ } else if (!party.getLeader().equals(inviter.getUniqueId())) {
+ plugin.sendMessage(inviter, plugin.getConfig().getString("messages.party-not-leader", "&cOnly the party leader can do that."));
+ return;
+ }
+ }
+ if (getParty(target.getUniqueId()) != null) {
+ plugin.sendMessage(inviter, plugin.getConfig().getString("messages.party-target-in-party", "&cThat player is already in a party."));
+ return;
+ }
+ pending.computeIfAbsent(target.getUniqueId(), key -> new HashMap<>())
+ .put(inviter.getUniqueId(), new PartyInvite(inviter.getUniqueId(), target.getUniqueId(), System.currentTimeMillis()));
+ plugin.sendMessage(inviter, plugin.getConfig().getString("messages.party-invite-sent", "&aParty invite sent to &f%player%&a.")
+ .replace("%player%", target.getName()));
+ sendInviteMessage(target, inviter);
+ try {
+ target.playSound(target.getLocation(), org.bukkit.Sound.BLOCK_NOTE_BLOCK_CHIME, 1.0f, 1.0f);
+ } catch (IllegalArgumentException ignored) {
+ }
+ }
+
+ public void accept(Player target, Player inviter) {
+ if (!plugin.getConfig().getBoolean("features.parties.enabled", true)) {
+ plugin.sendMessage(target, plugin.getConfig().getString("messages.party-feature-disabled", "&cParties are disabled on this server."));
+ return;
+ }
+ if (plugin.getMatchManager().isInMatch(target) || plugin.getPartyMatchManager().isInMatch(target)) {
+ plugin.sendMessage(target, plugin.getConfig().getString("messages.party-in-duel", "&cYou cannot do that while in a duel."));
+ return;
+ }
+ if (plugin.getMatchManager().isInMatch(inviter) || plugin.getPartyMatchManager().isInMatch(inviter)) {
+ plugin.sendMessage(target, plugin.getConfig().getString("messages.party-target-in-duel", "&cThat player is in a duel."));
+ return;
+ }
+ if (!hasPending(target.getUniqueId(), inviter.getUniqueId())) {
+ plugin.sendMessage(target, plugin.getConfig().getString("messages.party-invite-none", "&cNo pending party invite from that player."));
+ return;
+ }
+ removePending(target.getUniqueId(), inviter.getUniqueId());
+ Party party = getParty(inviter.getUniqueId());
+ if (party == null) {
+ party = new Party(inviter.getUniqueId());
+ registerParty(party);
+ }
+ plugin.getQueueManager().removePlayer(target.getUniqueId());
+ registerMember(party, target.getUniqueId());
+ String msg = plugin.getConfig().getString("messages.party-join", "&aYou joined &f%player%&a's party.");
+ plugin.sendMessage(target, msg.replace("%player%", inviter.getName()));
+ broadcast(party, plugin.getConfig().getString("messages.party-join-broadcast", "&a%player% joined the party.").replace("%player%", target.getName()));
+ }
+
+ public void deny(Player target, Player inviter) {
+ if (!hasPending(target.getUniqueId(), inviter.getUniqueId())) {
+ plugin.sendMessage(target, plugin.getConfig().getString("messages.party-invite-none", "&cNo pending party invite from that player."));
+ return;
+ }
+ removePending(target.getUniqueId(), inviter.getUniqueId());
+ plugin.sendMessage(target, plugin.getConfig().getString("messages.party-invite-denied", "&eYou denied the party invite from &f%player%&e.")
+ .replace("%player%", inviter.getName()));
+ if (inviter.isOnline()) {
+ plugin.sendMessage(inviter, plugin.getConfig().getString("messages.party-invite-denied-target", "&e%player% denied your party invite.")
+ .replace("%player%", target.getName()));
+ }
+ }
+
+ public void leave(Player player) {
+ Party party = getParty(player.getUniqueId());
+ if (party == null) {
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.party-none", "&cYou are not in a party."));
+ return;
+ }
+ if (party.getLeader().equals(player.getUniqueId())) {
+ disband(player);
+ return;
+ }
+ party.getMembers().remove(player.getUniqueId());
+ byMember.remove(player.getUniqueId());
+ removeAllRequestsFor(player);
+ plugin.getSocialStorage().removeMember(player.getUniqueId());
+ syncParty(party);
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.party-left", "&eYou left the party."));
+ broadcast(party, plugin.getConfig().getString("messages.party-left-broadcast", "&e%player% left the party.")
+ .replace("%player%", player.getName()));
+ }
+
+ public void forceLeave(Player player) {
+ Party party = getParty(player.getUniqueId());
+ if (party == null) {
+ return;
+ }
+ if (party.getLeader().equals(player.getUniqueId())) {
+ disband(player);
+ return;
+ }
+ party.getMembers().remove(player.getUniqueId());
+ byMember.remove(player.getUniqueId());
+ removeAllRequestsFor(player);
+ plugin.getSocialStorage().removeMember(player.getUniqueId());
+ syncParty(party);
+ broadcast(party, plugin.getConfig().getString("messages.party-left-broadcast", "&e%player% left the party.")
+ .replace("%player%", player.getName()));
+ }
+
+ public void kick(Player leader, Player target) {
+ Party party = getParty(leader.getUniqueId());
+ if (!ensureLeader(leader, party)) {
+ return;
+ }
+ if (target.getUniqueId().equals(leader.getUniqueId())) {
+ plugin.sendMessage(leader, "&cYou cannot kick yourself.");
+ return;
+ }
+ if (!party.isMember(target.getUniqueId())) {
+ plugin.sendMessage(leader, plugin.getConfig().getString("messages.party-not-in-party", "&cThat player is not in your party."));
+ return;
+ }
+ party.getMembers().remove(target.getUniqueId());
+ byMember.remove(target.getUniqueId());
+ removeAllRequestsFor(target);
+ plugin.getSocialStorage().removeMember(target.getUniqueId());
+ syncParty(party);
+ plugin.sendMessage(leader, plugin.getConfig().getString("messages.party-kick", "&eYou kicked &f%player%&e from the party.")
+ .replace("%player%", target.getName()));
+ if (target.isOnline()) {
+ plugin.sendMessage(target, plugin.getConfig().getString("messages.party-kicked", "&cYou were kicked from the party."));
+ }
+ broadcast(party, plugin.getConfig().getString("messages.party-kick-broadcast", "&e%player% was kicked from the party.")
+ .replace("%player%", target.getName()));
+ }
+
+ public void promote(Player leader, Player target) {
+ Party party = getParty(leader.getUniqueId());
+ if (!ensureLeader(leader, party)) {
+ return;
+ }
+ if (!party.isMember(target.getUniqueId())) {
+ plugin.sendMessage(leader, plugin.getConfig().getString("messages.party-not-in-party", "&cThat player is not in your party."));
+ return;
+ }
+ party.setLeader(target.getUniqueId());
+ plugin.getSocialStorage().removeParty(leader.getUniqueId());
+ syncParty(party);
+ plugin.sendMessage(leader, plugin.getConfig().getString("messages.party-leader-set", "&aYou made &f%player%&a the party leader.")
+ .replace("%player%", target.getName()));
+ broadcast(party, plugin.getConfig().getString("messages.party-leader-broadcast", "&a%player% is now the party leader.")
+ .replace("%player%", target.getName()));
+ }
+
+ public void disband(Player leader) {
+ Party party = getParty(leader.getUniqueId());
+ if (!ensureLeader(leader, party)) {
+ return;
+ }
+ List members = new ArrayList<>(party.getMembers());
+ for (UUID member : new ArrayList<>(party.getMembers())) {
+ byMember.remove(member);
+ Player online = plugin.getServer().getPlayer(member);
+ if (online != null && online.isOnline()) {
+ plugin.sendMessage(online, plugin.getConfig().getString("messages.party-disband", "&cThe party was disbanded."));
+ }
+ }
+ purgePendingFor(members);
+ plugin.getSocialStorage().removeParty(leader.getUniqueId());
+ }
+
+ public void list(Player player) {
+ Party party = getParty(player.getUniqueId());
+ if (party == null) {
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.party-none", "&cYou are not in a party."));
+ return;
+ }
+ List names = new ArrayList<>();
+ String leaderName = nameOf(party.getLeader());
+ names.add(leaderName + " &7(Leader)");
+ List rest = new ArrayList<>();
+ for (UUID member : party.getMembers()) {
+ if (member.equals(party.getLeader())) {
+ continue;
+ }
+ rest.add(nameOf(member));
+ }
+ rest.sort(Comparator.comparing(String::toLowerCase));
+ names.addAll(rest);
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.party-list", "&aParty: &f%list%")
+ .replace("%list%", String.join("&7, &f", names)));
+ }
+
+ public List getMemberNames(Party party) {
+ List names = new ArrayList<>();
+ if (party == null) {
+ return names;
+ }
+ for (UUID member : party.getMembers()) {
+ Player online = plugin.getServer().getPlayer(member);
+ if (online != null && online.isOnline()) {
+ names.add(online.getName());
+ }
+ }
+ return names;
+ }
+
+ private void registerParty(Party party) {
+ for (UUID member : party.getMembers()) {
+ byMember.put(member, party);
+ }
+ syncParty(party);
+ }
+
+ private void registerMember(Party party, UUID uuid) {
+ party.getMembers().add(uuid);
+ byMember.put(uuid, party);
+ syncParty(party);
+ }
+
+ private void syncParty(Party party) {
+ plugin.getSocialStorage().saveParty(party);
+ }
+
+ private boolean ensureLeader(Player leader, Party party) {
+ if (party == null) {
+ plugin.sendMessage(leader, plugin.getConfig().getString("messages.party-none", "&cYou are not in a party."));
+ return false;
+ }
+ if (!party.getLeader().equals(leader.getUniqueId())) {
+ plugin.sendMessage(leader, plugin.getConfig().getString("messages.party-not-leader", "&cOnly the party leader can do that."));
+ return false;
+ }
+ return true;
+ }
+
+ private boolean hasPending(UUID target, UUID inviter) {
+ Map map = pending.get(target);
+ return map != null && map.containsKey(inviter);
+ }
+
+ private void removePending(UUID target, UUID inviter) {
+ Map map = pending.get(target);
+ if (map == null) {
+ return;
+ }
+ map.remove(inviter);
+ if (map.isEmpty()) {
+ pending.remove(target);
+ }
+ }
+
+ public void removeAllRequestsFor(Player player) {
+ pending.remove(player.getUniqueId());
+ for (UUID target : new ArrayList<>(pending.keySet())) {
+ Map map = pending.get(target);
+ if (map == null) {
+ continue;
+ }
+ map.remove(player.getUniqueId());
+ if (map.isEmpty()) {
+ pending.remove(target);
+ }
+ }
+ }
+
+ private void purgePendingFor(List members) {
+ if (members == null || members.isEmpty()) {
+ return;
+ }
+ for (UUID member : members) {
+ pending.remove(member);
+ }
+ for (UUID target : new ArrayList<>(pending.keySet())) {
+ Map map = pending.get(target);
+ if (map == null) {
+ continue;
+ }
+ for (UUID member : members) {
+ map.remove(member);
+ }
+ if (map.isEmpty()) {
+ pending.remove(target);
+ }
+ }
+ }
+
+ private void sendInviteMessage(Player target, Player inviter) {
+ String prefix = plugin.getConfig().getString("messages.prefix", "&eStarPractice &7");
+ String base = plugin.getConfig().getString("messages.party-invite-received", "&a%player% invited you to a party.");
+ base = base.replace("%player%", inviter.getName());
+
+ TextComponent message = new TextComponent(TextComponent.fromLegacyText(Text.color(prefix + base + " ")));
+ TextComponent accept = new TextComponent(Text.color("&a[&a✔&a &aA&aC&aC&aE&aP&aT&a]"));
+ accept.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/party accept " + inviter.getName()));
+ accept.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(Text.color("&aClick to accept")).create()));
+ TextComponent deny = new TextComponent(Text.color("&c[&c✖&c &cD&cE&cN&cY&c]"));
+ deny.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/party deny " + inviter.getName()));
+ deny.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(Text.color("&cClick to deny")).create()));
+ message.addExtra(accept);
+ message.addExtra(new TextComponent(" "));
+ message.addExtra(deny);
+ target.spigot().sendMessage(message);
+ }
+
+ private void broadcast(Party party, String message) {
+ for (UUID member : party.getMembers()) {
+ Player online = plugin.getServer().getPlayer(member);
+ if (online != null && online.isOnline()) {
+ plugin.sendMessage(online, message);
+ }
+ }
+ }
+
+ private String nameOf(UUID uuid) {
+ Player online = plugin.getServer().getPlayer(uuid);
+ return online != null ? online.getName() : uuid.toString();
+ }
+
+ public void clearAll() {
+ byMember.clear();
+ pending.clear();
+ }
+}
+
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/PartyMatchManager.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/PartyMatchManager.java
new file mode 100644
index 0000000..0340aea
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/PartyMatchManager.java
@@ -0,0 +1,795 @@
+package com.starpractice.manager;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.Arena;
+import com.starpractice.model.Gamemode;
+import com.starpractice.model.Party;
+import com.starpractice.model.PartyMatch;
+import com.starpractice.model.PrepotData;
+import com.starpractice.util.Text;
+import com.starpractice.util.WorldEditAdapter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import org.bukkit.GameMode;
+import org.bukkit.Location;
+import org.bukkit.NamespacedKey;
+import org.bukkit.Sound;
+import org.bukkit.entity.Item;
+import org.bukkit.entity.Player;
+import org.bukkit.potion.PotionEffect;
+import org.bukkit.potion.PotionEffectType;
+
+public class PartyMatchManager {
+ private final StarPracticePlugin plugin;
+ private final WorldEditAdapter worldEdit;
+ private final Map matches = new HashMap<>();
+ private final Set frozen = new HashSet<>();
+ private final Map> placedBlocks = new HashMap<>();
+ private final Set healthDisplays = new HashSet<>();
+ private final Set activeHealthLoops = new HashSet<>();
+
+ public PartyMatchManager(StarPracticePlugin plugin, WorldEditAdapter worldEdit) {
+ this.plugin = plugin;
+ this.worldEdit = worldEdit;
+ }
+
+ public boolean isInMatch(Player player) {
+ return matches.containsKey(player.getUniqueId());
+ }
+
+ public PartyMatch getMatch(Player player) {
+ return matches.get(player.getUniqueId());
+ }
+
+ public boolean isFrozen(Player player) {
+ return frozen.contains(player.getUniqueId());
+ }
+
+ public void clearRuntimeState(UUID playerId) {
+ if (playerId == null) {
+ return;
+ }
+ matches.remove(playerId);
+ frozen.remove(playerId);
+ }
+
+ public void clearAllRuntime() {
+ for (UUID uuid : new HashSet<>(matches.keySet())) {
+ Player player = plugin.getServer().getPlayer(uuid);
+ if (player != null && player.isOnline()) {
+ plugin.getHotbarManager().sendToSpawn(player);
+ }
+ }
+ for (PartyMatch match : new HashSet<>(matches.values())) {
+ clearMatchRuntime(match);
+ Arena arena = plugin.getArenaManager().getById(match.getArenaId());
+ if (arena != null) {
+ arena.setInUse(false);
+ }
+ }
+ matches.clear();
+ frozen.clear();
+ placedBlocks.clear();
+ healthDisplays.clear();
+ activeHealthLoops.clear();
+ }
+
+ public void startMatch(Party party, PartyMatch.Mode mode, Gamemode gamemode, int rounds) {
+ List online = getOnlineMembers(party);
+ List participants = selectParticipants(online, mode);
+ if (participants == null) {
+ return;
+ }
+ for (Player player : participants) {
+ plugin.getQueueManager().removePlayer(player.getUniqueId());
+ }
+ boolean requireCenter = mode == PartyMatch.Mode.FFA;
+ Arena arena = plugin.getArenaManager().findAvailableArena(gamemode, requireCenter);
+ if (arena == null) {
+ if (!online.isEmpty()) {
+ plugin.sendMessage(online.get(0), plugin.getConfig().getString("messages.no-arenas"));
+ }
+ return;
+ }
+
+ arena.setInUse(true);
+ PartyMatch match = new PartyMatch(mode, arena.getId(), gamemode.getId(), Math.max(1, rounds));
+ for (Player player : participants) {
+ match.getParticipants().add(player.getUniqueId());
+ matches.put(player.getUniqueId(), match);
+ }
+ match.getAlive().addAll(match.getParticipants());
+ assignTeams(match, participants);
+ placedBlocks.remove(arena.getId());
+
+ for (Player player : participants) {
+ plugin.getScheduler().runAtEntity(player, () -> plugin.getHotbarManager().restoreIfStored(player));
+ }
+
+ for (Player player : participants) {
+ runPartyStartAnimation(player);
+ }
+ if (!participants.isEmpty()) {
+ Player anchor = participants.get(0);
+ plugin.getScheduler().runLaterAtEntity(anchor, 40L, () -> {
+ prepareRound(match, arena, gamemode, participants);
+ startCountdown(match, gamemode, participants);
+ });
+ }
+ }
+
+ public void handleDeath(Player dead) {
+ PartyMatch match = matches.get(dead.getUniqueId());
+ if (match == null) {
+ return;
+ }
+ match.getAlive().remove(dead.getUniqueId());
+ playDefeatEffects(dead, plugin.getArenaManager().getById(match.getArenaId()), dead.getLocation());
+ checkRoundEnd(match);
+ }
+
+ public void forfeit(Player player) {
+ PartyMatch match = matches.get(player.getUniqueId());
+ if (match == null) {
+ return;
+ }
+ if (match.getMode() == PartyMatch.Mode.FFA) {
+ removeParticipant(match, player.getUniqueId());
+ playDefeatEffects(player, plugin.getArenaManager().getById(match.getArenaId()), player.getLocation());
+ checkRoundEnd(match);
+ return;
+ }
+ handleForfeit(match, player);
+ }
+
+ public void leaveMatch(Player player) {
+ PartyMatch match = matches.get(player.getUniqueId());
+ if (match == null) {
+ return;
+ }
+ removeParticipant(match, player.getUniqueId());
+ plugin.getHotbarManager().sendToSpawn(player);
+ checkRoundEnd(match);
+ }
+
+ private void handleForfeit(PartyMatch match, Player player) {
+ match.setState(PartyMatch.State.ENDING);
+ healthDisplays.remove(match.getArenaId());
+ Arena arena = plugin.getArenaManager().getById(match.getArenaId());
+ List participants = getPlayers(match.getParticipants());
+ Integer team = match.getTeam().get(player.getUniqueId());
+ if (match.getMode() == PartyMatch.Mode.TWO_V_TWO && team != null) {
+ int winningTeam = team == 0 ? 1 : 0;
+ match.getTeamScore().put(winningTeam, match.getRequiredWins());
+ int red = match.getTeamScore().getOrDefault(0, 0);
+ int blue = match.getTeamScore().getOrDefault(1, 0);
+ String scoreLine = "&c" + red + " &7- &9" + blue;
+ for (Player p : participants) {
+ Integer t = match.getTeam().get(p.getUniqueId());
+ if (t != null && t == winningTeam) {
+ p.sendTitle(Text.color(plugin.getConfig().getString("messages.duel-win-title")), Text.color(scoreLine), 10, 60, 10);
+ playVictorySound(p);
+ } else {
+ p.sendTitle(Text.color(plugin.getConfig().getString("messages.duel-lose-title")), Text.color(scoreLine), 10, 60, 10);
+ }
+ }
+ } else if (match.getMode() == PartyMatch.Mode.ONE_V_ONE && team != null) {
+ int winningTeam = team == 0 ? 1 : 0;
+ match.getTeamScore().put(winningTeam, match.getRequiredWins());
+ int red = match.getTeamScore().getOrDefault(0, 0);
+ int blue = match.getTeamScore().getOrDefault(1, 0);
+ String scoreLine = "&c" + red + " &7- &9" + blue;
+ for (Player p : participants) {
+ Integer t = match.getTeam().get(p.getUniqueId());
+ if (t != null && t == winningTeam) {
+ p.sendTitle(Text.color(plugin.getConfig().getString("messages.duel-win-title")), Text.color(scoreLine), 10, 60, 10);
+ playVictorySound(p);
+ } else {
+ p.sendTitle(Text.color(plugin.getConfig().getString("messages.duel-lose-title")), Text.color(scoreLine), 10, 60, 10);
+ }
+ }
+ } else {
+ for (Player p : participants) {
+ if (!p.getUniqueId().equals(player.getUniqueId())) {
+ p.sendTitle(Text.color(plugin.getConfig().getString("messages.duel-win-title")), "", 10, 60, 10);
+ playVictorySound(p);
+ }
+ }
+ }
+ if (arena != null) {
+ clearPlacedBlocks(arena.getId());
+ clearDroppedItems(arena);
+ arena.setInUse(false);
+ }
+ clearMatchRuntime(match);
+ for (Player p : participants) {
+ com.starpractice.util.TablistUtil.clearHealth(p);
+ }
+ plugin.getScheduler().runLaterGlobal(100L, () -> {
+ for (Player p : participants) {
+ plugin.getHotbarManager().sendToSpawn(p);
+ }
+ if (arena != null && worldEdit.isAvailable() && plugin.getConfig().getBoolean("arena.regenerateAfterDuel", true)) {
+ Location region = arena.getCorner1() != null ? arena.getCorner1() : arena.getSpawn1();
+ if (region != null) {
+ plugin.getScheduler().runAtLocation(region, () -> worldEdit.restoreSnapshot(arena));
+ }
+ }
+ });
+ }
+
+ private void removeParticipant(PartyMatch match, UUID uuid) {
+ match.getParticipants().remove(uuid);
+ match.getAlive().remove(uuid);
+ match.getTeam().remove(uuid);
+ match.getPlayerScore().remove(uuid);
+ matches.remove(uuid);
+ frozen.remove(uuid);
+ }
+
+ public void recordPlacedBlock(String arenaId, Location location) {
+ if (arenaId == null || location == null || location.getWorld() == null) {
+ return;
+ }
+ placedBlocks.computeIfAbsent(arenaId, key -> new HashSet<>()).add(blockKey(location));
+ }
+
+ public boolean isPlacedBlock(String arenaId, Location location) {
+ if (arenaId == null || location == null || location.getWorld() == null) {
+ return false;
+ }
+ Set set = placedBlocks.get(arenaId);
+ return set != null && set.contains(blockKey(location));
+ }
+
+ private List getOnlineMembers(Party party) {
+ List players = new ArrayList<>();
+ for (UUID uuid : party.getMembers()) {
+ Player player = plugin.getServer().getPlayer(uuid);
+ if (player != null && player.isOnline()) {
+ players.add(player);
+ }
+ }
+ return players;
+ }
+
+ private List selectParticipants(List online, PartyMatch.Mode mode) {
+ if (mode == PartyMatch.Mode.ONE_V_ONE) {
+ if (online.size() < 2) {
+ if (!online.isEmpty()) {
+ plugin.sendMessage(online.get(0), plugin.getConfig().getString("messages.party-play-need", "&cNot enough players for that mode."));
+ }
+ return null;
+ }
+ return online.subList(0, 2);
+ }
+ if (mode == PartyMatch.Mode.TWO_V_TWO) {
+ if (online.size() < 4) {
+ if (!online.isEmpty()) {
+ plugin.sendMessage(online.get(0), plugin.getConfig().getString("messages.party-play-need", "&cNot enough players for that mode."));
+ }
+ return null;
+ }
+ return online.subList(0, 4);
+ }
+ if (online.size() < 2) {
+ if (!online.isEmpty()) {
+ plugin.sendMessage(online.get(0), plugin.getConfig().getString("messages.party-play-need", "&cNot enough players for that mode."));
+ }
+ return null;
+ }
+ return online;
+ }
+
+ private void assignTeams(PartyMatch match, List participants) {
+ if (match.getMode() == PartyMatch.Mode.FFA) {
+ for (Player player : participants) {
+ match.getPlayerScore().put(player.getUniqueId(), 0);
+ }
+ return;
+ }
+ int index = 0;
+ for (Player player : participants) {
+ int team = (index < participants.size() / 2) ? 0 : 1;
+ match.getTeam().put(player.getUniqueId(), team);
+ index++;
+ }
+ match.getTeamScore().put(0, 0);
+ match.getTeamScore().put(1, 0);
+ }
+
+ private void prepareRound(PartyMatch match, Arena arena, Gamemode gamemode, List participants) {
+ match.setState(PartyMatch.State.COUNTDOWN);
+ match.getAlive().clear();
+ match.getAlive().addAll(match.getParticipants());
+ frozen.clear();
+ for (Player player : participants) {
+ frozen.add(player.getUniqueId());
+ Location spawn = pickSpawn(match, arena, player);
+ plugin.getScheduler().runAtEntity(player, () -> {
+ preparePlayer(player, spawn, gamemode);
+ applyPostTeleportBlindness(player);
+ });
+ }
+ }
+
+ private Location pickSpawn(PartyMatch match, Arena arena, Player player) {
+ if (arena == null) {
+ return null;
+ }
+ if (match.getMode() == PartyMatch.Mode.FFA) {
+ return arena.getCenterSpawn();
+ }
+ Integer team = match.getTeam().get(player.getUniqueId());
+ if (team != null && team == 1) {
+ return arena.getSpawn2();
+ }
+ return arena.getSpawn1();
+ }
+
+ private void preparePlayer(Player player, Location spawn, Gamemode gamemode) {
+ if (spawn != null) {
+ player.teleport(spawn);
+ }
+ player.getActivePotionEffects().forEach(effect -> player.removePotionEffect(effect.getType()));
+ player.setFireTicks(0);
+ player.setHealth(player.getMaxHealth());
+ player.setFoodLevel(20);
+ player.setSaturation(gamemode.isFullSaturation() ? 20.0f : 0.0f);
+ player.setGameMode(GameMode.SURVIVAL);
+ com.starpractice.model.Kit kit = plugin.getPlayerKitManager().resolveKit(player, gamemode);
+ if (kit != null) {
+ kit.apply(player);
+ }
+ }
+
+ private void startCountdown(PartyMatch match, Gamemode gamemode, List participants) {
+ int seconds = plugin.getConfig().getInt("countdown.seconds", 5);
+ Sound sound;
+ try {
+ sound = Sound.valueOf(plugin.getConfig().getString("countdown.sound", "UI_BUTTON_CLICK"));
+ } catch (IllegalArgumentException e) {
+ sound = Sound.UI_BUTTON_CLICK;
+ }
+ float volume = (float) plugin.getConfig().getDouble("countdown.volume", 1.0);
+ float pitch = (float) plugin.getConfig().getDouble("countdown.pitch", 1.0);
+ final Sound finalSound = sound;
+ final float finalVolume = volume;
+ final float finalPitch = pitch;
+
+ for (int i = seconds; i >= 1; i--) {
+ int delay = (seconds - i) * 20;
+ int count = i;
+ for (Player player : participants) {
+ plugin.getScheduler().runLaterAtEntity(player, delay, () -> {
+ if (!isInMatch(player)) {
+ return;
+ }
+ player.sendTitle(Text.color("&e" + count), "", 0, 20, 0);
+ player.playSound(player.getLocation(), finalSound, finalVolume, finalPitch);
+ });
+ }
+ }
+ if (!participants.isEmpty()) {
+ Player anchor = participants.get(0);
+ plugin.getScheduler().runLaterAtEntity(anchor, seconds * 20L, () -> startFight(match, gamemode, participants));
+ }
+ }
+
+ private void startFight(PartyMatch match, Gamemode gamemode, List participants) {
+ if (match.getState() != PartyMatch.State.COUNTDOWN) {
+ return;
+ }
+ for (Player player : participants) {
+ frozen.remove(player.getUniqueId());
+ }
+ match.setState(PartyMatch.State.ACTIVE);
+ String startMsg = plugin.getConfig().getString("messages.duel-start", "&aFight!");
+ for (Player player : participants) {
+ player.sendTitle(Text.color(startMsg), "", 0, 40, 10);
+ player.playSound(player.getLocation(), Sound.ENTITY_ENDER_DRAGON_GROWL, 1.0f, 1.0f);
+ playPrepotEffects(player, gamemode);
+ }
+ if (gamemode.isHealthDisplay()) {
+ healthDisplays.add(match.getArenaId());
+ scheduleHealthUpdate(match.getArenaId());
+ }
+ }
+
+ private void runPartyStartAnimation(Player player) {
+ plugin.getScheduler().runAtEntity(player, () -> {
+ player.sendTitle(Text.color("&6Party Game Starting..."), "", 0, 40, 10);
+ applyStartBlindness(player);
+ Sound sound;
+ try {
+ sound = Sound.valueOf(plugin.getConfig().getString("startAnimation.sound", "ENTITY_EVOKER_PREPARE_ATTACK"));
+ } catch (IllegalArgumentException e) {
+ sound = Sound.ENTITY_EVOKER_PREPARE_ATTACK;
+ }
+ float volume = (float) plugin.getConfig().getDouble("startAnimation.volume", 1.0);
+ float pitch = (float) plugin.getConfig().getDouble("startAnimation.pitch", 1.0);
+ player.playSound(player.getLocation(), sound, volume, pitch);
+ });
+ }
+
+ private void applyStartBlindness(Player player) {
+ player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 40, 1, true, false, false));
+ }
+
+ private void applyPostTeleportBlindness(Player player) {
+ player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 40, 1, true, false, false));
+ }
+
+ private boolean applyPrepots(Player player, Gamemode gamemode) {
+ if (!gamemode.isPrepotEnabled()) {
+ return false;
+ }
+ boolean applied = false;
+ for (Map.Entry entry : gamemode.getPrepotEffects().entrySet()) {
+ PrepotData data = entry.getValue();
+ if (!data.isEnabled() || data.getDurationSeconds() <= 0) {
+ continue;
+ }
+ PotionEffectType type = PotionEffectType.getByKey(NamespacedKey.minecraft(entry.getKey()));
+ if (type == null) {
+ continue;
+ }
+ player.addPotionEffect(new PotionEffect(type, data.getDurationSeconds() * 20, data.getAmplifier(), true, true, true));
+ applied = true;
+ }
+ return applied;
+ }
+
+ private void playPrepotEffects(Player player, Gamemode gamemode) {
+ boolean applied = applyPrepots(player, gamemode);
+ if (applied) {
+ player.playSound(player.getLocation(), Sound.ENTITY_SPLASH_POTION_BREAK, 1.0f, 1.0f);
+ }
+ }
+
+ private void checkRoundEnd(PartyMatch match) {
+ if (match.getState() != PartyMatch.State.ACTIVE) {
+ return;
+ }
+ if (match.getParticipants().isEmpty()) {
+ finishMatch(match, new ArrayList<>(), plugin.getArenaManager().getById(match.getArenaId()));
+ return;
+ }
+ if (match.getAlive().isEmpty()) {
+ endRound(match, null, null);
+ return;
+ }
+ if (match.getMode() == PartyMatch.Mode.FFA) {
+ if (match.getAlive().size() <= 1) {
+ UUID winner = match.getAlive().stream().findFirst().orElse(null);
+ endRound(match, winner, null);
+ }
+ return;
+ }
+ Integer winningTeam = getWinningTeam(match);
+ if (winningTeam != null) {
+ endRound(match, null, winningTeam);
+ }
+ }
+
+ private Integer getWinningTeam(PartyMatch match) {
+ Integer team = null;
+ for (UUID uuid : match.getAlive()) {
+ Integer t = match.getTeam().get(uuid);
+ if (t == null) {
+ continue;
+ }
+ if (team == null) {
+ team = t;
+ } else if (!team.equals(t)) {
+ return null;
+ }
+ }
+ return team;
+ }
+
+ private void endRound(PartyMatch match, UUID winner, Integer winningTeam) {
+ Arena arena = plugin.getArenaManager().getById(match.getArenaId());
+ List participants = getPlayers(match.getParticipants());
+
+ if (match.getMode() == PartyMatch.Mode.FFA) {
+ if (winner != null) {
+ match.getPlayerScore().put(winner, match.getPlayerScore().getOrDefault(winner, 0) + 1);
+ }
+ for (Player player : participants) {
+ if (winner != null && player.getUniqueId().equals(winner)) {
+ player.sendTitle(Text.color(plugin.getConfig().getString("messages.duel-win-title")), Text.color("&7Winner"), 10, 60, 10);
+ playVictorySound(player);
+ } else {
+ player.sendTitle(Text.color(plugin.getConfig().getString("messages.duel-lose-title")), Text.color("&7Winner"), 10, 60, 10);
+ }
+ }
+ if (winner != null && match.getPlayerScore().getOrDefault(winner, 0) >= match.getRequiredWins()) {
+ finishMatch(match, participants, arena);
+ return;
+ }
+ } else if (winningTeam != null) {
+ match.getTeamScore().put(winningTeam, match.getTeamScore().getOrDefault(winningTeam, 0) + 1);
+ int red = match.getTeamScore().getOrDefault(0, 0);
+ int blue = match.getTeamScore().getOrDefault(1, 0);
+ String scoreLine = "&c" + red + " &7- &9" + blue;
+ for (Player player : participants) {
+ Integer team = match.getTeam().get(player.getUniqueId());
+ if (team != null && team.equals(winningTeam)) {
+ player.sendTitle(Text.color(plugin.getConfig().getString("messages.duel-win-title")), Text.color(scoreLine), 10, 60, 10);
+ playVictorySound(player);
+ } else {
+ player.sendTitle(Text.color(plugin.getConfig().getString("messages.duel-lose-title")), Text.color(scoreLine), 10, 60, 10);
+ }
+ }
+ if (match.getTeamScore().getOrDefault(winningTeam, 0) >= match.getRequiredWins()) {
+ finishMatch(match, participants, arena);
+ return;
+ }
+ }
+
+ match.setState(PartyMatch.State.COUNTDOWN);
+ scheduleRoundReset(arena, () -> startNextRound(match));
+ }
+
+ private void startNextRound(PartyMatch match) {
+ Gamemode gamemode = plugin.getGamemodeManager().getById(match.getGamemodeId());
+ Arena arena = plugin.getArenaManager().getById(match.getArenaId());
+ if (gamemode == null || arena == null) {
+ return;
+ }
+ List participants = getPlayers(match.getParticipants());
+ Runnable startRound = () -> {
+ clearDroppedItems(arena);
+ prepareRound(match, arena, gamemode, participants);
+ startCountdown(match, gamemode, participants);
+ };
+ if (worldEdit.isAvailable() && plugin.getConfig().getBoolean("arena.regenerateAfterDuel", true)) {
+ Location region = arena.getCorner1() != null ? arena.getCorner1() : arena.getSpawn1();
+ if (region != null) {
+ plugin.getScheduler().runAtLocation(region, () -> {
+ worldEdit.restoreSnapshot(arena);
+ startRound.run();
+ });
+ return;
+ }
+ }
+ startRound.run();
+ }
+
+ private void finishMatch(PartyMatch match, List participants, Arena arena) {
+ match.setState(PartyMatch.State.ENDING);
+ clearMatchRuntime(match);
+ for (Player player : participants) {
+ com.starpractice.util.TablistUtil.clearHealth(player);
+ }
+ plugin.getScheduler().runLaterGlobal(100L, () -> {
+ for (Player player : participants) {
+ plugin.getHotbarManager().sendToSpawn(player);
+ }
+ if (arena == null) {
+ return;
+ }
+ if (!plugin.getConfig().getBoolean("arena.regenerateAfterDuel", true) || !worldEdit.isAvailable()) {
+ clearPlacedBlocks(arena.getId());
+ clearDroppedItems(arena);
+ arena.setInUse(false);
+ return;
+ }
+ Location region = arena.getCorner1() != null ? arena.getCorner1() : arena.getSpawn1();
+ if (region != null) {
+ plugin.getScheduler().runAtLocation(region, () -> {
+ worldEdit.restoreSnapshot(arena);
+ clearPlacedBlocks(arena.getId());
+ clearDroppedItems(arena);
+ arena.setInUse(false);
+ });
+ return;
+ }
+ clearPlacedBlocks(arena.getId());
+ clearDroppedItems(arena);
+ arena.setInUse(false);
+ });
+ }
+
+ private void scheduleRoundReset(Arena arena, Runnable afterReset) {
+ if (arena == null) {
+ plugin.getScheduler().runLaterGlobal(1L, afterReset);
+ return;
+ }
+ clearPlacedBlocks(arena.getId());
+ clearDroppedItems(arena);
+ if (worldEdit.isAvailable() && plugin.getConfig().getBoolean("arena.regenerateAfterDuel", true)) {
+ Location region = arena.getCorner1() != null ? arena.getCorner1() : arena.getSpawn1();
+ if (region != null) {
+ plugin.getScheduler().runAtLocation(region, () -> {
+ worldEdit.restoreSnapshot(arena);
+ plugin.getScheduler().runLaterGlobal(1L, afterReset);
+ });
+ return;
+ }
+ }
+ plugin.getScheduler().runLaterGlobal(1L, afterReset);
+ }
+
+ private List getPlayers(Set uuids) {
+ List players = new ArrayList<>();
+ for (UUID uuid : uuids) {
+ Player player = plugin.getServer().getPlayer(uuid);
+ if (player != null && player.isOnline()) {
+ players.add(player);
+ }
+ }
+ return players;
+ }
+
+ private void playDefeatEffects(Player loser, Arena arena, Location deathLoc) {
+ Sound sound;
+ try {
+ sound = Sound.valueOf(plugin.getConfig().getString("duel.defeatSound", "ENTITY_PLAYER_HURT"));
+ } catch (IllegalArgumentException e) {
+ sound = Sound.ENTITY_PLAYER_HURT;
+ }
+ float volume = (float) plugin.getConfig().getDouble("duel.defeatVolume", 1.0);
+ float pitch = (float) plugin.getConfig().getDouble("duel.defeatPitch", 1.0);
+ Location targetLoc = deathLoc != null ? deathLoc : (arena != null ? arena.getSpectatorSpawn() : null);
+ final Sound finalSound = sound;
+ final float finalVolume = volume;
+ final float finalPitch = pitch;
+ plugin.getScheduler().runLaterAtEntity(loser, 1L, () -> {
+ try {
+ loser.spigot().respawn();
+ } catch (Exception ignored) {
+ }
+ plugin.getScheduler().runLaterAtEntity(loser, 1L, () -> {
+ loser.setGameMode(GameMode.SPECTATOR);
+ if (targetLoc != null) {
+ loser.teleport(targetLoc);
+ }
+ loser.playSound(loser.getLocation(), finalSound, finalVolume, finalPitch);
+ plugin.getScheduler().runLaterAtEntity(loser, 1L, () -> {
+ if (loser.getGameMode() != GameMode.SPECTATOR) {
+ plugin.getHotbarManager().sendToSpawn(loser);
+ }
+ });
+ });
+ });
+ }
+
+ private void playVictorySound(Player winner) {
+ Sound victory;
+ try {
+ victory = Sound.valueOf(plugin.getConfig().getString("duel.endVictorySound", "UI_TOAST_CHALLENGE_COMPLETE"));
+ } catch (IllegalArgumentException e) {
+ victory = Sound.UI_TOAST_CHALLENGE_COMPLETE;
+ }
+ float vVolume = (float) plugin.getConfig().getDouble("duel.endVictoryVolume", 1.0);
+ float vPitch = (float) plugin.getConfig().getDouble("duel.endVictoryPitch", 1.0);
+ winner.playSound(winner.getLocation(), victory, vVolume, vPitch);
+ }
+
+ private void clearPlacedBlocks(String arenaId) {
+ if (arenaId != null) {
+ placedBlocks.remove(arenaId);
+ }
+ }
+
+ private void clearDroppedItems(Arena arena) {
+ if (arena.getCorner1() == null || arena.getCorner2() == null) {
+ return;
+ }
+ Location c1 = arena.getCorner1();
+ Location c2 = arena.getCorner2();
+ if (c1.getWorld() == null) {
+ return;
+ }
+ int minX = Math.min(c1.getBlockX(), c2.getBlockX());
+ int minY = Math.min(c1.getBlockY(), c2.getBlockY());
+ int minZ = Math.min(c1.getBlockZ(), c2.getBlockZ());
+ int maxX = Math.max(c1.getBlockX(), c2.getBlockX());
+ int maxY = Math.max(c1.getBlockY(), c2.getBlockY());
+ int maxZ = Math.max(c1.getBlockZ(), c2.getBlockZ());
+
+ org.bukkit.util.BoundingBox box = org.bukkit.util.BoundingBox.of(
+ new org.bukkit.util.Vector(minX, minY, minZ),
+ new org.bukkit.util.Vector(maxX + 1, maxY + 1, maxZ + 1)
+ );
+ for (org.bukkit.entity.Entity entity : c1.getWorld().getNearbyEntities(box)) {
+ if (entity instanceof Player) {
+ continue;
+ }
+ entity.remove();
+ }
+ }
+
+ private long blockKey(Location location) {
+ return packBlock(location.getBlockX(), location.getBlockY(), location.getBlockZ());
+ }
+
+ private long packBlock(int x, int y, int z) {
+ return ((long) (x & 0x3FFFFFF) << 38) | ((long) (z & 0x3FFFFFF) << 12) | (y & 0xFFF);
+ }
+
+ public void handleEscape(Player player, Arena arena) {
+ PartyMatch match = matches.get(player.getUniqueId());
+ if (match == null || match.getState() == PartyMatch.State.ENDING) {
+ return;
+ }
+ String msg = Text.color("&7&o" + player.getName() + " tried to escape the map");
+ for (UUID uuid : match.getParticipants()) {
+ Player target = plugin.getServer().getPlayer(uuid);
+ if (target != null && target.isOnline()) {
+ target.sendMessage(msg);
+ }
+ }
+ plugin.getScheduler().runAtEntity(player, () -> player.setHealth(0.0));
+ }
+
+ private void scheduleHealthUpdate(String arenaId) {
+ if (arenaId == null || !healthDisplays.contains(arenaId) || !activeHealthLoops.add(arenaId)) {
+ return;
+ }
+ runHealthUpdateTick(arenaId);
+ }
+
+ private void runHealthUpdateTick(String arenaId) {
+ if (arenaId == null || !healthDisplays.contains(arenaId)) {
+ activeHealthLoops.remove(arenaId);
+ return;
+ }
+ PartyMatch match = getMatchByArena(arenaId);
+ if (match == null || match.getState() == PartyMatch.State.ENDING) {
+ healthDisplays.remove(arenaId);
+ activeHealthLoops.remove(arenaId);
+ return;
+ }
+ List participants = getPlayers(match.getParticipants());
+ if (participants.isEmpty()) {
+ healthDisplays.remove(arenaId);
+ activeHealthLoops.remove(arenaId);
+ return;
+ }
+ for (Player viewer : participants) {
+ com.starpractice.util.TablistUtil.updateHealth(viewer, participants);
+ }
+ plugin.getScheduler().runLaterGlobal(10L, () -> runHealthUpdateTick(arenaId));
+ }
+
+ private PartyMatch getMatchByArena(String arenaId) {
+ if (arenaId == null) {
+ return null;
+ }
+ for (PartyMatch match : new HashSet<>(matches.values())) {
+ if (arenaId.equals(match.getArenaId())) {
+ return match;
+ }
+ }
+ return null;
+ }
+
+ private void clearMatchRuntime(PartyMatch match) {
+ if (match == null) {
+ return;
+ }
+ String arenaId = match.getArenaId();
+ if (arenaId != null) {
+ healthDisplays.remove(arenaId);
+ activeHealthLoops.remove(arenaId);
+ clearPlacedBlocks(arenaId);
+ }
+ for (UUID uuid : new HashSet<>(match.getParticipants())) {
+ matches.remove(uuid);
+ frozen.remove(uuid);
+ }
+ match.getParticipants().clear();
+ match.getAlive().clear();
+ match.getTeam().clear();
+ match.getPlayerScore().clear();
+ match.getTeamScore().clear();
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/PlayerKitManager.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/PlayerKitManager.java
new file mode 100644
index 0000000..63a6553
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/PlayerKitManager.java
@@ -0,0 +1,79 @@
+package com.starpractice.manager;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.Gamemode;
+import com.starpractice.model.Kit;
+import com.starpractice.model.PlayerKitData;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import org.bukkit.entity.Player;
+
+public class PlayerKitManager {
+ private final StarPracticePlugin plugin;
+ private final Map> data = new HashMap<>();
+
+ public PlayerKitManager(StarPracticePlugin plugin) {
+ this.plugin = plugin;
+ }
+
+ public void load(Map> loaded) {
+ data.clear();
+ if (loaded != null) {
+ data.putAll(loaded);
+ }
+ }
+
+ public Map> exportData() {
+ return new HashMap<>(data);
+ }
+
+ public int getSelectedSlot(UUID uuid, String gamemodeId) {
+ PlayerKitData kitData = getOrCreate(uuid, gamemodeId);
+ return kitData.getSelectedSlot();
+ }
+
+ public void setSelectedSlot(UUID uuid, String gamemodeId, int slot) {
+ PlayerKitData kitData = getOrCreate(uuid, gamemodeId);
+ kitData.setSelectedSlot(slot);
+ save();
+ }
+
+ public Kit getLoadout(UUID uuid, String gamemodeId, int slot) {
+ PlayerKitData kitData = getOrCreate(uuid, gamemodeId);
+ return kitData.getLoadout(slot);
+ }
+
+ public void setLoadout(UUID uuid, String gamemodeId, int slot, Kit kit) {
+ PlayerKitData kitData = getOrCreate(uuid, gamemodeId);
+ kitData.setLoadout(slot, kit);
+ save();
+ }
+
+ public Kit resolveKit(Player player, Gamemode gamemode) {
+ if (player == null || gamemode == null) {
+ return gamemode != null ? gamemode.getKit() : null;
+ }
+ PlayerKitData kitData = getOrCreate(player.getUniqueId(), gamemode.getId());
+ Kit loadout = kitData.getLoadout(kitData.getSelectedSlot());
+ return loadout != null ? loadout : gamemode.getKit();
+ }
+
+ public Kit createDefaultLoadout(Gamemode gamemode) {
+ if (gamemode == null || gamemode.getKit() == null) {
+ return new Kit(new org.bukkit.inventory.ItemStack[36], new org.bukkit.inventory.ItemStack[4], null, new java.util.ArrayList<>());
+ }
+ return gamemode.getKit().copy();
+ }
+
+ private PlayerKitData getOrCreate(UUID uuid, String gamemodeId) {
+ Map perMode = data.computeIfAbsent(uuid, key -> new HashMap<>());
+ return perMode.computeIfAbsent(gamemodeId, key -> new PlayerKitData());
+ }
+
+ private void save() {
+ if (plugin.getStorageManager() != null) {
+ plugin.getStorageManager().savePlayerKits(exportData());
+ }
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/QueueManager.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/QueueManager.java
new file mode 100644
index 0000000..d99103f
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/QueueManager.java
@@ -0,0 +1,137 @@
+package com.starpractice.manager;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.Arena;
+import com.starpractice.model.Gamemode;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import org.bukkit.entity.Player;
+
+public class QueueManager {
+ private final StarPracticePlugin plugin;
+ private final Map> queues = new HashMap<>();
+ private final Map queuedPlayers = new HashMap<>();
+ private final Set actionbarQueued = new java.util.HashSet<>();
+
+ public QueueManager(StarPracticePlugin plugin) {
+ this.plugin = plugin;
+ }
+
+ public boolean isQueued(Player player) {
+ return queuedPlayers.containsKey(player.getUniqueId());
+ }
+
+ public int getQueueSize(String gamemodeId) {
+ Deque queue = queues.get(gamemodeId);
+ return queue == null ? 0 : queue.size();
+ }
+
+ public void joinQueue(Player player, Gamemode gamemode) {
+ if (!gamemode.isEnabled()) {
+ plugin.sendMessage(player, "&cThat gamemode is disabled.");
+ return;
+ }
+ if (isQueued(player)) {
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.already-queued"));
+ return;
+ }
+ if (plugin.getConfig().getBoolean("features.parties.enabled", true)
+ && plugin.getPartyManager().getParty(player.getUniqueId()) != null) {
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.party-queue-block", "&cYou cannot queue while in a party."));
+ return;
+ }
+ if (plugin.getMatchManager().isInMatch(player) || plugin.getSpectateManager().isSpectating(player)) {
+ plugin.sendMessage(player, "&cYou cannot queue right now.");
+ return;
+ }
+ queues.computeIfAbsent(gamemode.getId(), k -> new ArrayDeque<>()).add(player.getUniqueId());
+ queuedPlayers.put(player.getUniqueId(), gamemode.getId());
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.queued").replace("%mode%", gamemode.getDisplayName()));
+ startActionbar(player, gamemode.getDisplayName());
+ tryMatch(gamemode);
+ }
+
+ public void leaveQueue(Player player) {
+ String modeId = queuedPlayers.remove(player.getUniqueId());
+ if (modeId == null) {
+ return;
+ }
+ stopActionbar(player.getUniqueId());
+ Deque queue = queues.get(modeId);
+ if (queue != null) {
+ queue.remove(player.getUniqueId());
+ }
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.left-queue"));
+ }
+
+ public void tryMatch(Gamemode gamemode) {
+ Deque queue = queues.get(gamemode.getId());
+ if (queue == null || queue.size() < 2) {
+ return;
+ }
+ UUID p1Id = queue.poll();
+ UUID p2Id = queue.poll();
+ if (p1Id == null || p2Id == null) {
+ return;
+ }
+ queuedPlayers.remove(p1Id);
+ queuedPlayers.remove(p2Id);
+ stopActionbar(p1Id);
+ stopActionbar(p2Id);
+
+ Player p1 = plugin.getServer().getPlayer(p1Id);
+ Player p2 = plugin.getServer().getPlayer(p2Id);
+ if (p1 == null || p2 == null) {
+ return;
+ }
+
+ Arena arena = plugin.getArenaManager().findAvailableArena(gamemode);
+ if (arena == null) {
+ plugin.sendMessage(p1, plugin.getConfig().getString("messages.no-arenas"));
+ plugin.sendMessage(p2, plugin.getConfig().getString("messages.no-arenas"));
+ return;
+ }
+
+ plugin.getMatchManager().startSeries(gamemode, arena, p1, p2, 1, true);
+ }
+
+ public void removePlayer(UUID uuid) {
+ String modeId = queuedPlayers.remove(uuid);
+ if (modeId == null) {
+ return;
+ }
+ stopActionbar(uuid);
+ Deque queue = queues.get(modeId);
+ if (queue != null) {
+ queue.remove(uuid);
+ }
+ }
+
+ private void startActionbar(Player player, String modeName) {
+ UUID uuid = player.getUniqueId();
+ actionbarQueued.add(uuid);
+ sendActionbar(player, modeName);
+ }
+
+ private void sendActionbar(Player player, String modeName) {
+ if (!actionbarQueued.contains(player.getUniqueId())) {
+ return;
+ }
+ String msg = "&fIn queue for &6" + modeName + "&f, to leave queue type &c/leave";
+ player.spigot().sendMessage(net.md_5.bungee.api.ChatMessageType.ACTION_BAR,
+ new net.md_5.bungee.api.chat.TextComponent(com.starpractice.util.Text.color(msg)));
+ plugin.getScheduler().runLaterAtEntity(player, 40L, () -> {
+ if (player.isOnline() && actionbarQueued.contains(player.getUniqueId())) {
+ sendActionbar(player, modeName);
+ }
+ });
+ }
+
+ private void stopActionbar(UUID uuid) {
+ actionbarQueued.remove(uuid);
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/SettingsManager.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/SettingsManager.java
new file mode 100644
index 0000000..58183d6
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/SettingsManager.java
@@ -0,0 +1,70 @@
+package com.starpractice.manager;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.PlayerSettings;
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.configuration.file.YamlConfiguration;
+
+public class SettingsManager {
+ private final StarPracticePlugin plugin;
+ private final Map settings = new HashMap<>();
+ private final File file;
+
+ public SettingsManager(StarPracticePlugin plugin) {
+ this.plugin = plugin;
+ this.file = new File(plugin.getDataFolder(), "player-settings.yml");
+ }
+
+ public void load() {
+ if (!file.exists()) {
+ return;
+ }
+ FileConfiguration config = YamlConfiguration.loadConfiguration(file);
+ if (!config.isConfigurationSection("players")) {
+ return;
+ }
+ for (String key : config.getConfigurationSection("players").getKeys(false)) {
+ UUID uuid;
+ try {
+ uuid = UUID.fromString(key);
+ } catch (IllegalArgumentException e) {
+ continue;
+ }
+ boolean duelRequests = config.getBoolean("players." + key + ".duelRequests", true);
+ boolean partyInvites = config.getBoolean("players." + key + ".partyInvites", true);
+ boolean friendRequests = config.getBoolean("players." + key + ".friendRequests",
+ config.getBoolean("players." + key + ".publicStats", true));
+ settings.put(uuid, new PlayerSettings(duelRequests, partyInvites, friendRequests));
+ }
+ }
+
+ public void save() {
+ FileConfiguration config = new YamlConfiguration();
+ for (Map.Entry entry : settings.entrySet()) {
+ String key = entry.getKey().toString();
+ PlayerSettings ps = entry.getValue();
+ config.set("players." + key + ".duelRequests", ps.isDuelRequests());
+ config.set("players." + key + ".partyInvites", ps.isPartyInvites());
+ config.set("players." + key + ".friendRequests", ps.isFriendRequests());
+ }
+ try {
+ config.save(file);
+ } catch (IOException e) {
+ plugin.getLogger().warning("Failed to save player-settings.yml: " + e.getMessage());
+ }
+ }
+
+ public PlayerSettings getSettings(UUID uuid) {
+ return settings.computeIfAbsent(uuid, key -> new PlayerSettings(true, true, true));
+ }
+
+ public void update(UUID uuid, PlayerSettings playerSettings) {
+ settings.put(uuid, playerSettings);
+ save();
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/SpectateManager.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/SpectateManager.java
new file mode 100644
index 0000000..c124415
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/SpectateManager.java
@@ -0,0 +1,177 @@
+package com.starpractice.manager;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.Arena;
+import com.starpractice.model.DuelMatch;
+import com.starpractice.util.TablistUtil;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import org.bukkit.GameMode;
+import org.bukkit.entity.Player;
+
+public class SpectateManager {
+ private final StarPracticePlugin plugin;
+ private final Map previousMode = new HashMap<>();
+ private final Map spectatorArena = new HashMap<>();
+
+ public SpectateManager(StarPracticePlugin plugin) {
+ this.plugin = plugin;
+ }
+
+ public boolean isSpectating(Player player) {
+ return previousMode.containsKey(player.getUniqueId());
+ }
+
+ public void spectate(Player spectator, Player target) {
+ DuelMatch match = plugin.getMatchManager().getMatch(target);
+ if (match == null) {
+ plugin.sendMessage(spectator, "&cThat player is not in a duel.");
+ return;
+ }
+ Arena arena = plugin.getArenaManager().getById(match.getArenaId());
+ if (arena == null || arena.getSpectatorSpawn() == null) {
+ plugin.sendMessage(spectator, "&cSpectator spawn not set.");
+ return;
+ }
+ previousMode.put(spectator.getUniqueId(), spectator.getGameMode());
+ spectatorArena.put(spectator.getUniqueId(), arena.getId());
+ plugin.getScheduler().runAtEntity(spectator, () -> {
+ spectator.getInventory().clear();
+ spectator.getInventory().setArmorContents(new org.bukkit.inventory.ItemStack[4]);
+ spectator.getInventory().setItemInOffHand(new org.bukkit.inventory.ItemStack(org.bukkit.Material.AIR));
+ spectator.teleport(arena.getSpectatorSpawn());
+ spectator.setGameMode(GameMode.SPECTATOR);
+ plugin.getScheduler().runLaterAtEntity(spectator, 1L, () -> {
+ if (!isSpectating(spectator)) {
+ return;
+ }
+ if (spectator.getGameMode() != GameMode.SPECTATOR) {
+ previousMode.remove(spectator.getUniqueId());
+ spectatorArena.remove(spectator.getUniqueId());
+ spectator.setGameMode(GameMode.SURVIVAL);
+ spectator.setFlying(false);
+ spectator.setAllowFlight(false);
+ showToAll(spectator);
+ plugin.sendMessage(spectator, "&cYou cannot spectate the match.");
+ plugin.getHotbarManager().sendToSpawn(spectator);
+ return;
+ }
+ plugin.getMatchManager().refreshVisibilityForArena(arena.getId());
+ broadcastSpectateAlert(arena.getId(), "&7&o" + spectator.getName() + " has started spectating");
+ String msg = plugin.getConfig().getString("messages.spectate-start", "&aNow spectating &f%target%&a.");
+ plugin.sendMessage(spectator, msg.replace("%target%", target.getName()));
+ TablistUtil.enablePrivateTablist(spectator);
+ });
+ });
+ }
+
+ public void leave(Player player) {
+ GameMode prev = previousMode.remove(player.getUniqueId());
+ String arenaId = spectatorArena.remove(player.getUniqueId());
+ if (prev == null) {
+ return;
+ }
+ plugin.getScheduler().runAtEntity(player, () -> {
+ player.setGameMode(GameMode.SURVIVAL);
+ player.setFlying(false);
+ player.setAllowFlight(false);
+ plugin.getHotbarManager().sendToSpawn(player);
+ });
+ showToAll(player);
+ plugin.getMatchManager().refreshVisibilityForArena(arenaId);
+ if (arenaId != null) {
+ broadcastSpectateAlert(arenaId, "&7&o" + player.getName() + " has stopped spectating");
+ }
+ plugin.sendMessage(player, plugin.getConfig().getString("messages.spectate-end"));
+ TablistUtil.disablePrivateTablist(player);
+ }
+
+ public void endSpectatorsForArena(String arenaId) {
+ if (arenaId == null) {
+ return;
+ }
+ for (Map.Entry entry : new HashMap<>(spectatorArena).entrySet()) {
+ if (!arenaId.equals(entry.getValue())) {
+ continue;
+ }
+ Player player = plugin.getServer().getPlayer(entry.getKey());
+ if (player != null) {
+ leave(player);
+ } else {
+ previousMode.remove(entry.getKey());
+ spectatorArena.remove(entry.getKey());
+ }
+ }
+ }
+
+ public List getSpectatorsForArena(String arenaId) {
+ List players = new ArrayList<>();
+ if (arenaId == null) {
+ return players;
+ }
+ for (Map.Entry entry : spectatorArena.entrySet()) {
+ if (!arenaId.equals(entry.getValue())) {
+ continue;
+ }
+ Player player = plugin.getServer().getPlayer(entry.getKey());
+ if (player != null && player.isOnline()) {
+ players.add(player);
+ }
+ }
+ return players;
+ }
+
+ public boolean isLegacySpectator(Player player) {
+ return false;
+ }
+
+ public void clearRuntimeState(UUID playerId) {
+ if (playerId == null) {
+ return;
+ }
+ previousMode.remove(playerId);
+ spectatorArena.remove(playerId);
+ }
+
+ public org.bukkit.Location getSpectatorSpawn(Player player) {
+ String arenaId = spectatorArena.get(player.getUniqueId());
+ if (arenaId == null) {
+ return null;
+ }
+ Arena arena = plugin.getArenaManager().getById(arenaId);
+ return arena != null ? arena.getSpectatorSpawn() : null;
+ }
+
+ public String getSpectatorArenaId(Player player) {
+ return spectatorArena.get(player.getUniqueId());
+ }
+
+ private void showToAll(Player spectator) {
+ for (Player online : plugin.getServer().getOnlinePlayers()) {
+ online.showPlayer(plugin, spectator);
+ }
+ TablistUtil.disablePrivateTablist(spectator);
+ }
+
+ private void broadcastSpectateAlert(String arenaId, String message) {
+ DuelMatch match = plugin.getMatchManager().getMatchByArena(arenaId);
+ Set recipients = new HashSet<>();
+ if (match != null) {
+ recipients.add(match.getPlayer1());
+ recipients.add(match.getPlayer2());
+ }
+ for (Player spectator : getSpectatorsForArena(arenaId)) {
+ recipients.add(spectator.getUniqueId());
+ }
+ String colored = com.starpractice.util.Text.color(message);
+ for (UUID uuid : recipients) {
+ Player player = plugin.getServer().getPlayer(uuid);
+ if (player != null && player.isOnline()) {
+ player.sendMessage(colored);
+ }
+ }
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/StorageManager.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/StorageManager.java
new file mode 100644
index 0000000..08d404c
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/manager/StorageManager.java
@@ -0,0 +1,62 @@
+package com.starpractice.manager;
+
+import com.starpractice.StarPracticePlugin;
+import com.starpractice.model.Arena;
+import com.starpractice.model.Gamemode;
+import com.starpractice.model.SpawnData;
+import com.starpractice.storage.SocialStorage;
+import com.starpractice.storage.Storage;
+import java.util.List;
+
+public class StorageManager {
+ private final StarPracticePlugin plugin;
+ private final Storage storage;
+ private final SocialStorage socialStorage;
+
+ public StorageManager(StarPracticePlugin plugin, Storage storage, SocialStorage socialStorage) {
+ this.plugin = plugin;
+ this.storage = storage;
+ this.socialStorage = socialStorage;
+ }
+
+ public void loadAll() {
+ List gamemodes = storage.loadGamemodes();
+ List arenas = storage.loadArenas();
+ SpawnData spawn = storage.loadSpawn();
+ java.util.Map> friends = socialStorage.loadFriends();
+ java.util.Map> playerKits = storage.loadPlayerKits();
+
+ plugin.getGamemodeManager().load(gamemodes);
+ plugin.getArenaManager().load(arenas);
+ plugin.getHotbarManager().setSpawnData(spawn);
+ plugin.getFriendManager().load(friends);
+ plugin.getPlayerKitManager().load(playerKits);
+ }
+
+ public void saveAll() {
+ saveGamemodes();
+ saveArenas();
+ saveSpawn();
+ saveFriends(plugin.getFriendManager().exportData());
+ }
+
+ public void saveGamemodes() {
+ storage.saveGamemodes(plugin.getGamemodeManager().getAll());
+ }
+
+ public void saveArenas() {
+ storage.saveArenas(plugin.getArenaManager().getAll());
+ }
+
+ public void saveSpawn() {
+ storage.saveSpawn(plugin.getHotbarManager().getSpawnData());
+ }
+
+ public void saveFriends(java.util.Map> friends) {
+ socialStorage.saveFriends(friends);
+ }
+
+ public void savePlayerKits(java.util.Map> data) {
+ storage.savePlayerKits(data);
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/model/Arena.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/model/Arena.java
new file mode 100644
index 0000000..71e5d76
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/model/Arena.java
@@ -0,0 +1,200 @@
+package com.starpractice.model;
+
+import com.starpractice.util.LocationUtil;
+import java.util.HashMap;
+import java.util.Map;
+import org.bukkit.Location;
+import org.bukkit.inventory.ItemStack;
+
+public class Arena {
+ private final String id;
+ private String displayName;
+ private boolean enabled;
+ private String world;
+ private Location corner1;
+ private Location corner2;
+ private Location spawn1;
+ private Location spawn2;
+ private Location spectatorSpawn;
+ private Location centerSpawn;
+ private String snapshotPath;
+ private boolean inUse;
+ private ItemStack iconItem;
+
+ public Arena(String id) {
+ this.id = id;
+ this.displayName = id;
+ this.enabled = false;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ public void setDisplayName(String displayName) {
+ this.displayName = displayName;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public String getWorldName() {
+ return world;
+ }
+
+ public void setWorldName(String world) {
+ this.world = world;
+ }
+
+ public Location getCorner1() {
+ return corner1;
+ }
+
+ public void setCorner1(Location corner1) {
+ this.corner1 = corner1;
+ if (corner1 != null && corner1.getWorld() != null) {
+ this.world = corner1.getWorld().getName();
+ }
+ }
+
+ public Location getCorner2() {
+ return corner2;
+ }
+
+ public void setCorner2(Location corner2) {
+ this.corner2 = corner2;
+ if (corner2 != null && corner2.getWorld() != null) {
+ this.world = corner2.getWorld().getName();
+ }
+ }
+
+ public Location getSpawn1() {
+ return spawn1;
+ }
+
+ public void setSpawn1(Location spawn1) {
+ this.spawn1 = spawn1;
+ if (spawn1 != null && spawn1.getWorld() != null) {
+ this.world = spawn1.getWorld().getName();
+ }
+ }
+
+ public Location getSpawn2() {
+ return spawn2;
+ }
+
+ public void setSpawn2(Location spawn2) {
+ this.spawn2 = spawn2;
+ if (spawn2 != null && spawn2.getWorld() != null) {
+ this.world = spawn2.getWorld().getName();
+ }
+ }
+
+ public Location getSpectatorSpawn() {
+ return spectatorSpawn;
+ }
+
+ public void setSpectatorSpawn(Location spectatorSpawn) {
+ this.spectatorSpawn = spectatorSpawn;
+ if (spectatorSpawn != null && spectatorSpawn.getWorld() != null) {
+ this.world = spectatorSpawn.getWorld().getName();
+ }
+ }
+
+ public Location getCenterSpawn() {
+ return centerSpawn;
+ }
+
+ public void setCenterSpawn(Location centerSpawn) {
+ this.centerSpawn = centerSpawn;
+ if (centerSpawn != null && centerSpawn.getWorld() != null) {
+ this.world = centerSpawn.getWorld().getName();
+ }
+ }
+
+ public String getSnapshotPath() {
+ return snapshotPath;
+ }
+
+ public void setSnapshotPath(String snapshotPath) {
+ this.snapshotPath = snapshotPath;
+ }
+
+ public boolean isInUse() {
+ return inUse;
+ }
+
+ public void setInUse(boolean inUse) {
+ this.inUse = inUse;
+ }
+
+ public ItemStack getIconItem() {
+ if (iconItem != null) {
+ return iconItem.clone();
+ }
+ return new ItemStack(org.bukkit.Material.GRASS_BLOCK);
+ }
+
+ public void setIconItem(ItemStack iconItem) {
+ this.iconItem = iconItem == null ? null : iconItem.clone();
+ }
+
+ public Map toMap() {
+ Map map = new HashMap<>();
+ map.put("id", id);
+ map.put("displayName", displayName);
+ map.put("enabled", enabled);
+ map.put("world", world);
+ map.put("corner1", LocationUtil.toMap(corner1));
+ map.put("corner2", LocationUtil.toMap(corner2));
+ map.put("spawn1", LocationUtil.toMap(spawn1));
+ map.put("spawn2", LocationUtil.toMap(spawn2));
+ map.put("spectatorSpawn", LocationUtil.toMap(spectatorSpawn));
+ map.put("centerSpawn", LocationUtil.toMap(centerSpawn));
+ map.put("snapshotPath", snapshotPath);
+ map.put("iconItem", iconItem);
+ return map;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static Arena fromMap(Map map) {
+ String id = String.valueOf(map.get("id"));
+ Arena arena = new Arena(id);
+ arena.displayName = String.valueOf(map.getOrDefault("displayName", id));
+ arena.enabled = Boolean.parseBoolean(String.valueOf(map.getOrDefault("enabled", false)));
+ arena.world = String.valueOf(map.getOrDefault("world", ""));
+ arena.corner1 = LocationUtil.fromMap(readSection(map.get("corner1")));
+ arena.corner2 = LocationUtil.fromMap(readSection(map.get("corner2")));
+ arena.spawn1 = LocationUtil.fromMap(readSection(map.get("spawn1")));
+ arena.spawn2 = LocationUtil.fromMap(readSection(map.get("spawn2")));
+ arena.spectatorSpawn = LocationUtil.fromMap(readSection(map.get("spectatorSpawn")));
+ arena.centerSpawn = LocationUtil.fromMap(readSection(map.get("centerSpawn")));
+ arena.snapshotPath = (String) map.getOrDefault("snapshotPath", "");
+ Object iconObj = map.get("iconItem");
+ if (iconObj instanceof ItemStack stack) {
+ arena.iconItem = stack.clone();
+ }
+ arena.inUse = false;
+ return arena;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static Map readSection(Object value) {
+ if (value instanceof Map) {
+ return (Map) value;
+ }
+ if (value instanceof org.bukkit.configuration.ConfigurationSection section) {
+ return section.getValues(false);
+ }
+ return null;
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/model/DuelMatch.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/model/DuelMatch.java
new file mode 100644
index 0000000..bdc1a4b
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/model/DuelMatch.java
@@ -0,0 +1,100 @@
+package com.starpractice.model;
+
+import java.util.UUID;
+
+public class DuelMatch {
+ public enum State {
+ COUNTDOWN,
+ ACTIVE,
+ ENDING
+ }
+
+ private final UUID player1;
+ private final UUID player2;
+ private final String arenaId;
+ private final String gamemodeId;
+ private State state;
+ private final int totalRounds;
+ private final int requiredWins;
+ private int redScore;
+ private int blueScore;
+ private final UUID redPlayer;
+ private final UUID bluePlayer;
+
+ public DuelMatch(UUID player1, UUID player2, String arenaId, String gamemodeId, int totalRounds) {
+ this.player1 = player1;
+ this.player2 = player2;
+ this.arenaId = arenaId;
+ this.gamemodeId = gamemodeId;
+ this.state = State.COUNTDOWN;
+ this.totalRounds = totalRounds;
+ this.requiredWins = totalRounds / 2 + 1;
+ if (Math.random() < 0.5) {
+ this.redPlayer = player1;
+ this.bluePlayer = player2;
+ } else {
+ this.redPlayer = player2;
+ this.bluePlayer = player1;
+ }
+ }
+
+ public UUID getPlayer1() {
+ return player1;
+ }
+
+ public UUID getPlayer2() {
+ return player2;
+ }
+
+ public String getArenaId() {
+ return arenaId;
+ }
+
+ public String getGamemodeId() {
+ return gamemodeId;
+ }
+
+ public State getState() {
+ return state;
+ }
+
+ public void setState(State state) {
+ this.state = state;
+ }
+
+ public int getTotalRounds() {
+ return totalRounds;
+ }
+
+ public int getRequiredWins() {
+ return requiredWins;
+ }
+
+ public int getRedScore() {
+ return redScore;
+ }
+
+ public int getBlueScore() {
+ return blueScore;
+ }
+
+ public void incrementRedScore() {
+ this.redScore += 1;
+ }
+
+ public void incrementBlueScore() {
+ this.blueScore += 1;
+ }
+
+ public UUID getRedPlayer() {
+ return redPlayer;
+ }
+
+ public UUID getBluePlayer() {
+ return bluePlayer;
+ }
+
+ public boolean isRed(UUID uuid) {
+ return redPlayer.equals(uuid);
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/model/DuelRequest.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/model/DuelRequest.java
new file mode 100644
index 0000000..e0ef59b
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/model/DuelRequest.java
@@ -0,0 +1,45 @@
+package com.starpractice.model;
+
+import java.util.UUID;
+
+public class DuelRequest {
+ private final UUID requester;
+ private final UUID target;
+ private final String gamemodeId;
+ private final int totalRounds;
+ private final int requiredWins;
+ private final long createdAt;
+
+ public DuelRequest(UUID requester, UUID target, String gamemodeId, int totalRounds, long createdAt) {
+ this.requester = requester;
+ this.target = target;
+ this.gamemodeId = gamemodeId;
+ this.totalRounds = totalRounds;
+ this.requiredWins = totalRounds / 2 + 1;
+ this.createdAt = createdAt;
+ }
+
+ public UUID getRequester() {
+ return requester;
+ }
+
+ public UUID getTarget() {
+ return target;
+ }
+
+ public String getGamemodeId() {
+ return gamemodeId;
+ }
+
+ public int getTotalRounds() {
+ return totalRounds;
+ }
+
+ public int getRequiredWins() {
+ return requiredWins;
+ }
+
+ public long getCreatedAt() {
+ return createdAt;
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/model/FriendRequest.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/model/FriendRequest.java
new file mode 100644
index 0000000..ce1179e
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/model/FriendRequest.java
@@ -0,0 +1,27 @@
+package com.starpractice.model;
+
+import java.util.UUID;
+
+public class FriendRequest {
+ private final UUID requester;
+ private final UUID target;
+ private final long createdAt;
+
+ public FriendRequest(UUID requester, UUID target, long createdAt) {
+ this.requester = requester;
+ this.target = target;
+ this.createdAt = createdAt;
+ }
+
+ public UUID getRequester() {
+ return requester;
+ }
+
+ public UUID getTarget() {
+ return target;
+ }
+
+ public long getCreatedAt() {
+ return createdAt;
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/model/Gamemode.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/model/Gamemode.java
new file mode 100644
index 0000000..6c795cf
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/model/Gamemode.java
@@ -0,0 +1,299 @@
+package com.starpractice.model;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.LinkedHashMap;
+import org.bukkit.potion.PotionEffectType;
+import org.bukkit.Material;
+import org.bukkit.inventory.ItemStack;
+
+public class Gamemode {
+ private final String id;
+ private String displayName;
+ private boolean enabled;
+ private Material iconMaterial;
+ private int customModelData;
+ private ItemStack iconItem;
+ private Kit kit;
+ private final Set allowedArenas;
+ private boolean fullSaturation;
+ private boolean prepotEnabled;
+ private final Map prepotEffects;
+ private boolean blockBreak;
+ private boolean blockPlace;
+ private boolean naturalRegen;
+ private boolean onlyBreakPlaced;
+ private boolean lootDrops;
+ private boolean healthDisplay;
+
+ public Gamemode(String id) {
+ this.id = id;
+ this.displayName = id;
+ this.enabled = true;
+ this.iconMaterial = Material.IRON_SWORD;
+ this.customModelData = -1;
+ this.iconItem = null;
+ this.kit = new Kit(new org.bukkit.inventory.ItemStack[36], new org.bukkit.inventory.ItemStack[4], null, new ArrayList<>());
+ this.allowedArenas = new HashSet<>();
+ this.fullSaturation = false;
+ this.prepotEnabled = false;
+ this.prepotEffects = new LinkedHashMap<>();
+ this.blockBreak = false;
+ this.blockPlace = true;
+ this.naturalRegen = true;
+ this.onlyBreakPlaced = true;
+ this.lootDrops = false;
+ this.healthDisplay = false;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ public void setDisplayName(String displayName) {
+ this.displayName = displayName;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public Material getIconMaterial() {
+ return iconMaterial;
+ }
+
+ public void setIconMaterial(Material iconMaterial) {
+ this.iconMaterial = iconMaterial;
+ }
+
+ public ItemStack getIconItem() {
+ if (iconItem != null) {
+ return iconItem.clone();
+ }
+ ItemStack item = new ItemStack(iconMaterial);
+ if (customModelData >= 0) {
+ org.bukkit.inventory.meta.ItemMeta meta = item.getItemMeta();
+ if (meta != null) {
+ meta.setCustomModelData(customModelData);
+ item.setItemMeta(meta);
+ }
+ }
+ return item;
+ }
+
+ public void setIconItem(ItemStack iconItem) {
+ this.iconItem = iconItem == null ? null : iconItem.clone();
+ if (this.iconItem != null) {
+ this.iconMaterial = this.iconItem.getType();
+ org.bukkit.inventory.meta.ItemMeta meta = this.iconItem.getItemMeta();
+ if (meta != null && meta.hasCustomModelData()) {
+ this.customModelData = meta.getCustomModelData();
+ } else {
+ this.customModelData = -1;
+ }
+ }
+ }
+
+ public int getCustomModelData() {
+ return customModelData;
+ }
+
+ public void setCustomModelData(int customModelData) {
+ this.customModelData = customModelData;
+ }
+
+ public Kit getKit() {
+ return kit;
+ }
+
+ public void setKit(Kit kit) {
+ this.kit = kit;
+ }
+
+ public Set getAllowedArenas() {
+ return allowedArenas;
+ }
+
+ public boolean isFullSaturation() {
+ return fullSaturation;
+ }
+
+ public void setFullSaturation(boolean fullSaturation) {
+ this.fullSaturation = fullSaturation;
+ }
+
+ public boolean isPrepotEnabled() {
+ return prepotEnabled;
+ }
+
+ public void setPrepotEnabled(boolean prepotEnabled) {
+ this.prepotEnabled = prepotEnabled;
+ }
+
+ public PrepotData getPrepotData(PotionEffectType type) {
+ String key = type.getKey().getKey();
+ PrepotData data = prepotEffects.get(key);
+ if (data == null) {
+ data = new PrepotData();
+ prepotEffects.put(key, data);
+ }
+ return data;
+ }
+
+ public Map getPrepotEffects() {
+ return prepotEffects;
+ }
+
+ public boolean isBlockBreak() {
+ return blockBreak;
+ }
+
+ public void setBlockBreak(boolean blockBreak) {
+ this.blockBreak = blockBreak;
+ }
+
+ public boolean isBlockPlace() {
+ return blockPlace;
+ }
+
+ public void setBlockPlace(boolean blockPlace) {
+ this.blockPlace = blockPlace;
+ }
+
+ public boolean isNaturalRegen() {
+ return naturalRegen;
+ }
+
+ public void setNaturalRegen(boolean naturalRegen) {
+ this.naturalRegen = naturalRegen;
+ }
+
+ public boolean isOnlyBreakPlaced() {
+ return onlyBreakPlaced;
+ }
+
+ public void setOnlyBreakPlaced(boolean onlyBreakPlaced) {
+ this.onlyBreakPlaced = onlyBreakPlaced;
+ if (onlyBreakPlaced) {
+ this.blockBreak = false;
+ }
+ }
+
+ public boolean isLootDrops() {
+ return lootDrops;
+ }
+
+ public void setLootDrops(boolean lootDrops) {
+ this.lootDrops = lootDrops;
+ }
+
+ public boolean isHealthDisplay() {
+ return healthDisplay;
+ }
+
+ public void setHealthDisplay(boolean healthDisplay) {
+ this.healthDisplay = healthDisplay;
+ }
+
+
+ public Map toMap() {
+ Map map = new HashMap<>();
+ map.put("id", id);
+ map.put("displayName", displayName);
+ map.put("enabled", enabled);
+ map.put("iconMaterial", iconMaterial.name());
+ map.put("customModelData", customModelData);
+ map.put("iconItem", iconItem);
+ map.put("kit", kit.toMap());
+ map.put("allowedArenas", new ArrayList<>(allowedArenas));
+ map.put("fullSaturation", fullSaturation);
+ map.put("prepotEnabled", prepotEnabled);
+ map.put("blockBreak", blockBreak);
+ map.put("blockPlace", blockPlace);
+ map.put("naturalRegen", naturalRegen);
+ map.put("onlyBreakPlaced", onlyBreakPlaced);
+ map.put("lootDrops", lootDrops);
+ map.put("healthDisplay", healthDisplay);
+ Map prepotMap = new HashMap<>();
+ for (Map.Entry entry : prepotEffects.entrySet()) {
+ prepotMap.put(entry.getKey(), entry.getValue().toMap());
+ }
+ map.put("prepotEffects", prepotMap);
+ return map;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static Gamemode fromMap(Map map) {
+ String id = String.valueOf(map.get("id"));
+ Gamemode mode = new Gamemode(id);
+ mode.displayName = String.valueOf(map.getOrDefault("displayName", id));
+ mode.enabled = Boolean.parseBoolean(String.valueOf(map.getOrDefault("enabled", true)));
+ try {
+ mode.iconMaterial = Material.valueOf(String.valueOf(map.getOrDefault("iconMaterial", "IRON_SWORD")));
+ } catch (IllegalArgumentException e) {
+ mode.iconMaterial = Material.IRON_SWORD;
+ }
+ mode.customModelData = ((Number) map.getOrDefault("customModelData", -1)).intValue();
+ Object iconObj = map.get("iconItem");
+ if (iconObj instanceof ItemStack stack) {
+ mode.iconItem = stack.clone();
+ mode.iconMaterial = mode.iconItem.getType();
+ org.bukkit.inventory.meta.ItemMeta meta = mode.iconItem.getItemMeta();
+ if (meta != null && meta.hasCustomModelData()) {
+ mode.customModelData = meta.getCustomModelData();
+ }
+ }
+ Object kitObj = map.get("kit");
+ Map kitMap = null;
+ if (kitObj instanceof Map) {
+ kitMap = (Map) kitObj;
+ } else if (kitObj instanceof org.bukkit.configuration.ConfigurationSection section) {
+ kitMap = section.getValues(false);
+ }
+ mode.kit = Kit.fromMap(kitMap);
+ List arenas = (List) map.getOrDefault("allowedArenas", new ArrayList<>());
+ mode.allowedArenas.addAll(arenas);
+ mode.fullSaturation = Boolean.parseBoolean(String.valueOf(map.getOrDefault("fullSaturation", false)));
+ mode.prepotEnabled = Boolean.parseBoolean(String.valueOf(map.getOrDefault("prepotEnabled", false)));
+ mode.blockBreak = Boolean.parseBoolean(String.valueOf(map.getOrDefault("blockBreak", false)));
+ mode.blockPlace = Boolean.parseBoolean(String.valueOf(map.getOrDefault("blockPlace", true)));
+ mode.naturalRegen = Boolean.parseBoolean(String.valueOf(map.getOrDefault("naturalRegen", true)));
+ mode.onlyBreakPlaced = Boolean.parseBoolean(String.valueOf(map.getOrDefault("onlyBreakPlaced", true)));
+ mode.lootDrops = Boolean.parseBoolean(String.valueOf(map.getOrDefault("lootDrops", false)));
+ mode.healthDisplay = Boolean.parseBoolean(String.valueOf(map.getOrDefault("healthDisplay", false)));
+ if (mode.onlyBreakPlaced) {
+ mode.blockBreak = false;
+ }
+ Object prepotObj = map.get("prepotEffects");
+ Map prepotMap = null;
+ if (prepotObj instanceof Map) {
+ prepotMap = (Map) prepotObj;
+ } else if (prepotObj instanceof org.bukkit.configuration.ConfigurationSection section) {
+ prepotMap = section.getValues(false);
+ }
+ if (prepotMap != null) {
+ for (Map.Entry entry : prepotMap.entrySet()) {
+ Map dataMap = null;
+ if (entry.getValue() instanceof Map) {
+ dataMap = (Map) entry.getValue();
+ } else if (entry.getValue() instanceof org.bukkit.configuration.ConfigurationSection section) {
+ dataMap = section.getValues(false);
+ }
+ mode.prepotEffects.put(entry.getKey(), PrepotData.fromMap(dataMap));
+ }
+ }
+ return mode;
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/model/InventorySnapshot.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/model/InventorySnapshot.java
new file mode 100644
index 0000000..754f864
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/model/InventorySnapshot.java
@@ -0,0 +1,29 @@
+package com.starpractice.model;
+
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+
+public class InventorySnapshot {
+ private final ItemStack[] contents;
+ private final ItemStack[] armor;
+ private final ItemStack offhand;
+
+ public InventorySnapshot(ItemStack[] contents, ItemStack[] armor, ItemStack offhand) {
+ this.contents = contents;
+ this.armor = armor;
+ this.offhand = offhand;
+ }
+
+ public static InventorySnapshot fromPlayer(Player player) {
+ ItemStack[] contents = player.getInventory().getContents();
+ ItemStack[] armor = player.getInventory().getArmorContents();
+ ItemStack offhand = player.getInventory().getItemInOffHand();
+ return new InventorySnapshot(contents, armor, offhand);
+ }
+
+ public void apply(Player player) {
+ player.getInventory().setContents(contents);
+ player.getInventory().setArmorContents(armor);
+ player.getInventory().setItemInOffHand(offhand);
+ }
+}
diff --git a/StarPractice (2)/StarPractice/src/main/java/com/starpractice/model/Kit.java b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/model/Kit.java
new file mode 100644
index 0000000..a73d8fd
--- /dev/null
+++ b/StarPractice (2)/StarPractice/src/main/java/com/starpractice/model/Kit.java
@@ -0,0 +1,128 @@
+package com.starpractice.model;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.potion.PotionEffect;
+import org.bukkit.potion.PotionEffectType;
+
+public class Kit {
+ private final ItemStack[] contents;
+ private final ItemStack[] armor;
+ private final ItemStack offhand;
+ private final List effects;
+
+ public Kit(ItemStack[] contents, ItemStack[] armor, ItemStack offhand, List effects) {
+ this.contents = contents;
+ this.armor = armor;
+ this.offhand = offhand;
+ this.effects = effects;
+ }
+
+ public static Kit fromPlayer(Player player) {
+ ItemStack[] contents = player.getInventory().getContents();
+ ItemStack[] armor = player.getInventory().getArmorContents();
+ ItemStack offhand = player.getInventory().getItemInOffHand();
+ List effects = new ArrayList<>(player.getActivePotionEffects());
+ return new Kit(contents, armor, offhand, effects);
+ }
+
+ public void apply(Player player) {
+ player.getInventory().clear();
+ player.getInventory().setContents(contents);
+ player.getInventory().setArmorContents(armor);
+ player.getInventory().setItemInOffHand(offhand);
+ player.getActivePotionEffects().forEach(effect -> player.removePotionEffect(effect.getType()));
+ for (PotionEffect effect : effects) {
+ player.addPotionEffect(effect);
+ }
+ player.updateInventory();
+ }
+
+ public ItemStack[] getContents() {
+ return cloneArray(contents);
+ }
+
+ public ItemStack[] getArmor() {
+ return cloneArray(armor);
+ }
+
+ public ItemStack getOffhand() {
+ return offhand == null ? null : offhand.clone();
+ }
+
+ public List getEffects() {
+ return new ArrayList<>(effects);
+ }
+
+ public Kit copy() {
+ return new Kit(getContents(), getArmor(), getOffhand(), getEffects());
+ }
+
+ public Map toMap() {
+ Map map = new HashMap<>();
+ map.put("contents", contents);
+ map.put("armor", armor);
+ map.put("offhand", offhand);
+ List