Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2d5b6beef3 | ||
|
|
2f91860ad9
|
||
|
|
4ae8786e8e
|
||
|
|
60e0b41186
|
||
|
|
4632d61b96
|
||
|
|
03b955fd2a | ||
|
|
8d04fc0cf7 | ||
|
|
64d652a676 | ||
|
|
31bc05689d | ||
|
|
3dee6ed808 | ||
|
|
280063a609 | ||
|
|
8a84095afe | ||
|
|
3fcdfee824 | ||
|
|
eb4f80f467 | ||
|
|
055e4393d4 | ||
|
|
14e784a7ea | ||
|
|
ad2af065f4 | ||
|
|
34ff8e7443 | ||
|
|
d56c34fdd6 | ||
|
|
f697333710 | ||
|
|
a01c07f641 | ||
|
|
74bda649a5 | ||
|
|
c685d4ccfa | ||
|
|
40ef184e3a | ||
|
|
aadf6cc622 | ||
|
|
e2947d30db | ||
|
|
fc9afdf09a | ||
|
|
d1d0fd2eb2 | ||
|
|
a3a118ee11 | ||
|
|
6f6296971d | ||
|
|
a8f257ae62 | ||
|
|
c0107a99d4 | ||
|
|
cf4db3f5ba | ||
|
|
dfffb9c154 | ||
|
|
98bd470968 | ||
|
|
0abb3fcb9a | ||
|
|
c3b22df4f6 | ||
|
|
5bf3e2def8 | ||
|
|
ff4118bb4e | ||
|
|
5b11813ff7 | ||
|
|
84627afee6 | ||
|
|
46b0581005 | ||
|
|
aaa15b93c3 | ||
|
|
e2526f8f01 | ||
|
|
b6c44164f6 | ||
|
|
d960e23fc5 | ||
|
|
bcf10d0688 | ||
|
|
acf4242ab8 | ||
|
|
5bfd192d97 | ||
|
|
e133f70b86 | ||
|
|
fbc303bbee | ||
|
|
df72b954c4 | ||
|
|
086278d662 | ||
|
|
a9b9770233 | ||
|
|
9065c44d9e | ||
|
|
794d34d0df | ||
|
|
d5777add02 | ||
|
|
77653f48c2 | ||
|
|
843e4d6ee1 | ||
|
|
48fd17a36d | ||
|
|
d846cd5519 | ||
|
|
5da1b96e20 | ||
|
|
9e60483c78 | ||
|
|
f5c20777eb | ||
|
|
6b36ea7d8f | ||
|
|
7fdfde4523 | ||
|
|
5a51918af1 | ||
|
|
696e762fbd | ||
|
|
8d7f3d6da5 | ||
|
|
bf765d8055 | ||
|
|
ee6ad93f5c | ||
|
|
b2e39dd9af | ||
|
|
b649d0f1e2 | ||
|
|
f67dd7bce3 | ||
|
|
5671730d22 | ||
|
|
ef49346fca | ||
|
|
4954745ceb | ||
|
|
215b2dbe83 | ||
|
|
19d82a11d9 | ||
|
|
23f3952a6b | ||
|
|
12ddb16175 | ||
|
|
cb41cfe553 | ||
|
|
4f0612b338 | ||
|
|
e9e50e2b5e | ||
|
|
4f48b825f6 | ||
|
|
91019a2c40 | ||
|
|
29e082dc94 | ||
|
|
91999ea0ce | ||
|
|
afbb1348ae | ||
|
|
d1f579894d | ||
|
|
937d14a08d | ||
|
|
bc1231cd81 | ||
|
|
3c5afcc030 | ||
|
|
b79d4bd628 | ||
|
|
b41a82d533 | ||
|
|
48f2f6f3c8 | ||
|
|
c4c889d432 | ||
|
|
620a98d1cf | ||
|
|
e1702994b0 | ||
|
|
5cb1c11f0e | ||
|
|
4f7cc7bad7 | ||
|
|
f61cdd6b0e | ||
|
|
9212ad99ff | ||
|
|
5d7b4c09d6 | ||
|
|
3eb9e625ea | ||
|
|
96ac8d63a6 | ||
|
|
0f6728220a | ||
|
|
e3270fbc51 | ||
|
|
2555593fa6 | ||
|
|
2781e3d599 | ||
|
|
205e7a2d4d | ||
|
|
a93764355f | ||
|
|
62c095d9a2 | ||
|
|
c7b983c1ff | ||
|
|
65ceba4708 | ||
|
|
333837ccea | ||
|
|
85d20e17d3 | ||
|
|
1ad76d43dc | ||
|
|
c2366d3013 | ||
|
|
f57056a13a | ||
|
|
2ccec38b65 | ||
|
|
ca4287dcf5 | ||
|
|
b1c3cf280f | ||
|
|
a1cc8e9cfb | ||
|
|
b2873319dc | ||
|
|
1effcc0d87 | ||
|
|
bf05c51d3d | ||
|
|
6c3adbcd40 | ||
|
|
24d6d2d2b2 | ||
|
|
f1eea4626e | ||
|
|
6e637ca5c8 | ||
|
|
eb3145daa6 | ||
|
|
4f8e5bbaf2 | ||
|
|
505f9876a2 | ||
|
|
99b3a958bf | ||
|
|
c0b5d5dffb | ||
|
|
70be2c8b2e | ||
|
|
6887d1b1ed | ||
|
|
c3fa548841 | ||
|
|
16c6f70c66 | ||
|
|
846d72de85 | ||
|
|
64b6c24213 | ||
|
|
d7cb1c9523 | ||
|
|
4117b44984 | ||
|
|
6d6b228801 | ||
|
|
e6e3782b04 | ||
|
|
ae0e8db57a | ||
|
|
1d00e73a75 | ||
|
|
fc054f4896 | ||
|
|
2940a7b3bd | ||
|
|
36b85109d6 | ||
|
|
3a8627863f | ||
|
|
41d774258a | ||
|
|
0d535aed72 | ||
|
|
f3532f703c | ||
|
|
9c4a6046b8 | ||
|
|
fde7fdb090 | ||
|
|
289dd486c8 | ||
|
|
5bb09887f5 | ||
|
|
1fc5a836dd | ||
|
|
e9443a35da | ||
|
|
23b12d945f | ||
|
|
6e20f5c2dd | ||
|
|
0da0a5709e | ||
|
|
d42082b05c | ||
|
|
c2b0fef9b1 | ||
|
|
a352a07fdb | ||
|
|
22bc0ce8a6 | ||
|
|
ce3d058e65 | ||
|
|
8529b0d472 | ||
|
|
8f208d7352 | ||
|
|
8efb8b495d | ||
|
|
0c3001d1d7 | ||
|
|
a6bdb5614a | ||
|
|
ed578c3400 | ||
|
|
b07dc76605 | ||
|
|
682c615504 | ||
|
|
5827c022ff | ||
|
|
2185913c20 | ||
|
|
5e2dcbafa3 | ||
|
|
2a94d729a6 | ||
|
|
51aed96ba8 | ||
|
|
3ae7933015 | ||
|
|
51152f61fd | ||
|
|
ac4a81340c | ||
|
|
f92754d37b | ||
|
|
dcae65f1c5 | ||
|
|
87aa8069e4 | ||
|
|
73340ed882 | ||
|
|
2a3dd0abc1 | ||
|
|
addb564e37 | ||
|
|
105d34afb4 | ||
|
|
1d2879b6bf | ||
|
|
24998b99d4 | ||
|
|
e8b130c15a | ||
|
|
f329bddb6c | ||
|
|
201fc9aa2c | ||
|
|
7a4ee61f8e | ||
|
|
1c5b00262e | ||
|
|
f5dd1a7cc2 | ||
|
|
474672b004 |
No files matched your search
@@ -0,0 +1 @@
|
||||
.gitea/CODEOWNERS linguist-detectable=false
|
||||
@@ -0,0 +1,3 @@
|
||||
# Pull requests request review from the eligible staff team(s).
|
||||
# One approval from either an Admin or Developer satisfies branch protection.
|
||||
* @trueog/Admins @trueog/Developers
|
||||
+6
-1
@@ -1,6 +1,12 @@
|
||||
*.class
|
||||
target/
|
||||
out/
|
||||
build/
|
||||
.gradle/
|
||||
bin/
|
||||
.classpath
|
||||
.project
|
||||
.checkstyle
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
@@ -10,7 +16,6 @@ out/
|
||||
*.eml
|
||||
*.iml
|
||||
|
||||
|
||||
# Eclipse files
|
||||
.settings
|
||||
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
image: maven:3-jdk-9-slim
|
||||
|
||||
cache:
|
||||
paths:
|
||||
- .m2/repository
|
||||
|
||||
variables:
|
||||
MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true"
|
||||
MAVEN_CLI_OPTS: "--batch-mode --errors --fail-at-end --show-version -DinstallAtEnd=true -DdeployAtEnd=true"
|
||||
|
||||
stages:
|
||||
- build
|
||||
- deploy
|
||||
|
||||
build:
|
||||
stage: build
|
||||
script:
|
||||
- apt update
|
||||
- apt install wget -y
|
||||
- wget https://gitlab.com/cubekrowd/mavenrepo/raw/master/build2.sh
|
||||
- bash build2.sh
|
||||
artifacts:
|
||||
paths:
|
||||
- "*.jar"
|
||||
|
||||
deploy:
|
||||
stage: deploy
|
||||
script:
|
||||
- apt update
|
||||
- apt install wget -y
|
||||
- wget https://gitlab.com/cubekrowd/mavenrepo/raw/master/deploy1.sh
|
||||
- bash deploy1.sh
|
||||
only:
|
||||
- master
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "libs/Utilities-OG"]
|
||||
path = libs/Utilities-OG
|
||||
url = https://git.trueog.net/trueog/Utilities-OG
|
||||
@@ -1,375 +1,21 @@
|
||||
Copyright © 2015, Leon Mangler and the SuperVanish contributors
|
||||
|
||||
Mozilla Public License Version 2.0
|
||||
==================================
|
||||
|
||||
1. Definitions
|
||||
--------------
|
||||
|
||||
1.1. "Contributor"
|
||||
means each individual or legal entity that creates, contributes to
|
||||
the creation of, or owns Covered Software.
|
||||
|
||||
1.2. "Contributor Version"
|
||||
means the combination of the Contributions of others (if any) used
|
||||
by a Contributor and that particular Contributor's Contribution.
|
||||
|
||||
1.3. "Contribution"
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
means Source Code Form to which the initial Contributor has attached
|
||||
the notice in Exhibit A, the Executable Form of such Source Code
|
||||
Form, and Modifications of such Source Code Form, in each case
|
||||
including portions thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
(a) that the initial Contributor has attached the notice described
|
||||
in Exhibit B to the Covered Software; or
|
||||
|
||||
(b) that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the
|
||||
terms of a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
means a work that combines Covered Software with other material, in
|
||||
a separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
means having the right to grant, to the maximum extent possible,
|
||||
whether at the time of the initial grant or subsequently, any and
|
||||
all of the rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
means any of the following:
|
||||
|
||||
(a) any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered
|
||||
Software; or
|
||||
|
||||
(b) any new file in Source Code Form that contains any Covered
|
||||
Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the
|
||||
License, by the making, using, selling, offering for sale, having
|
||||
made, import, or transfer of either its Contributions or its
|
||||
Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
means either the GNU General Public License, Version 2.0, the GNU
|
||||
Lesser General Public License, Version 2.1, the GNU Affero General
|
||||
Public License, Version 3.0, or any later versions of those
|
||||
licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that
|
||||
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 and Conditions
|
||||
--------------------------------
|
||||
|
||||
2.1. Grants
|
||||
|
||||
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 such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
(b) under Patent Claims of such Contributor to make, use, sell, offer
|
||||
for sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
(a) for any code that a Contributor has removed from Covered Software;
|
||||
or
|
||||
|
||||
(b) for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
(c) under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights
|
||||
to grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
|
||||
in Section 2.1.
|
||||
|
||||
3. Responsibilities
|
||||
-------------------
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
(a) such Covered Software must also be made available in Source Code
|
||||
Form, as described in Section 3.1, and You must inform recipients of
|
||||
the Executable Form how they can obtain a copy of such Source Code
|
||||
Form by reasonable means in a timely manner, at a charge no more
|
||||
than the cost of distribution to the recipient; and
|
||||
|
||||
(b) You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter
|
||||
the recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty,
|
||||
or limitations of liability) contained within the Source Code Form of
|
||||
the Covered Software, except that You may alter any license notices to
|
||||
the extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
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 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 every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
---------------------------------------------------
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this
|
||||
License with respect to some or all of the Covered Software due to
|
||||
statute, judicial order, or regulation then You must: (a) comply with
|
||||
the terms of this License to the maximum extent possible; and (b)
|
||||
describe the limitations and the code they affect. Such description must
|
||||
be placed in a text file included with all distributions of the Covered
|
||||
Software under this License. Except to the extent prohibited by statute
|
||||
or regulation, such description must be sufficiently detailed for a
|
||||
recipient of ordinary skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
--------------
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically
|
||||
if You fail to comply with any of its terms. However, if You become
|
||||
compliant, then the rights granted under this License from a particular
|
||||
Contributor are reinstated (a) provisionally, unless and until such
|
||||
Contributor explicitly and finally terminates Your grants, and (b) on an
|
||||
ongoing basis, if such Contributor fails to notify You of the
|
||||
non-compliance by some reasonable means prior to 60 days after You have
|
||||
come back into compliance. Moreover, Your grants from a particular
|
||||
Contributor are reinstated on an ongoing basis if such Contributor
|
||||
notifies You of the non-compliance by some reasonable means, this is the
|
||||
first time You have received notice of non-compliance with this License
|
||||
from such Contributor, and You become compliant prior to 30 days after
|
||||
Your receipt of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
|
||||
end user license agreements (excluding distributors and resellers) which
|
||||
have been validly granted by You or Your distributors under this License
|
||||
prior to termination shall survive termination.
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 6. Disclaimer of Warranty *
|
||||
* ------------------------- *
|
||||
* *
|
||||
* Covered Software is provided under this License on an "as is" *
|
||||
* basis, without warranty of any kind, either expressed, implied, or *
|
||||
* statutory, 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 any 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 under this License except under this disclaimer. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 7. Limitation of Liability *
|
||||
* -------------------------- *
|
||||
* *
|
||||
* Under no circumstances and under no legal theory, whether tort *
|
||||
* (including negligence), contract, or otherwise, shall any *
|
||||
* Contributor, or anyone who distributes Covered Software as *
|
||||
* permitted above, be liable to You for any direct, indirect, *
|
||||
* special, incidental, or consequential damages of any character *
|
||||
* including, without limitation, damages for lost profits, 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. Litigation
|
||||
-------------
|
||||
|
||||
Any litigation relating to this License may be brought only in the
|
||||
courts of a jurisdiction where the defendant maintains its principal
|
||||
place of business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions.
|
||||
Nothing in this Section shall prevent a party's ability to bring
|
||||
cross-claims or counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
----------------
|
||||
|
||||
This License represents the complete agreement concerning the 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. Any law or regulation which provides
|
||||
that the language of a contract shall be construed against the drafter
|
||||
shall not be used to construe this License against a Contributor.
|
||||
|
||||
10. Versions of the License
|
||||
---------------------------
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses
|
||||
|
||||
If You choose to distribute Source Code Form that is Incompatible With
|
||||
Secondary Licenses under the terms of this version of the License, the
|
||||
notice described in Exhibit B of this License must be attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
-------------------------------------------
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular
|
||||
file, then You may include the notice in a location (such as a LICENSE
|
||||
file in a relevant directory) where a recipient would be likely to look
|
||||
for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
---------------------------------------------------------
|
||||
|
||||
This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
defined by the Mozilla Public License, v. 2.0.
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Leon Mangler
|
||||
|
||||
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.
|
||||
@@ -1,28 +1,162 @@
|
||||
# SuperVanish
|
||||
Website: https://www.spigotmc.org/resources/supervanish-be-invisible.1331/
|
||||
# Vanish-OG
|
||||
|
||||
Bukkit-Plugin for Spigot/CraftBukkit (Minecraft-Server software)
|
||||
A fork of [SuperVanish](https://www.spigotmc.org/resources/supervanish-be-invisible.1331/) for [TrueOG Network](https://trueog.net). Lets staff become completely invisible so they can quietly observe and moderate.
|
||||
|
||||
Allows server admins to be completely invisible and undetectable for other players, which helps them with their administrative work.
|
||||
Built for **Purpur 1.19.4**. Clients from **Minecraft 1.8 through 1.21.11** can connect through ViaSuite (ViaVersion / ViaBackwards / ViaRewind) and vanish works correctly across the board.
|
||||
|
||||
Feel free to create Pull Requests if you think that you can improve SuperVanish!
|
||||
### What's different from SuperVanish?
|
||||
|
||||
## Maven Repository
|
||||
- **Tab list hiding works on 1.19+** Upstream switched it off after a Mojang change broke it. Vanish-OG handles the new format so vanished staff stay hidden from the tab list.
|
||||
- **Spectator indication works on 1.19.4 again.** `MarkVanishedPlayersAsSpectators` now uses the native 1.19.4 player info update packet, so staff who can see vanished players still get the dark-gray/head-only tab list cue across Via-served 1.8-1.21.11 clients.
|
||||
- **Silent chest opening works on 1.19.4 again.** Peeking into containers looks completely invisible to other players if vanished.
|
||||
- **All connected clients see the same thing.** Whether someone joins from 1.8 or the latest 1.21.11 release through ViaSuite, vanish behaves identically.
|
||||
- **[Chat-OG](https://git.trueog.net/trueog/Chat-OG) owns announcement visibility.** Vanish-OG no longer rewrites join/quit, death, or advancement messages and no longer emits fake join/quit broadcasts on vanish toggles. Chat-OG is responsible for hiding vanished-player activity from Discord-facing announcements.
|
||||
- **OpenInv support.** If installed, Vanish-OG hands off chest viewing to OpenInv so staff never enter spectator mode and can't get stuck there after a crash.
|
||||
- **MiniPlaceholders support** (via Utilities-OG) for use in chat, tab, and hologram plugins.
|
||||
- **Safer chest peeking.** Staff no longer occasionally fall through the floor when finishing a peek. Pair with [WGamemode](https://github.com/true-og/WGamemode) to auto-restore gamemodes after crashes if OpenInv is not installed.
|
||||
- **Flat-file storage again.** Vanish state and player preferences are stored locally in `plugins/Vanish-OG/data.yml`, which keeps the runtime path simple and removes the external KeyDB dependency.
|
||||
- **Rejoin state is persisted, not permission-driven.** Players only reconnect vanished if `data.yml` still marks them vanished from last time; there is no "always join vanished" permission path anymore.
|
||||
- **TAB-OG compatibility via TAB API.** When [TAB-OG](https://git.trueog.net/trueog/TAB-OG) is installed, Vanish-OG registers a `VanishIntegration` handler with TAB's API so TAB consults Vanish-OG's state manager directly for its `canSee()` / `isVanished()` checks instead of depending solely on the `"vanished"` player metadata key. This closes the join-time race where Forge clients crashed because TAB evaluated tab-list visibility before the metadata was set. The metadata key is still set during `PlayerLoginEvent` so TAB's placeholder-level `isVanished` fallback and any other plugin using the convention keep working.
|
||||
- **Removed old clutter.** Deprecated functions are removed and the code is updated for java 17 conventions.
|
||||
|
||||
### Chat-OG handles some events that used to be handled by SuperVanish
|
||||
|
||||
If your stack includes [Chat-OG](https://git.trueog.net/trueog/Chat-OG), think of the split like this:
|
||||
|
||||
- Vanish-OG manages vanish state, player/entity visibility, tab list hiding, spectator indication, and silent chest behavior.
|
||||
- Chat-OG manages whether vanished-player join/quit, kick, advancement, death, and Discord bridge announcements are surfaced.
|
||||
|
||||
This avoids two plugins trying to suppress or fake the same announcement events.
|
||||
|
||||
### API
|
||||
|
||||
Vanish-OG ships the same Bukkit-facing API package as SuperVanish: `de.myzelyam.api.vanish`.
|
||||
|
||||
### Main entry point
|
||||
|
||||
Use [`VanishAPI`](src/main/java/de/myzelyam/api/vanish/VanishAPI.java) for all direct integrations.
|
||||
|
||||
```java
|
||||
import de.myzelyam.api.vanish.VanishAPI;
|
||||
import net.trueog.utilitiesog.UtilitiesOG;
|
||||
```
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>cubekrowd-repo</id>
|
||||
<url>https://mavenrepo.cubekrowd.net/artifactory/repo/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<!-- SuperVanish -->
|
||||
<dependency>
|
||||
<groupId>de.myzelyam</groupId>
|
||||
<artifactId>SuperVanish</artifactId>
|
||||
<version>6.0.5</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
### Commands
|
||||
|
||||
Main command: `/vanish` (also `/v`, `/sv`, `/supervanish`).
|
||||
|
||||
### State queries
|
||||
|
||||
- `VanishAPI.getInvisiblePlayers()`
|
||||
Returns the UUIDs of all online vanished players.
|
||||
- `VanishAPI.getAllInvisiblePlayers()`
|
||||
Returns the UUIDs of all vanished players, including offline players stored in `data.yml`.
|
||||
- `VanishAPI.isVanished(Player player)`
|
||||
Checks if a player is vanished. Returns `boolean`.
|
||||
- `VanishAPI.isVanished(UUID uuid)`
|
||||
Checks if a player is vanished. Returns `boolean`.
|
||||
|
||||
Java:
|
||||
|
||||
```java
|
||||
if (VanishAPI.isVanished(player) || VanishAPI.isVanished(player.getUniqueId())) {
|
||||
UtilitiesOG.trueogMessage(player, "You are vanished.");
|
||||
}
|
||||
```
|
||||
|
||||
Kotlin:
|
||||
|
||||
```kotlin
|
||||
if (VanishAPI.isVanished(player) || VanishAPI.isVanished(player.uniqueId)) {
|
||||
UtilitiesOG.trueogMessage(player, "You are vanished.")
|
||||
}
|
||||
```
|
||||
|
||||
### Visibility control
|
||||
|
||||
- `VanishAPI.hidePlayer(Player player)`
|
||||
Vanishes the player through the normal SuperVanish pipeline and fires the related events. Main thread only.
|
||||
- `VanishAPI.showPlayer(Player player)`
|
||||
Reveals the player through the normal SuperVanish pipeline and fires the related events. Main thread only.
|
||||
- `VanishAPI.canSee(Player viewer, Player viewed)`
|
||||
Returns whether `viewer` should currently be able to see `viewed`. Main thread only.
|
||||
|
||||
Java:
|
||||
|
||||
```java
|
||||
if (!VanishAPI.canSee(viewer, target)) {
|
||||
UtilitiesOG.trueogMessage(viewer, "<red>That player is hidden from you.");
|
||||
}
|
||||
|
||||
VanishAPI.hidePlayer(target);
|
||||
VanishAPI.showPlayer(target);
|
||||
```
|
||||
|
||||
Kotlin:
|
||||
|
||||
```kotlin
|
||||
if (!VanishAPI.canSee(viewer, target)) {
|
||||
UtilitiesOG.trueogMessage(viewer, "<red>That player is hidden from you.")
|
||||
}
|
||||
|
||||
VanishAPI.hidePlayer(target)
|
||||
VanishAPI.showPlayer(target)
|
||||
```
|
||||
|
||||
### Configuration access
|
||||
|
||||
- `VanishAPI.getConfiguration()`
|
||||
Returns `config.yml`. Main thread only; treat the returned `FileConfiguration` as Bukkit-owned mutable state.
|
||||
- `VanishAPI.getMessages()`
|
||||
Returns `messages.yml`. Main thread only; treat the returned `FileConfiguration` as Bukkit-owned mutable state.
|
||||
- `VanishAPI.reloadConfig()`
|
||||
Reloads the plugin. Main thread only.
|
||||
- `VanishAPI.getPlugin()`
|
||||
Returns the active `SuperVanish` plugin instance. Fetching the reference is cheap, but any interaction with the plugin or Bukkit APIs should stay on the main thread.
|
||||
|
||||
### Events
|
||||
|
||||
The API exposes the following Bukkit events in `de.myzelyam.api.vanish`:
|
||||
|
||||
All of these are normal Bukkit events and should be handled on the main server thread. Do not assume they fire asynchronously.
|
||||
|
||||
- [`PlayerHideEvent`](src/main/java/de/myzelyam/api/vanish/PlayerHideEvent.java)
|
||||
Fired before a player is hidden. Cancellable. Includes `isSilent()` / `setSilent(boolean)`.
|
||||
- [`PostPlayerHideEvent`](src/main/java/de/myzelyam/api/vanish/PostPlayerHideEvent.java)
|
||||
Fired after a player has been hidden. Not cancellable. Includes `isSilent()`.
|
||||
- [`PlayerShowEvent`](src/main/java/de/myzelyam/api/vanish/PlayerShowEvent.java)
|
||||
Fired before a player is shown. Cancellable. Includes `isSilent()` / `setSilent(boolean)`.
|
||||
- [`PostPlayerShowEvent`](src/main/java/de/myzelyam/api/vanish/PostPlayerShowEvent.java)
|
||||
Fired after a player has been shown. Not cancellable. Includes `isSilent()`.
|
||||
- [`PlayerVanishStateChangeEvent`](src/main/java/de/myzelyam/api/vanish/PlayerVanishStateChangeEvent.java)
|
||||
Fired when persisted vanish state changes for a UUID. Cancellable. Exposes `isVanishing()`, `getUUID()`, `getPlayer()` (returns the Bukkit `Player` or `null` if offline), `getName()`, and `getCause()`. Constructible via `(UUID, String, boolean, String)` or `(Player, boolean, String)`.
|
||||
|
||||
### Example listener
|
||||
|
||||
Java:
|
||||
|
||||
```java
|
||||
@EventHandler
|
||||
public void onPlayerHide(PlayerHideEvent event) {
|
||||
if (!event.getPlayer().hasPermission("myplugin.allowvanish")) {
|
||||
UtilitiesOG.trueogMessage(event.getPlayer(), "<red>You are not allowed to vanish.");
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Kotlin:
|
||||
|
||||
```kotlin
|
||||
@EventHandler
|
||||
fun onPlayerHide(event: PlayerHideEvent) {
|
||||
if (!event.player.hasPermission("myplugin.allowvanish")) {
|
||||
UtilitiesOG.trueogMessage(event.player, "<red>You are not allowed to vanish.")
|
||||
event.isCancelled = true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Reporting issues
|
||||
|
||||
Open an issue on the [Vanish-OG Gitea repository](https://git.trueog.net/trueog/Vanish-OG/issues).
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
# Fetch all submodule content.
|
||||
git submodule update --force --recursive --init
|
||||
@@ -0,0 +1,157 @@
|
||||
/* ------------------------------ Plugins ------------------------------ */
|
||||
plugins {
|
||||
id("java") // Import Java plugin.
|
||||
id("java-library") // Import Java Library plugin.
|
||||
id("com.diffplug.spotless") version "8.1.0" // Import Spotless plugin.
|
||||
id("com.gradleup.shadow") version "8.3.9" // Import Shadow plugin.
|
||||
id("checkstyle") // Import Checkstyle plugin.
|
||||
eclipse // Import Eclipse plugin.
|
||||
}
|
||||
|
||||
/* --------------------------- JDK / Kotlin ---------------------------- */
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_17 // Compile with JDK 17 compatibility.
|
||||
toolchain { // Select Java toolchain.
|
||||
languageVersion.set(JavaLanguageVersion.of(17)) // Use JDK 17.
|
||||
vendor.set(JvmVendorSpec.GRAAL_VM) // Use GraalVM CE.
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------- Metadata ------------------------------ */
|
||||
group = "de.myzelyam.vanishog" // Declare bundle identifier.
|
||||
|
||||
version = "1.1" // Declare plugin version (will be in .jar).
|
||||
|
||||
val apiVersion = "1.13" // Declare minecraft server target version.
|
||||
|
||||
/* ----------------------------- Resources ----------------------------- */
|
||||
tasks.named<ProcessResources>("processResources") {
|
||||
val props = mapOf("version" to version, "apiVersion" to apiVersion)
|
||||
inputs.properties(props) // Indicates to rerun if version changes.
|
||||
filesMatching(listOf("plugin.yml", "config.yml", "messages.yml")) {
|
||||
expand(props) { escapeBackslash.set(true) } // Keep literal '\n' etc. intact in YAML comments/values.
|
||||
}
|
||||
from("LICENSE") { into("/") } // Bundle main GPLv2 license at jar root.
|
||||
from("libs/License.txt") { // Bundle ProtocolLib GPLv2 license.
|
||||
into("META-INF/licenses/ProtocolLib")
|
||||
rename { "LICENSE" }
|
||||
}
|
||||
from("libs/TAB-OG/LICENSE") { // Bundle TAB-OG license.
|
||||
into("META-INF/licenses/TAB-OG")
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------- Repos ---------------------------------- */
|
||||
repositories {
|
||||
mavenCentral() // Import the Maven Central Maven Repository.
|
||||
gradlePluginPortal() // Import the Gradle Plugin Portal Maven Repository.
|
||||
maven { url = uri("https://repo.purpurmc.org/snapshots") } // Import the PurpurMC Maven Repository.
|
||||
maven { url = uri("https://repo.papermc.io/repository/maven-public/") } // PaperMC.
|
||||
maven { url = uri("https://repo.essentialsx.net/releases/") } // EssentialsX.
|
||||
maven { url = uri("https://jitpack.io") } // JitPack (VaultAPI, TrailGUI, OpenInv, Dynmap).
|
||||
maven { url = uri("https://repo.citizensnpcs.co/") } // Citizens.
|
||||
maven { url = uri("https://libraries.minecraft.net") } // Mojang Brigadier.
|
||||
}
|
||||
|
||||
/* ---------------------- Java project deps ---------------------------- */
|
||||
dependencies {
|
||||
// Purpur API (server target).
|
||||
compileOnly("org.purpurmc.purpur:purpur-api:1.19.4-R0.1-SNAPSHOT")
|
||||
|
||||
// Import TrueOG Network Utilities-OG Java API (from source).
|
||||
compileOnlyApi(project(":libs:Utilities-OG"))
|
||||
|
||||
// EssentialsX API.
|
||||
compileOnly("net.essentialsx:EssentialsX:2.21.0") {
|
||||
exclude(group = "org.bstats", module = "bstats-bukkit") // Exclude bstats.
|
||||
}
|
||||
|
||||
// LuckPerms API (group, prefix, suffix lookups).
|
||||
compileOnly("net.luckperms:api:5.5") // Import the LuckPerms API.
|
||||
|
||||
// ProtocolLib (local jar in libs/ProtocolLib/).
|
||||
compileOnly(files("libs/ProtocolLib/ProtocolLib-5.0.jar"))
|
||||
|
||||
// TAB-OG API (local jar in libs/TAB-OG/).
|
||||
compileOnly(files("libs/TAB-OG/tab-api-4.2.0.jar"))
|
||||
|
||||
// Citizens API.
|
||||
compileOnly("net.citizensnpcs:citizensapi:2.0.28-SNAPSHOT")
|
||||
|
||||
// TrailGUI (via JitPack).
|
||||
compileOnly("com.github.SinnDevelopment:TrailGUI:37659dda03")
|
||||
|
||||
// Import MiniPlaceholders API.
|
||||
compileOnly("io.github.miniplaceholders:miniplaceholders-api:2.2.3")
|
||||
|
||||
// Mojang Brigadier (provided at runtime by Purpur).
|
||||
compileOnly("com.mojang:brigadier:1.0.18")
|
||||
}
|
||||
|
||||
apply(from = "eclipse.gradle.kts") // Import eclipse classpath support script.
|
||||
|
||||
/* ---------------------- Reproducible jars ---------------------------- */
|
||||
tasks.withType<AbstractArchiveTask>().configureEach { // Ensure reproducible .jars
|
||||
isPreserveFileTimestamps = false
|
||||
isReproducibleFileOrder = true
|
||||
}
|
||||
|
||||
/* ----------------------------- Shadow -------------------------------- */
|
||||
tasks.shadowJar {
|
||||
exclude("io.github.miniplaceholders.*") // Exclude the MiniPlaceholders package from being shadowed.
|
||||
isEnableRelocation = true
|
||||
relocationPrefix = "${project.group}.shadow"
|
||||
mergeServiceFiles()
|
||||
archiveClassifier.set("") // Use empty string instead of null.
|
||||
archiveBaseName.set(rootProject.name) // Vanish-OG-${version}.jar
|
||||
}
|
||||
|
||||
tasks.jar { archiveClassifier.set("part") } // Applies to root jarfile only.
|
||||
|
||||
tasks.build { dependsOn(tasks.spotlessApply, tasks.shadowJar) } // Build depends on spotless and shadow.
|
||||
|
||||
/* --------------------------- Javac opts ------------------------------- */
|
||||
tasks.withType<JavaCompile>().configureEach {
|
||||
options.compilerArgs.add("-parameters") // Enable reflection for java code.
|
||||
options.isFork = true // Run javac in its own process.
|
||||
options.compilerArgs.add("-Xlint:deprecation") // Trigger deprecation warning messages.
|
||||
options.encoding = "UTF-8" // Use UTF-8 file encoding.
|
||||
}
|
||||
|
||||
/* ----------------------------- Auto Formatting ------------------------ */
|
||||
spotless {
|
||||
java {
|
||||
eclipse().configFile("config/formatter/eclipse-java-formatter.xml") // Eclipse java formatting.
|
||||
leadingTabsToSpaces() // Convert leftover leading tabs to spaces.
|
||||
removeUnusedImports() // Remove imports that aren't being called.
|
||||
}
|
||||
kotlinGradle {
|
||||
ktfmt().kotlinlangStyle().configure { it.setMaxWidth(120) } // JetBrains Kotlin formatting.
|
||||
target("build.gradle.kts", "settings.gradle.kts") // Gradle files to format.
|
||||
}
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
toolVersion = "10.18.1" // Declare checkstyle version to use.
|
||||
configFile = file("config/checkstyle/checkstyle.xml") // Point checkstyle to config file.
|
||||
isIgnoreFailures = true // Don't fail the build if checkstyle does not pass.
|
||||
isShowViolations = true // Show the violations in any IDE with the checkstyle plugin.
|
||||
}
|
||||
|
||||
tasks.named("compileJava") {
|
||||
dependsOn("spotlessApply") // Run spotless before compiling with the JDK.
|
||||
}
|
||||
|
||||
tasks.named("spotlessCheck") {
|
||||
dependsOn("spotlessApply") // Run spotless before checking if spotless ran.
|
||||
}
|
||||
|
||||
/* ------------------------------ Eclipse SHIM ------------------------- */
|
||||
|
||||
// This can't be put in eclipse.gradle.kts because Gradle is weird.
|
||||
subprojects {
|
||||
apply(plugin = "java-library")
|
||||
apply(plugin = "eclipse")
|
||||
eclipse.project.name = "${project.name}-${rootProject.name}"
|
||||
tasks.withType<Jar>().configureEach { archiveBaseName.set("${project.name}-${rootProject.name}") }
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE module PUBLIC
|
||||
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
|
||||
"https://checkstyle.org/dtds/configuration_1_3.dtd">
|
||||
<module name="Checker">
|
||||
|
||||
<module name="FileTabCharacter">
|
||||
<property name="eachLine" value="true"/>
|
||||
<property name="severity" value="error"/>
|
||||
</module>
|
||||
|
||||
<module name="TreeWalker">
|
||||
<module name="FinalLocalVariable"/>
|
||||
<module name="AvoidStarImport"/>
|
||||
<module name="Indentation">
|
||||
<property name="severity" value="ignore"/>
|
||||
</module>
|
||||
</module>
|
||||
|
||||
<module name="RegexpSingleline">
|
||||
<property name="format" value="\borg\.junit\.jupiter\.api\.Assertions\.fail\s*\(\s*"Not yet implemented"\s*\)\s*;"/>
|
||||
<property name="message" value="Remove placeholder fail() and implement the test."/>
|
||||
<property name="ignoreCase" value="true"/>
|
||||
<property name="severity" value="warning"/>
|
||||
</module>
|
||||
|
||||
<module name="RegexpSingleline">
|
||||
<property name="format" value="(?<!\w)fail\s*\(\s*"Not yet implemented"\s*\)\s*;"/>
|
||||
<property name="message" value="Remove placeholder fail() and implement the test."/>
|
||||
<property name="severity" value="warning"/>
|
||||
</module>
|
||||
|
||||
</module>
|
||||
|
||||
@@ -0,0 +1,404 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<profiles version="23">
|
||||
<profile kind="CodeFormatterProfile" name="TrueOG Network Formatting" version="23">
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment" value="common_lines"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration" value="common_lines"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.align_with_spaces" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_before_code_block" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_record_components" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_logical_operator" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line" value="one_line_never"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_record_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line" value="one_line_never"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause" value="common_lines"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line" value="one_line_never"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_shift_operator" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="next_line_on_wrap"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_loops" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_switch_case_arrow_operator" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation" value="common_lines"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_enum_constant" value="49"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.text_block_indentation" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_module_statements" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line" value="one_line_never"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_permitted_types" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="next_line_on_wrap"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_annotations" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assertion_message_operator" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines" value="2147483647"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="next_line_on_wrap"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_not_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration" value="common_lines"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package" value="49"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_record_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.javadoc_do_not_separate_block_tags" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_tag_description" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_constructor" value="next_line_on_wrap"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_string_concatenation" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="next_line_on_wrap"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_shift_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_shift_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_record_components" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_additive_operator" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case_after_arrow" value="next_line_on_wrap"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_record_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_relational_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_logical_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation" value="common_lines"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_record_declaration" value="common_lines"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement" value="common_lines"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement" value="common_lines"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_switch_body_block_on_one_line" value="one_line_never"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="next_line_on_wrap"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_arrow" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="80"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_method_body_on_one_line" value="one_line_never"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line" value="one_line_never"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="next_line_on_wrap"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line" value="one_line_never"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_additive_operator" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_constructor" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_relational_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_record_declaration_on_one_line" value="one_line_never"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="next_line_on_wrap"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="next_line_on_wrap"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_relational_operator" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.align_arrows_in_switch_on_columns" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_additive_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.align_selector_in_method_invocation_on_expression_first_line" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_declaration" value="next_line_on_wrap"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_switch_case_with_arrow_on_one_line" value="one_line_never"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_colon" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type" value="49"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable" value="49"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="next_line_on_wrap"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_additive_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field" value="49"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.join_line_comments" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_shift_operator" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause" value="common_lines"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_code_block_on_one_line" value="one_line_never"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_record_components" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_record_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="next_line_on_wrap"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_switch_case_with_arrow" value="20"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line" value="one_line_never"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method" value="49"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_record_constructor_on_one_line" value="one_line_never"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assertion_message" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_logical_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_record_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_relational_operator" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_logical_operator" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration" value="common_lines"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_permitted_types" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line" value="one_line_never"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="next_line_on_wrap"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="next_line_on_wrap"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_string_concatenation" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="120"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
|
||||
</profile>
|
||||
</profiles>
|
||||
Vendored
BIN
Binary file not shown.
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
@@ -0,0 +1,158 @@
|
||||
/* This is free and unencumbered software released into the public domain */
|
||||
|
||||
import org.gradle.api.tasks.bundling.Jar
|
||||
import org.gradle.plugins.ide.eclipse.model.EclipseModel
|
||||
import java.nio.file.Files
|
||||
import javax.xml.parsers.DocumentBuilderFactory
|
||||
import javax.xml.transform.OutputKeys
|
||||
import javax.xml.transform.TransformerFactory
|
||||
import javax.xml.transform.dom.DOMSource
|
||||
import javax.xml.transform.stream.StreamResult
|
||||
|
||||
val sourcePluginProjects =
|
||||
configurations
|
||||
.getByName("compileClasspath")
|
||||
.allDependencies
|
||||
.filterIsInstance<ProjectDependency>()
|
||||
.map { it.path }
|
||||
.filter { it.startsWith(":libs:") }
|
||||
.distinct()
|
||||
val sourcePluginProjectNames = sourcePluginProjects.map { it.substringAfterLast(":") }.toSet()
|
||||
sourcePluginProjects.forEach { evaluationDependsOn(it) }
|
||||
|
||||
val ideLibs: Configuration by
|
||||
configurations.creating {
|
||||
isCanBeResolved = true
|
||||
isCanBeConsumed = false
|
||||
}
|
||||
|
||||
configure<EclipseModel> {
|
||||
project {
|
||||
name = "${rootProject.name}-Plugin"
|
||||
}
|
||||
classpath {
|
||||
plusConfigurations.add(ideLibs)
|
||||
}
|
||||
}
|
||||
|
||||
val ideLibDir = layout.buildDirectory.dir("ide-libs")
|
||||
val hashRegex = Regex("-[0-9a-fA-F]{10}(?=\\.jar$)") // Black magic.
|
||||
|
||||
val copyTasks = mutableListOf<TaskProvider<Copy>>()
|
||||
|
||||
sourcePluginProjects.forEach { path ->
|
||||
val sub = project(path)
|
||||
val archiveTaskName = if ("shadowJar" in sub.tasks.names) "shadowJar" else "jar"
|
||||
val archiveTask = sub.tasks.named<Jar>(archiveTaskName)
|
||||
val copyTask =
|
||||
tasks.register<Copy>("ideCopy${sub.name.replaceFirstChar(Char::titlecase)}") {
|
||||
dependsOn(archiveTask)
|
||||
from(archiveTask.flatMap { it.archiveFile })
|
||||
into(ideLibDir)
|
||||
rename { it.replace(hashRegex, "") } // Remove git commit hash from jarfile.
|
||||
}
|
||||
copyTasks += copyTask
|
||||
}
|
||||
|
||||
/* Ensure the jars exist before .classpath is generated */
|
||||
tasks.named("eclipseClasspath").configure { dependsOn(copyTasks) }
|
||||
|
||||
/* Supply those jars to the ideLibs configuration (after evaluation) */
|
||||
afterEvaluate { dependencies { add("ideLibs", fileTree(ideLibDir) { include("*.jar") }) } }
|
||||
|
||||
val injectIdeLibs =
|
||||
tasks.register("injectIdeLibs") {
|
||||
dependsOn("eclipse") // run after all eclipse files are generated
|
||||
doLast {
|
||||
val cpFile = file(".classpath")
|
||||
if (!cpFile.exists()) return@doLast
|
||||
|
||||
val jars = fileTree(ideLibDir.get()) { include("*.jar") }.files.sortedBy { it.name }
|
||||
if (jars.isEmpty()) return@doLast
|
||||
|
||||
// Parse DOM
|
||||
val dbf = DocumentBuilderFactory.newInstance()
|
||||
val doc = dbf.newDocumentBuilder().parse(cpFile)
|
||||
val root = doc.documentElement
|
||||
|
||||
// Helper to see if an entry already exists
|
||||
fun exists(path: String): Boolean =
|
||||
root.getElementsByTagName("classpathentry").let { list ->
|
||||
(0 until list.length).any { i ->
|
||||
val n = list.item(i)
|
||||
val kind = n.attributes?.getNamedItem("kind")?.nodeValue
|
||||
val p = n.attributes?.getNamedItem("path")?.nodeValue
|
||||
kind == "lib" && p == path
|
||||
}
|
||||
}
|
||||
|
||||
// Remove any entry that points to ide-libs dir or unresolved :libs: project refs.
|
||||
val toRemove = mutableListOf<org.w3c.dom.Node>()
|
||||
val list = root.getElementsByTagName("classpathentry")
|
||||
val dirPath = ideLibDir.get().asFile.absolutePath
|
||||
for (i in 0 until list.length) {
|
||||
val n = list.item(i)
|
||||
val kind = n.attributes?.getNamedItem("kind")?.nodeValue
|
||||
val p = n.attributes?.getNamedItem("path")?.nodeValue ?: ""
|
||||
val isIdeLibEntry = kind == "lib" && (p == dirPath || p.startsWith("$dirPath/"))
|
||||
val sourceProjectPath = p.removePrefix("/")
|
||||
val isHalfImportedSourceModule = kind == "src" && p.startsWith("/libs:")
|
||||
val isSourcePluginModule = kind == "src" && sourceProjectPath in sourcePluginProjectNames
|
||||
if (isIdeLibEntry || isHalfImportedSourceModule || isSourcePluginModule) {
|
||||
toRemove += n
|
||||
}
|
||||
}
|
||||
toRemove.forEach { root.removeChild(it) }
|
||||
|
||||
// Append our jar entries LAST
|
||||
jars.forEach { f ->
|
||||
val abs = f.absolutePath
|
||||
if (!exists(abs)) {
|
||||
val entry = doc.createElement("classpathentry")
|
||||
entry.setAttribute("kind", "lib")
|
||||
entry.setAttribute("path", abs)
|
||||
root.appendChild(entry)
|
||||
}
|
||||
}
|
||||
|
||||
// Write back pretty
|
||||
val tf =
|
||||
TransformerFactory.newInstance().newTransformer().apply {
|
||||
setOutputProperty(OutputKeys.INDENT, "yes")
|
||||
setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "1")
|
||||
setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no")
|
||||
setOutputProperty(OutputKeys.ENCODING, "UTF-8")
|
||||
}
|
||||
Files.newBufferedWriter(cpFile.toPath()).use { w -> tf.transform(DOMSource(doc), StreamResult(w)) }
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named("eclipse").configure { finalizedBy(injectIdeLibs) }
|
||||
|
||||
val eclipseModel = extensions.getByType<EclipseModel>()
|
||||
|
||||
fun Project.addResolvableEclipseConfigs() {
|
||||
val jarAttr =
|
||||
objects.named(org.gradle.api.attributes.LibraryElements::class, org.gradle.api.attributes.LibraryElements.JAR)
|
||||
val apiAttr = objects.named(org.gradle.api.attributes.Usage::class, org.gradle.api.attributes.Usage.JAVA_API)
|
||||
|
||||
val compileOnlyRes =
|
||||
configurations.create("eclipseCompileOnly") {
|
||||
extendsFrom(configurations.getByName("compileOnly"))
|
||||
isCanBeResolved = true
|
||||
isCanBeConsumed = false
|
||||
attributes.attribute(org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE, apiAttr)
|
||||
attributes.attribute(org.gradle.api.attributes.LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, jarAttr)
|
||||
}
|
||||
val compileOnlyApiRes =
|
||||
configurations.create("eclipseCompileOnlyApi") {
|
||||
extendsFrom(configurations.getByName("compileOnlyApi"))
|
||||
isCanBeResolved = true
|
||||
isCanBeConsumed = false
|
||||
attributes.attribute(org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE, apiAttr)
|
||||
attributes.attribute(org.gradle.api.attributes.LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, jarAttr)
|
||||
}
|
||||
eclipseModel.classpath.plusConfigurations.addAll(listOf(compileOnlyRes, compileOnlyApiRes))
|
||||
}
|
||||
|
||||
addResolvableEclipseConfigs()
|
||||
Vendored
BIN
Binary file not shown.
+7
@@ -0,0 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
@@ -0,0 +1,251 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
} >&2
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH="\\\"\\\""
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
Vendored
+94
@@ -0,0 +1,94 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
@rem SPDX-License-Identifier: Apache-2.0
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser 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.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
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) <year> <name of author>
|
||||
|
||||
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-1301 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 Lesser General
|
||||
Public License instead of this License.
|
||||
Binary file not shown.
@@ -0,0 +1,174 @@
|
||||
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.
|
||||
Binary file not shown.
Submodule
+1
Submodule libs/Utilities-OG added at 8b5c86cc9c.
@@ -1,169 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>de.myzelyam</groupId>
|
||||
<artifactId>SuperVanish</artifactId>
|
||||
<version>6.0.5</version>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>cubekrowd-repo</id>
|
||||
<name>cubekrowd-public-releases</name>
|
||||
<url>https://mavenrepo.cubekrowd.net/artifactory/public-release-local/</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>cubekrowd-repo</id>
|
||||
<name>cubekrowd-public-snapshots</name>
|
||||
<url>https://mavenrepo.cubekrowd.net/artifactory/public-snapshot-local/</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.7.0</version>
|
||||
<configuration>
|
||||
<source>1.7</source>
|
||||
<target>1.7</target>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.16.16</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<version>2.8.2</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spigot-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>mvdw-software</id>
|
||||
<name>MVdW Public Repositories</name>
|
||||
<url>http://repo.mvdw-software.be/content/groups/public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>ess-repo</id>
|
||||
<url>http://repo.ess3.net/content/groups/essentials</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>dmulloy2-repo</id>
|
||||
<url>http://repo.dmulloy2.net/content/groups/public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>vault-repo</id>
|
||||
<url>http://nexus.hc.to/content/repositories/pub_releases</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>everything</id>
|
||||
<url>http://repo.citizensnpcs.co</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>placeholderapi</id>
|
||||
<url>http://repo.extendedclip.com/content/repositories/placeholderapi/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<!--Spigot API-->
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.12.2-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!--Lombok-->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.16.16</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!--Essentials API-->
|
||||
<dependency>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>Essentials</artifactId>
|
||||
<version>2.14-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<!--ProtocolLib-->
|
||||
<dependency>
|
||||
<groupId>com.comphenix.protocol</groupId>
|
||||
<artifactId>ProtocolLib-API</artifactId>
|
||||
<version>4.4.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<!--Vault API-->
|
||||
<dependency>
|
||||
<groupId>net.milkbowl.vault</groupId>
|
||||
<artifactId>VaultAPI</artifactId>
|
||||
<version>1.6</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!--Citizens API-->
|
||||
<dependency>
|
||||
<groupId>net.citizensnpcs</groupId>
|
||||
<artifactId>citizensapi</artifactId>
|
||||
<version>2.0.22-SNAPSHOT</version>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
<!--TrailGUI-->
|
||||
<dependency>
|
||||
<groupId>ca.jamiesinn.trailgui</groupId>
|
||||
<artifactId>TrailGUI</artifactId>
|
||||
<scope>system</scope>
|
||||
<systemPath>${basedir}/dependencies/TrailGUI-5.15-SNAPSHOT.jar</systemPath>
|
||||
<version>1.0</version>
|
||||
</dependency>
|
||||
<!--Dynmap-->
|
||||
<dependency>
|
||||
<groupId>org.dynmap</groupId>
|
||||
<artifactId>Dynmap</artifactId>
|
||||
<scope>system</scope>
|
||||
<systemPath>${basedir}/dependencies/dynmap-2.5.jar</systemPath>
|
||||
<version>1.0</version>
|
||||
</dependency>
|
||||
<!--SuperTrails-->
|
||||
<dependency>
|
||||
<groupId>me.kvq.plugin.trails</groupId>
|
||||
<artifactId>SuperTrails</artifactId>
|
||||
<scope>system</scope>
|
||||
<systemPath>${basedir}/dependencies/SuperTrails.jar</systemPath>
|
||||
<version>1.0</version>
|
||||
</dependency>
|
||||
<!--MVdWPlaceholderAPI-->
|
||||
<dependency>
|
||||
<groupId>be.maximvdw</groupId>
|
||||
<artifactId>MVdWPlaceholderAPI</artifactId>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!--PlaceholderAPI-->
|
||||
<dependency>
|
||||
<groupId>me.clip</groupId>
|
||||
<artifactId>placeholderapi</artifactId>
|
||||
<version>2.8.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,13 @@
|
||||
rootProject.name = "Vanish-OG"
|
||||
|
||||
ProcessBuilder("sh", "bootstrap.sh").directory(rootDir).inheritIO().start().let {
|
||||
if (it.waitFor() != 0) throw GradleException("bootstrap.sh failed")
|
||||
}
|
||||
|
||||
file("libs")
|
||||
.listFiles()
|
||||
?.filter { it.isDirectory && !it.name.startsWith(".") }
|
||||
?.forEach { dir ->
|
||||
include(":libs:${dir.name}")
|
||||
project(":libs:${dir.name}").projectDir = dir
|
||||
}
|
||||
@@ -20,34 +20,49 @@ public class PlayerHideEvent extends PlayerEvent implements Cancellable {
|
||||
private boolean isCancelled = false;
|
||||
|
||||
public PlayerHideEvent(Player p, boolean silent) {
|
||||
|
||||
super(p);
|
||||
this.silent = silent;
|
||||
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
|
||||
return handlers;
|
||||
|
||||
}
|
||||
|
||||
public boolean isSilent() {
|
||||
|
||||
return silent;
|
||||
|
||||
}
|
||||
|
||||
public void setSilent(boolean silent) {
|
||||
|
||||
this.silent = silent;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
|
||||
return isCancelled;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
|
||||
isCancelled = cancel;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
|
||||
return handlers;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,34 +20,49 @@ public class PlayerShowEvent extends PlayerEvent implements Cancellable {
|
||||
private boolean isCancelled = false;
|
||||
|
||||
public PlayerShowEvent(Player p, boolean silent) {
|
||||
|
||||
super(p);
|
||||
this.silent = silent;
|
||||
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
|
||||
return handlers;
|
||||
|
||||
}
|
||||
|
||||
public boolean isSilent() {
|
||||
|
||||
return silent;
|
||||
|
||||
}
|
||||
|
||||
public void setSilent(boolean silent) {
|
||||
|
||||
this.silent = silent;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
|
||||
return isCancelled;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
|
||||
isCancelled = cancel;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
|
||||
return handlers;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
package de.myzelyam.api.vanish;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
@@ -25,19 +27,31 @@ public class PlayerVanishStateChangeEvent extends Event implements Cancellable {
|
||||
private boolean isCancelled = false;
|
||||
|
||||
public PlayerVanishStateChangeEvent(UUID uuid, String name, boolean vanishing, String cause) {
|
||||
|
||||
this.vanishing = vanishing;
|
||||
this.uuid = uuid;
|
||||
this.name = name;
|
||||
this.cause = cause;
|
||||
|
||||
}
|
||||
|
||||
public PlayerVanishStateChangeEvent(Player player, boolean vanishing, String cause) {
|
||||
|
||||
this(player.getUniqueId(), player.getName(), vanishing, cause);
|
||||
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
|
||||
return handlers;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
|
||||
return isCancelled;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -45,41 +59,65 @@ public class PlayerVanishStateChangeEvent extends Event implements Cancellable {
|
||||
*/
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
|
||||
isCancelled = cancel;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TRUE if the player is vanishing, FALSE if the player is reappearing
|
||||
*/
|
||||
public boolean isVanishing() {
|
||||
|
||||
return vanishing;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The name of the player who is vanishing/reappearing
|
||||
*/
|
||||
public String getName() {
|
||||
|
||||
return name;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The UUID of the player who is vanishing/reappearing
|
||||
*/
|
||||
public UUID getUUID() {
|
||||
|
||||
return uuid;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The name of the command sender who caused the vanish state change or null if the cause is
|
||||
* either not specified or it's SuperVanish itself, please note that if this returns 'CONSOLE' then it's
|
||||
* the console which caused this state change
|
||||
* @return The Bukkit Player who is vanishing/reappearing, or null if the player
|
||||
* is not currently online
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
|
||||
return Bukkit.getPlayer(uuid);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The name of the command sender who caused the vanish state change or
|
||||
* null if the cause is either not specified or it's SuperVanish itself,
|
||||
* please note that if this returns 'CONSOLE' then it's the console
|
||||
* which caused this state change
|
||||
*/
|
||||
public String getCause() {
|
||||
|
||||
return cause;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
|
||||
return handlers;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,20 +18,29 @@ public class PostPlayerHideEvent extends PlayerEvent {
|
||||
private final boolean silent;
|
||||
|
||||
public PostPlayerHideEvent(Player p, boolean silent) {
|
||||
|
||||
super(p);
|
||||
this.silent = silent;
|
||||
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
|
||||
return handlers;
|
||||
|
||||
}
|
||||
|
||||
public boolean isSilent() {
|
||||
|
||||
return silent;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
|
||||
return handlers;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,20 +18,29 @@ public class PostPlayerShowEvent extends PlayerEvent {
|
||||
private final boolean silent;
|
||||
|
||||
public PostPlayerShowEvent(Player p, boolean silent) {
|
||||
|
||||
super(p);
|
||||
this.silent = silent;
|
||||
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
|
||||
return handlers;
|
||||
|
||||
}
|
||||
|
||||
public boolean isSilent() {
|
||||
|
||||
return silent;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
|
||||
return handlers;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -30,38 +30,45 @@ public class VanishAPI {
|
||||
* @return A collection of the UUIDs of all online vanished players
|
||||
*/
|
||||
public static List<UUID> getInvisiblePlayers() {
|
||||
|
||||
return new ArrayList<>(PLUGIN.getVanishStateMgr().getOnlineVanishedPlayers());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A collection of the UUIDs of all vanished players, both online and offline players
|
||||
* @return A collection of the UUIDs of all vanished players, both online and
|
||||
* offline players
|
||||
*/
|
||||
public static List<UUID> getAllInvisiblePlayers() {
|
||||
|
||||
return new ArrayList<>(PLUGIN.getVanishStateMgr().getVanishedPlayers());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Player must be online for this to return true if MySQL is enabled
|
||||
*
|
||||
* @param p - the player.
|
||||
* @return TRUE if the player is invisible, FALSE otherwise.
|
||||
*/
|
||||
public static boolean isInvisible(Player p) {
|
||||
Validation.checkNotNull("Player cannot be null!", p);
|
||||
return PLUGIN.getVanishStateMgr().isVanished(p.getUniqueId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a player is invisible, online or not
|
||||
* <p/>
|
||||
* Deprecated: Will cause minor lag if mysql is enabled, use asynchronously or sparingly
|
||||
* Checks if a player is vanished.
|
||||
*
|
||||
* @param uuid - the player's UUID.
|
||||
* @return TRUE if the player is invisible, FALSE otherwise.
|
||||
* @return TRUE if the player is vanished, FALSE otherwise.
|
||||
*/
|
||||
public static boolean isInvisibleOffline(UUID uuid) {
|
||||
public static boolean isVanished(UUID uuid) {
|
||||
|
||||
Validation.checkNotNull("UUID cannot be null!", uuid);
|
||||
return PLUGIN.getVanishStateMgr().isVanished(uuid);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a player is vanished.
|
||||
*
|
||||
* @param player - the player.
|
||||
* @return TRUE if the player is vanished, FALSE otherwise.
|
||||
*/
|
||||
public static boolean isVanished(Player player) {
|
||||
|
||||
Validation.checkNotNull("Player cannot be null!", player);
|
||||
return PLUGIN.getVanishStateMgr().isVanished(player);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,8 +77,10 @@ public class VanishAPI {
|
||||
* @param p - the player.
|
||||
*/
|
||||
public static void hidePlayer(Player p) {
|
||||
|
||||
Validation.checkNotNull("Player cannot be null!", p);
|
||||
PLUGIN.getVisibilityChanger().hidePlayer(p);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,8 +89,10 @@ public class VanishAPI {
|
||||
* @param p - the player.
|
||||
*/
|
||||
public static void showPlayer(Player p) {
|
||||
|
||||
Validation.checkNotNull("Player cannot be null!", p);
|
||||
PLUGIN.getVisibilityChanger().showPlayer(p);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,33 +100,43 @@ public class VanishAPI {
|
||||
*
|
||||
* @param viewer - the viewer
|
||||
* @param viewed - the viewed player
|
||||
* @return TRUE if viewed is not vanished or viewer has the permission to see viewed
|
||||
* @return TRUE if viewed is not vanished or viewer has the permission to see
|
||||
* viewed
|
||||
*/
|
||||
public static boolean canSee(Player viewer, Player viewed) {
|
||||
|
||||
return PLUGIN.canSee(viewer, viewed);
|
||||
|
||||
}
|
||||
|
||||
public static FileConfiguration getConfiguration() {
|
||||
|
||||
return PLUGIN.getSettings();
|
||||
|
||||
}
|
||||
|
||||
public static FileConfiguration getMessages() {
|
||||
return PLUGIN.getMessages();
|
||||
}
|
||||
|
||||
public static FileConfiguration getPlayerData() {
|
||||
return PLUGIN.getPlayerData();
|
||||
return PLUGIN.getMessages();
|
||||
|
||||
}
|
||||
|
||||
public static void reloadConfig() {
|
||||
|
||||
PLUGIN.reload();
|
||||
|
||||
}
|
||||
|
||||
public static SuperVanish getPlugin() {
|
||||
|
||||
return PLUGIN;
|
||||
|
||||
}
|
||||
|
||||
public static void setPlugin(SuperVanish plugin) {
|
||||
|
||||
VanishAPI.PLUGIN = plugin;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,48 +18,64 @@ public class LayeredPermissionChecker {
|
||||
private final FileConfiguration settings;
|
||||
|
||||
public LayeredPermissionChecker(SuperVanish plugin) {
|
||||
|
||||
this.plugin = plugin;
|
||||
settings = plugin.getSettings();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TRUE if sender has *permission* to use /sv on, else FALSE; TRUE doesn't mean that sender can
|
||||
* actually use /sv on
|
||||
* @return TRUE if sender has *permission* to use /sv on, else FALSE; TRUE
|
||||
* doesn't mean that sender can actually use /sv on
|
||||
*/
|
||||
public boolean hasPermissionToVanish(CommandSender sender) {
|
||||
if (settings.getBoolean(
|
||||
"IndicationFeatures.LayeredPermissions.LayeredSeeAndUsePermissions", false)) {
|
||||
if (sender.hasPermission("sv.use")) return true;
|
||||
|
||||
if (settings.getBoolean("IndicationFeatures.LayeredPermissions.LayeredSeeAndUsePermissions", false)) {
|
||||
|
||||
if (sender.hasPermission("sv.use"))
|
||||
return true;
|
||||
int permissionLevel;
|
||||
if (sender instanceof Player)
|
||||
permissionLevel = plugin.getVanishPlayer((Player) sender).getUsePermissionLevel();
|
||||
else permissionLevel = getLayeredPermissionLevel(sender, "use");
|
||||
else
|
||||
permissionLevel = getLayeredPermissionLevel(sender, "use");
|
||||
return permissionLevel > 0 && sender.hasPermission("sv.use.level" + permissionLevel);
|
||||
} else return sender.hasPermission("sv.use");
|
||||
|
||||
} else
|
||||
return sender.hasPermission("sv.use");
|
||||
|
||||
}
|
||||
|
||||
public boolean hasPermissionToSee(Player viewer, Player viewed) {
|
||||
|
||||
if (viewer == null)
|
||||
throw new IllegalArgumentException("viewer cannot be null");
|
||||
if (viewer == viewed) return true;
|
||||
if (settings.getBoolean(
|
||||
"IndicationFeatures.LayeredPermissions.LayeredSeeAndUsePermissions", false)) {
|
||||
if (viewer == viewed)
|
||||
return true;
|
||||
if (settings.getBoolean("IndicationFeatures.LayeredPermissions.LayeredSeeAndUsePermissions", false)) {
|
||||
|
||||
VanishPlayer vanishViewer = plugin.getVanishPlayer(viewer);
|
||||
VanishPlayer vanishViewed = plugin.getVanishPlayer(viewed);
|
||||
int viewerLevel = vanishViewer.getSeePermissionLevel();
|
||||
if (viewerLevel == 0) return false;
|
||||
if (viewerLevel == 0)
|
||||
return false;
|
||||
int viewedLevel = Math.max(1, vanishViewed.getUsePermissionLevel());
|
||||
return viewerLevel >= viewedLevel;
|
||||
|
||||
} else {
|
||||
|
||||
boolean enableSeePermission = settings
|
||||
.getBoolean("IndicationFeatures.LayeredPermissions.EnableSeePermission", true);
|
||||
return enableSeePermission && viewer.hasPermission("sv.see");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int getLayeredPermissionLevel(CommandSender sender, String permission) {
|
||||
boolean enableSeePermission = settings
|
||||
.getBoolean("IndicationFeatures.LayeredPermissions.EnableSeePermission", true);
|
||||
|
||||
boolean enableSeePermission = settings.getBoolean("IndicationFeatures.LayeredPermissions.EnableSeePermission",
|
||||
true);
|
||||
if (!enableSeePermission && permission.equalsIgnoreCase("see"))
|
||||
return 0;
|
||||
int maxLevel = settings.getInt("IndicationFeatures.LayeredPermissions.MaxLevel", 100);
|
||||
@@ -68,5 +84,7 @@ public class LayeredPermissionChecker {
|
||||
if (sender.hasPermission("sv." + permission + ".level" + i))
|
||||
level = i;
|
||||
return level;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,157 +8,297 @@
|
||||
|
||||
package de.myzelyam.supervanish;
|
||||
|
||||
import com.earth2me.essentials.Essentials;
|
||||
import com.earth2me.essentials.User;
|
||||
|
||||
import de.myzelyam.supervanish.hooks.PlaceholderAPIHook;
|
||||
import de.myzelyam.supervanish.utils.Validation;
|
||||
|
||||
import net.milkbowl.vault.chat.Chat;
|
||||
import net.milkbowl.vault.permission.Permission;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import com.earth2me.essentials.Essentials;
|
||||
import com.earth2me.essentials.User;
|
||||
|
||||
import be.maximvdw.placeholderapi.PlaceholderAPI;
|
||||
import de.myzelyam.supervanish.utils.Validation;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
import net.luckperms.api.LuckPerms;
|
||||
import net.luckperms.api.LuckPermsProvider;
|
||||
import net.luckperms.api.cacheddata.CachedMetaData;
|
||||
import net.trueog.utilitiesog.UtilitiesOG;
|
||||
|
||||
public class PlaceholderConverter {
|
||||
|
||||
private final SuperVanish plugin;
|
||||
private static final LegacyComponentSerializer LEGACY_SERIALIZER = LegacyComponentSerializer.legacySection();
|
||||
|
||||
public PlaceholderConverter(SuperVanish plugin) {
|
||||
this.plugin = plugin;
|
||||
|
||||
}
|
||||
|
||||
public String replacePlaceholders(String msg, Object... additionalPlayerInfo) {
|
||||
Validation.checkIsTrue("Failed to replace variables (Illegal arguments)",
|
||||
msg != null, additionalPlayerInfo != null);
|
||||
//noinspection ConstantConditions
|
||||
Validation.checkIsTrue(additionalPlayerInfo.length > 0);
|
||||
// check vararg
|
||||
final List<Object> additionalPlayerInfoList = Arrays
|
||||
.asList(additionalPlayerInfo);
|
||||
Object unspecifiedPlayer = additionalPlayerInfoList.get(0);
|
||||
String unspecifiedOtherPlayersName = null;
|
||||
if (additionalPlayerInfoList.size() > 1
|
||||
&& (additionalPlayerInfoList.get(1) instanceof String
|
||||
|| additionalPlayerInfoList.get(1) instanceof Player)) {
|
||||
unspecifiedOtherPlayersName = (String) (additionalPlayerInfoList
|
||||
.get(1) instanceof Player
|
||||
? ((Player) additionalPlayerInfoList.get(1)).getName()
|
||||
: additionalPlayerInfoList.get(1));
|
||||
}
|
||||
//noinspection ConstantConditions
|
||||
msg = msg.replace("\\n", "\n");
|
||||
// replace sender specific variables
|
||||
replaceVariables:
|
||||
{
|
||||
if (unspecifiedPlayer instanceof OfflinePlayer
|
||||
&& !(unspecifiedPlayer instanceof Player)) {
|
||||
// offline player
|
||||
OfflinePlayer specifiedPlayer = (OfflinePlayer) unspecifiedPlayer;
|
||||
// MVdWPlaceholderAPI
|
||||
if (Bukkit.getPluginManager().isPluginEnabled("MVdWPlaceholderAPI")
|
||||
&& plugin.getSettings().getBoolean("HookOptions.EnableMVdWPlaceholderAPIHook", true)) {
|
||||
String replaced = PlaceholderAPI.replacePlaceholders(specifiedPlayer, msg);
|
||||
msg = replaced == null ? msg : replaced;
|
||||
}
|
||||
// replace essentials nick names
|
||||
if (Bukkit.getPluginManager()
|
||||
.getPlugin("Essentials") != null) {
|
||||
msg = msg.replace("%nick%", specifiedPlayer.getName());
|
||||
}
|
||||
// replace general variables
|
||||
msg = msg.replace("%d%", specifiedPlayer.getName())
|
||||
.replace("%p%", specifiedPlayer.getName())
|
||||
.replace("%tab%", specifiedPlayer.getName());
|
||||
// replace other player's name if possible
|
||||
msg = msg.replace("%other%", unspecifiedOtherPlayersName != null
|
||||
? unspecifiedOtherPlayersName : "UNKNOWN");
|
||||
break replaceVariables;
|
||||
}
|
||||
if (unspecifiedPlayer instanceof Player) {
|
||||
// player
|
||||
Player specifiedPlayer = (Player) unspecifiedPlayer;
|
||||
// PlaceholderAPI
|
||||
if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")
|
||||
&& plugin.getSettings().getBoolean("HookOptions.EnablePlaceholderAPIHook", true)) {
|
||||
String replaced = PlaceholderAPIHook.translatePlaceholders(msg, specifiedPlayer);
|
||||
//noinspection ConstantConditions
|
||||
msg = replaced == null ? msg : replaced;
|
||||
}
|
||||
// MVdWPlaceholderAPI
|
||||
if (Bukkit.getPluginManager().isPluginEnabled("MVdWPlaceholderAPI")
|
||||
&& plugin.getSettings().getBoolean("HookOptions.EnableMVdWPlaceholderAPIHook", true)) {
|
||||
String replaced = PlaceholderAPI.replacePlaceholders(specifiedPlayer, msg);
|
||||
msg = replaced == null ? msg : replaced;
|
||||
}
|
||||
// replace essentials nick names
|
||||
if (Bukkit.getPluginManager().getPlugin("Essentials") != null) {
|
||||
Essentials ess = (Essentials) Bukkit.getServer()
|
||||
.getPluginManager().getPlugin("Essentials");
|
||||
User u = ess.getUser(specifiedPlayer);
|
||||
if (u != null)
|
||||
if (u.getNickname() != null)
|
||||
msg = msg.replace("%nick%", u.getNickname());
|
||||
}
|
||||
// replace vault info
|
||||
if (Bukkit.getPluginManager().getPlugin("Vault") != null) {
|
||||
RegisteredServiceProvider<Permission> permService = plugin.getServer()
|
||||
.getServicesManager().getRegistration(Permission.class);
|
||||
RegisteredServiceProvider<Chat> chatService = plugin.getServer()
|
||||
.getServicesManager().getRegistration(Chat.class);
|
||||
Permission permAPI = permService != null ? permService.getProvider() : null;
|
||||
Chat chatAPI = chatService != null ? chatService.getProvider() : null;
|
||||
try {
|
||||
if (permAPI != null) {
|
||||
String group = permAPI.getPrimaryGroup(specifiedPlayer);
|
||||
if (group != null)
|
||||
msg = msg.replace("%group%", group);
|
||||
}
|
||||
if (chatAPI != null) {
|
||||
String prefix = chatAPI.getPlayerPrefix(specifiedPlayer);
|
||||
String suffix = chatAPI.getPlayerSuffix(specifiedPlayer);
|
||||
if (prefix != null) {
|
||||
msg = msg.replace("%prefix%", prefix);
|
||||
}
|
||||
if (suffix != null) {
|
||||
msg = msg.replace("%suffix%", suffix);
|
||||
}
|
||||
}
|
||||
} catch (UnsupportedOperationException ignored) {
|
||||
}
|
||||
}
|
||||
// replace general variables
|
||||
msg = msg.replace("%d%", "" + specifiedPlayer.getDisplayName())
|
||||
.replace("%p%", "" + specifiedPlayer.getName())
|
||||
.replace("%tab%",
|
||||
"" + specifiedPlayer.getPlayerListName());
|
||||
// replace other player's name if possible
|
||||
msg = msg.replace("%other%", unspecifiedOtherPlayersName != null
|
||||
? unspecifiedOtherPlayersName : "UNKNOWN");
|
||||
|
||||
break replaceVariables;
|
||||
}
|
||||
if (unspecifiedPlayer instanceof CommandSender) {
|
||||
// console
|
||||
// replace general variables
|
||||
msg = msg.replace("%d%", "Console").replace("%p%", "Console")
|
||||
.replace("%tab%", "Console");
|
||||
// replace other player's name if possible
|
||||
msg = msg.replace("%other%", unspecifiedOtherPlayersName != null
|
||||
? unspecifiedOtherPlayersName : "UNKNOWN");
|
||||
}
|
||||
}
|
||||
// convert color codes
|
||||
msg = ChatColor.translateAlternateColorCodes('&', msg);
|
||||
return msg;
|
||||
return LEGACY_SERIALIZER.serialize(expandPlaceholders(msg, additionalPlayerInfo));
|
||||
|
||||
}
|
||||
|
||||
public Component expandPlaceholders(String msg, Object... additionalPlayerInfo) {
|
||||
|
||||
return expandPlaceholders(null, msg, additionalPlayerInfo);
|
||||
|
||||
}
|
||||
|
||||
public Component expandPlaceholders(CommandSender recipient, String msg, Object... additionalPlayerInfo) {
|
||||
|
||||
Validation.checkNotNull("Failed to replace variables (Illegal arguments)", msg, additionalPlayerInfo);
|
||||
final PlaceholderContext context = parseContext(additionalPlayerInfo);
|
||||
final String preparedMessage = applyInlinePlaceholders(msg.replace("\\n", "\n"), context);
|
||||
|
||||
if (recipient instanceof Player player) {
|
||||
|
||||
if (context.primaryPlayer != null) {
|
||||
|
||||
return UtilitiesOG.trueogExpand(preparedMessage, player, context.primaryPlayer);
|
||||
|
||||
}
|
||||
|
||||
return UtilitiesOG.trueogExpand(preparedMessage, player);
|
||||
|
||||
}
|
||||
|
||||
if (context.primaryPlayer != null) {
|
||||
|
||||
return UtilitiesOG.trueogExpand(preparedMessage, context.primaryPlayer);
|
||||
|
||||
}
|
||||
|
||||
return UtilitiesOG.trueogExpand(preparedMessage);
|
||||
|
||||
}
|
||||
|
||||
public static MessagePlaceholder placeholder(String name, Object value) {
|
||||
|
||||
return new MessagePlaceholder(name, value == null ? "" : String.valueOf(value));
|
||||
|
||||
}
|
||||
|
||||
private PlaceholderContext parseContext(Object... additionalPlayerInfo) {
|
||||
|
||||
final PlaceholderContext context = new PlaceholderContext();
|
||||
if (additionalPlayerInfo == null) {
|
||||
|
||||
return context;
|
||||
|
||||
}
|
||||
|
||||
for (Object entry : additionalPlayerInfo) {
|
||||
|
||||
if (entry instanceof MessagePlaceholder messagePlaceholder) {
|
||||
|
||||
context.inlinePlaceholders.add(messagePlaceholder);
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
if (context.primaryObject == null) {
|
||||
|
||||
context.primaryObject = entry;
|
||||
if (entry instanceof Player player) {
|
||||
|
||||
context.primaryPlayer = player;
|
||||
|
||||
}
|
||||
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
if (context.otherName == null && (entry instanceof Player || entry instanceof String)) {
|
||||
|
||||
if (entry instanceof Player player) {
|
||||
|
||||
context.otherName = player.getName();
|
||||
|
||||
} else {
|
||||
|
||||
context.otherName = String.valueOf(entry);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return context;
|
||||
|
||||
}
|
||||
|
||||
private String applyInlinePlaceholders(String message, PlaceholderContext context) {
|
||||
|
||||
message = replaceTag(message, "sv_player_name", getPrimaryName(context.primaryObject));
|
||||
message = replaceTag(message, "sv_player_display_name", getPrimaryDisplayName(context.primaryObject));
|
||||
message = replaceTag(message, "sv_player_tab_name", getPrimaryTabName(context.primaryObject));
|
||||
message = replaceTag(message, "sv_player_prefix", getPrimaryPrefix(context.primaryObject));
|
||||
message = replaceTag(message, "sv_player_suffix", getPrimarySuffix(context.primaryObject));
|
||||
message = replaceTag(message, "sv_player_group", getPrimaryGroup(context.primaryObject));
|
||||
message = replaceTag(message, "sv_player_nick", getPrimaryNick(context.primaryObject));
|
||||
message = replaceTag(message, "sv_other_name", context.otherName != null ? context.otherName : "UNKNOWN");
|
||||
|
||||
for (MessagePlaceholder inlinePlaceholder : context.inlinePlaceholders) {
|
||||
|
||||
message = replaceTag(message, inlinePlaceholder.name(), inlinePlaceholder.value());
|
||||
|
||||
}
|
||||
|
||||
return message;
|
||||
|
||||
}
|
||||
|
||||
private String getPrimaryName(Object primaryObject) {
|
||||
|
||||
if (primaryObject instanceof OfflinePlayer offlinePlayer) {
|
||||
|
||||
return offlinePlayer.getName();
|
||||
|
||||
}
|
||||
|
||||
if (primaryObject instanceof CommandSender) {
|
||||
|
||||
return "Console";
|
||||
|
||||
}
|
||||
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
private String getPrimaryDisplayName(Object primaryObject) {
|
||||
|
||||
if (primaryObject instanceof Player player) {
|
||||
|
||||
return LEGACY_SERIALIZER.serialize(player.displayName());
|
||||
|
||||
}
|
||||
|
||||
return getPrimaryName(primaryObject);
|
||||
|
||||
}
|
||||
|
||||
private String getPrimaryTabName(Object primaryObject) {
|
||||
|
||||
if (primaryObject instanceof Player player) {
|
||||
|
||||
return LEGACY_SERIALIZER.serialize(player.playerListName());
|
||||
|
||||
}
|
||||
|
||||
return getPrimaryName(primaryObject);
|
||||
|
||||
}
|
||||
|
||||
private String getPrimaryNick(Object primaryObject) {
|
||||
|
||||
if (!(primaryObject instanceof Player player) || Bukkit.getPluginManager().getPlugin("Essentials") == null) {
|
||||
|
||||
return getPrimaryName(primaryObject);
|
||||
|
||||
}
|
||||
|
||||
final Essentials essentials = (Essentials) Bukkit.getServer().getPluginManager().getPlugin("Essentials");
|
||||
final User user = essentials.getUser(player);
|
||||
if (user == null || user.getNickname() == null) {
|
||||
|
||||
return player.getName();
|
||||
|
||||
}
|
||||
|
||||
return user.getNickname();
|
||||
|
||||
}
|
||||
|
||||
private String getPrimaryGroup(Object primaryObject) {
|
||||
|
||||
if (!(primaryObject instanceof OfflinePlayer offlinePlayer)) {
|
||||
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
if (Bukkit.getPluginManager().getPlugin("LuckPerms") == null) {
|
||||
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
final LuckPerms luckPerms = LuckPermsProvider.get();
|
||||
final net.luckperms.api.model.user.User user = luckPerms.getUserManager()
|
||||
.getUser(offlinePlayer.getUniqueId());
|
||||
return user == null ? "" : user.getPrimaryGroup();
|
||||
|
||||
} catch (IllegalStateException ignored) {
|
||||
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String getPrimaryPrefix(Object primaryObject) {
|
||||
|
||||
final CachedMetaData metaData = getPrimaryMetaData(primaryObject);
|
||||
return metaData == null || metaData.getPrefix() == null ? "" : metaData.getPrefix();
|
||||
|
||||
}
|
||||
|
||||
private String getPrimarySuffix(Object primaryObject) {
|
||||
|
||||
final CachedMetaData metaData = getPrimaryMetaData(primaryObject);
|
||||
return metaData == null || metaData.getSuffix() == null ? "" : metaData.getSuffix();
|
||||
|
||||
}
|
||||
|
||||
private CachedMetaData getPrimaryMetaData(Object primaryObject) {
|
||||
|
||||
if (!(primaryObject instanceof OfflinePlayer offlinePlayer)
|
||||
|| Bukkit.getPluginManager().getPlugin("LuckPerms") == null)
|
||||
{
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
final LuckPerms luckPerms = LuckPermsProvider.get();
|
||||
final net.luckperms.api.model.user.User user = luckPerms.getUserManager()
|
||||
.getUser(offlinePlayer.getUniqueId());
|
||||
return user == null ? null : user.getCachedData().getMetaData();
|
||||
|
||||
} catch (IllegalStateException ignored) {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String replaceTag(String message, String tagName, String value) {
|
||||
|
||||
return message.replace("<" + tagName + ">", value == null ? "" : value);
|
||||
|
||||
}
|
||||
|
||||
public record MessagePlaceholder(String name, String value) {
|
||||
}
|
||||
|
||||
private static final class PlaceholderContext {
|
||||
|
||||
private Object primaryObject;
|
||||
private Player primaryPlayer;
|
||||
private String otherName;
|
||||
private final List<MessagePlaceholder> inlinePlaceholders = new ArrayList<>();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,28 +8,13 @@
|
||||
|
||||
package de.myzelyam.supervanish;
|
||||
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
|
||||
import de.myzelyam.api.vanish.VanishAPI;
|
||||
import de.myzelyam.supervanish.commands.VanishCommand;
|
||||
import de.myzelyam.supervanish.config.ConfigMgr;
|
||||
import de.myzelyam.supervanish.events.GeneralEventHandler;
|
||||
import de.myzelyam.supervanish.events.JoinEvent;
|
||||
import de.myzelyam.supervanish.events.LoginEvent;
|
||||
import de.myzelyam.supervanish.events.PlayerBlockModifyEventHandler;
|
||||
import de.myzelyam.supervanish.events.QuitEvent;
|
||||
import de.myzelyam.supervanish.events.WorldChangeEvent;
|
||||
import de.myzelyam.supervanish.features.FeatureMgr;
|
||||
import de.myzelyam.supervanish.hooks.PluginHookMgr;
|
||||
import de.myzelyam.supervanish.net.UpdateNotifier;
|
||||
import de.myzelyam.supervanish.utils.ExceptionLogger;
|
||||
import de.myzelyam.supervanish.utils.VersionUtil;
|
||||
import de.myzelyam.supervanish.visibility.ActionBarMgr;
|
||||
import de.myzelyam.supervanish.visibility.FileVanishStateMgr;
|
||||
import de.myzelyam.supervanish.visibility.ServerListPacketListener;
|
||||
import de.myzelyam.supervanish.visibility.VisibilityChanger;
|
||||
import de.myzelyam.supervanish.visibility.hiders.PreventionHider;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -40,257 +25,610 @@ import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
|
||||
import lombok.Getter;
|
||||
import de.myzelyam.api.vanish.VanishAPI;
|
||||
import de.myzelyam.supervanish.commands.VanishCommand;
|
||||
import de.myzelyam.supervanish.config.ConfigMgr;
|
||||
import de.myzelyam.supervanish.features.FeatureMgr;
|
||||
import de.myzelyam.supervanish.hooks.PluginHookMgr;
|
||||
import de.myzelyam.supervanish.listeners.GeneralListener;
|
||||
import de.myzelyam.supervanish.listeners.JoinListener;
|
||||
import de.myzelyam.supervanish.listeners.LoginListener;
|
||||
import de.myzelyam.supervanish.listeners.PlayerBlockModifyListener;
|
||||
import de.myzelyam.supervanish.listeners.QuitListener;
|
||||
import de.myzelyam.supervanish.listeners.TabCompleteListener;
|
||||
import de.myzelyam.supervanish.listeners.WorldChangeListener;
|
||||
import de.myzelyam.supervanish.utils.ExceptionLogger;
|
||||
import de.myzelyam.supervanish.utils.BukkitPlayerHidingUtil;
|
||||
import de.myzelyam.supervanish.utils.VersionUtil;
|
||||
import de.myzelyam.supervanish.visibility.ActionBarMgr;
|
||||
import de.myzelyam.supervanish.visibility.ServerListPacketListener;
|
||||
import de.myzelyam.supervanish.visibility.VanishStateMgr;
|
||||
import de.myzelyam.supervanish.visibility.VisibilityChanger;
|
||||
import de.myzelyam.supervanish.visibility.YamlVanishStateRepository;
|
||||
import de.myzelyam.supervanish.visibility.hiders.PreventionHider;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
import net.trueog.utilitiesog.UtilitiesOG;
|
||||
|
||||
public class SuperVanish extends JavaPlugin implements SuperVanishPlugin {
|
||||
|
||||
public static final String[] NON_REQUIRED_SETTINGS_UPDATES = {"6.0.0", "6.0.1", "6.0.2", "6.0.3",
|
||||
"6.0.4"},
|
||||
NON_REQUIRED_MESSAGES_UPDATES = {"6.0.0", "6.0.1", "6.0.2", "6.0.3", "6.0.4"};
|
||||
public static final String[] NON_REQUIRED_MESSAGES_UPDATES = { "6.0.0", "6.0.1", "6.0.2", "6.0.3", "6.0.4", "6.0.5",
|
||||
"6.1.0", "6.1.1", "6.1.2", "6.1.3", "6.1.4", "6.1.5", "6.1.6", "6.1.7", "6.1.8", "6.2.0", "6.2.1", "6.2.2",
|
||||
"6.2.3", "6.2.4", "6.2.5", "6.2.6", "6.2.7", "6.2.8", "6.2.9", "6.2.10", "6.2.11", "6.2.12", "6.2.13",
|
||||
"6.2.14", "6.2.15", "6.2.16", "6.2.17", "6.2.18", "6.2.19", "6.2.20" };
|
||||
|
||||
@Getter
|
||||
private boolean useProtocolLib;
|
||||
@Getter
|
||||
private ActionBarMgr actionBarMgr;
|
||||
@Getter
|
||||
private FileVanishStateMgr vanishStateMgr;
|
||||
@Getter
|
||||
private VanishStateMgr vanishStateMgr;
|
||||
private VersionUtil versionUtil;
|
||||
@Getter
|
||||
private ConfigMgr configMgr;
|
||||
@Getter
|
||||
private FeatureMgr featureMgr;
|
||||
@Getter
|
||||
private PlaceholderConverter placeholderConverter;
|
||||
@Getter
|
||||
private VanishCommand command;
|
||||
@Getter
|
||||
private VisibilityChanger visibilityChanger;
|
||||
@Getter
|
||||
private UpdateNotifier updateNotifier;
|
||||
@Getter
|
||||
private LoginEvent loginEvent;
|
||||
@Getter
|
||||
private LoginListener loginListener;
|
||||
private LayeredPermissionChecker layeredPermissionChecker;
|
||||
private Set<VanishPlayer> vanishPlayers = new HashSet<>();
|
||||
private PluginHookMgr pluginHookMgr;
|
||||
private final Set<VanishPlayer> vanishPlayers = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
|
||||
try {
|
||||
|
||||
useProtocolLib = getServer().getPluginManager().isPluginEnabled("ProtocolLib");
|
||||
if (!useProtocolLib) log(Level.INFO,
|
||||
"Please install ProtocolLib to be able to use all SuperVanish features: " +
|
||||
"https://www.spigotmc.org/resources/protocollib.1997/");
|
||||
if (!useProtocolLib) {
|
||||
|
||||
log(Level.INFO, "Please install ProtocolLib to be able to use all Vanish-OG features: "
|
||||
+ "https://www.spigotmc.org/resources/protocollib.1997/");
|
||||
|
||||
}
|
||||
|
||||
configMgr = new ConfigMgr(this);
|
||||
configMgr.prepareFiles();
|
||||
placeholderConverter = new PlaceholderConverter(this);
|
||||
layeredPermissionChecker = new LayeredPermissionChecker(this);
|
||||
command = new VanishCommand(this);
|
||||
versionUtil = new VersionUtil(this);
|
||||
vanishStateMgr = new FileVanishStateMgr(this);
|
||||
if (getSettings().getBoolean("MiscellaneousOptions.UpdateChecker.Enable", true))
|
||||
updateNotifier = new UpdateNotifier(this);
|
||||
vanishStateMgr = new VanishStateMgr(this, new YamlVanishStateRepository(this));
|
||||
configMgr.checkFilesForLeftOvers();
|
||||
|
||||
visibilityChanger = new VisibilityChanger(new PreventionHider(this), this);
|
||||
if (versionUtil.isOneDotXOrHigher(8) && useProtocolLib)
|
||||
if (versionUtil.isOneDotXOrHigher(8) && useProtocolLib) {
|
||||
|
||||
actionBarMgr = new ActionBarMgr(this);
|
||||
if (useProtocolLib && ServerListPacketListener.isEnabled(this))
|
||||
|
||||
}
|
||||
|
||||
if (useProtocolLib && ServerListPacketListener.isEnabled(this)) {
|
||||
|
||||
ServerListPacketListener.register(this);
|
||||
|
||||
}
|
||||
|
||||
registerEvents();
|
||||
new PluginHookMgr(this);
|
||||
pluginHookMgr = new PluginHookMgr(this);
|
||||
featureMgr = new FeatureMgr(this);
|
||||
featureMgr.enableFeatures();
|
||||
if (!Bukkit.getOnlinePlayers().isEmpty())
|
||||
if (!Bukkit.getOnlinePlayers().isEmpty()) {
|
||||
|
||||
onReload();
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
logException(e);
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
VanishAPI.setPlugin(this);
|
||||
|
||||
} catch (NoSuchMethodError ignored) {
|
||||
|
||||
// API already loaded by other plugin
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
|
||||
try {
|
||||
if (featureMgr != null) featureMgr.disableFeatures();
|
||||
|
||||
// Unhook from TAB-OG before tearing down VanishStateMgr so no stale
|
||||
// handler survives across reload with a disabled plugin reference.
|
||||
if (pluginHookMgr != null) {
|
||||
|
||||
pluginHookMgr.onSuperVanishDisable();
|
||||
|
||||
}
|
||||
|
||||
forceShowAllPlayers();
|
||||
if (visibilityChanger != null) {
|
||||
|
||||
visibilityChanger.getHider().clearHiddenState();
|
||||
|
||||
}
|
||||
|
||||
if (featureMgr != null) {
|
||||
|
||||
featureMgr.disableFeatures();
|
||||
|
||||
}
|
||||
|
||||
if (vanishStateMgr != null) {
|
||||
|
||||
vanishStateMgr.close();
|
||||
|
||||
}
|
||||
|
||||
vanishPlayers.clear();
|
||||
VanishAPI.setPlugin(null);
|
||||
|
||||
} catch (Throwable e) {
|
||||
if (e instanceof ThreadDeath || e instanceof VirtualMachineError) throw e;
|
||||
if (!(e instanceof NoClassDefFoundError | e instanceof NoSuchMethodError)) {
|
||||
e.printStackTrace();
|
||||
|
||||
if (e instanceof ThreadDeath || e instanceof VirtualMachineError) {
|
||||
|
||||
throw e;
|
||||
|
||||
}
|
||||
|
||||
if (!(e instanceof NoClassDefFoundError | e instanceof NoSuchMethodError)) {
|
||||
|
||||
e.printStackTrace();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void onReload() {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
boolean itemPickUps = getPlayerData().getBoolean(
|
||||
"PlayerData." + player.getUniqueId() + ".itemPickUps",
|
||||
|
||||
forceShowAllPlayers();
|
||||
visibilityChanger.getHider().clearHiddenState();
|
||||
|
||||
Bukkit.getOnlinePlayers().forEach((Player player) -> {
|
||||
|
||||
final boolean itemPickUps = vanishStateMgr.getItemPickUps(player.getUniqueId(),
|
||||
getSettings().getBoolean("InvisibilityFeatures.DefaultPickUpItemsOption"));
|
||||
boolean vanished = vanishStateMgr.isVanished(player.getUniqueId());
|
||||
final boolean vanished = vanishStateMgr.isVanished(player.getUniqueId());
|
||||
createVanishPlayer(player, itemPickUps);
|
||||
if (vanished) {
|
||||
for (Player onlinePlayer : Bukkit.getOnlinePlayers())
|
||||
if (!hasPermissionToSee(onlinePlayer, player))
|
||||
visibilityChanger.getHider().setHidden(player, onlinePlayer, true);
|
||||
}
|
||||
if (getSettings().getBoolean("MessageOptions.DisplayActionBar")
|
||||
&& vanished && actionBarMgr != null) {
|
||||
if (vanished)
|
||||
player.setMetadata("vanished", new FixedMetadataValue(this, true));
|
||||
else
|
||||
player.removeMetadata("vanished", this);
|
||||
|
||||
if (getSettings().getBoolean("MessageOptions.DisplayActionBar") && vanished && actionBarMgr != null) {
|
||||
|
||||
actionBarMgr.addActionBar(player);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
reconcileAllVisibilities();
|
||||
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
|
||||
getServer().getScheduler().cancelTasks(this);
|
||||
HandlerList.unregisterAll(this);
|
||||
if (useProtocolLib)
|
||||
if (useProtocolLib) {
|
||||
|
||||
ProtocolLibrary.getProtocolManager().removePacketListeners(this);
|
||||
|
||||
}
|
||||
|
||||
onDisable();
|
||||
onEnable();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
||||
|
||||
return this.command.tabComplete(command, sender, alias, args);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
|
||||
this.command.execute(command, sender, label, args);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
private void registerEvents() {
|
||||
PluginManager pluginManager = getServer().getPluginManager();
|
||||
pluginManager.registerEvents(new GeneralEventHandler(this), this);
|
||||
pluginManager.registerEvents(new PlayerBlockModifyEventHandler(this), this);
|
||||
pluginManager.registerEvents(new WorldChangeEvent(this), this);
|
||||
pluginManager.registerEvents(loginEvent = new LoginEvent(this), this);
|
||||
JoinEvent joinEvent = new JoinEvent(this);
|
||||
pluginManager.registerEvent(PlayerJoinEvent.class, joinEvent,
|
||||
getEventPriority(PlayerJoinEvent.class), joinEvent, this, false);
|
||||
QuitEvent quitEvent = new QuitEvent(this);
|
||||
pluginManager.registerEvent(PlayerQuitEvent.class, quitEvent,
|
||||
getEventPriority(PlayerQuitEvent.class), quitEvent, this, false);
|
||||
|
||||
final PluginManager pluginManager = getServer().getPluginManager();
|
||||
pluginManager.registerEvents(new GeneralListener(this), this);
|
||||
pluginManager.registerEvents(new PlayerBlockModifyListener(this), this);
|
||||
pluginManager.registerEvents(new WorldChangeListener(this), this);
|
||||
if (versionUtil.isOneDotXOrHigher(10)) {
|
||||
|
||||
pluginManager.registerEvents(new TabCompleteListener(this), this);
|
||||
|
||||
}
|
||||
|
||||
pluginManager.registerEvents(loginListener = new LoginListener(this), this);
|
||||
final JoinListener joinListener = new JoinListener(this);
|
||||
pluginManager.registerEvent(PlayerJoinEvent.class, joinListener, getEventPriority(PlayerJoinEvent.class),
|
||||
joinListener, this, false);
|
||||
final QuitListener quitListener = new QuitListener(this);
|
||||
pluginManager.registerEvent(PlayerQuitEvent.class, quitListener, getEventPriority(PlayerQuitEvent.class),
|
||||
quitListener, this, false);
|
||||
|
||||
}
|
||||
|
||||
private EventPriority getEventPriority(Class<? extends Event> eventClass) {
|
||||
|
||||
try {
|
||||
String eventName = eventClass.getSimpleName();
|
||||
String configString = getSettings().getString("CompatibilityOptions." + eventName + "Priority");
|
||||
if (configString == null) return EventPriority.NORMAL;
|
||||
EventPriority priority = EventPriority.valueOf(configString);
|
||||
return priority;
|
||||
|
||||
final String eventName = eventClass.getSimpleName();
|
||||
final String configString = getSettings().getString("CompatibilityOptions." + eventName + "Priority");
|
||||
if (configString == null) {
|
||||
|
||||
return EventPriority.NORMAL;
|
||||
|
||||
}
|
||||
|
||||
return EventPriority.valueOf(configString);
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
logException(e);
|
||||
return EventPriority.NORMAL;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String replacePlaceholders(String msg, Object... additionalPlayerInfo) {
|
||||
|
||||
return placeholderConverter.replacePlaceholders(msg, additionalPlayerInfo);
|
||||
|
||||
}
|
||||
|
||||
public Component expandPlaceholders(CommandSender recipient, String msg, Object... additionalPlayerInfo) {
|
||||
|
||||
return placeholderConverter.expandPlaceholders(recipient, msg, additionalPlayerInfo);
|
||||
|
||||
}
|
||||
|
||||
public String getMessage(String path) {
|
||||
|
||||
String message = getMessages().getString("Messages." + path);
|
||||
if (message == null) {
|
||||
|
||||
message = configMgr.getMessagesFile().getDefaultConfig().getString("Messages." + path);
|
||||
|
||||
}
|
||||
|
||||
return message;
|
||||
|
||||
}
|
||||
|
||||
public VanishPlayer getVanishPlayer(Player player) {
|
||||
|
||||
for (VanishPlayer vanishPlayer : vanishPlayers) {
|
||||
if (vanishPlayer.getPlayer().equals(player)) {
|
||||
|
||||
if (vanishPlayer.getPlayerUUID().equals(player.getUniqueId())) {
|
||||
|
||||
return vanishPlayer;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ensure that there is always a vanish player
|
||||
boolean itemPickUps = getPlayerData().getBoolean(
|
||||
"PlayerData." + player.getUniqueId() + ".itemPickUps",
|
||||
final boolean itemPickUps = vanishStateMgr.getItemPickUps(player.getUniqueId(),
|
||||
getSettings().getBoolean("InvisibilityFeatures.DefaultPickUpItemsOption"));
|
||||
final VanishPlayer vanishPlayer = new VanishPlayer(player, this, itemPickUps);
|
||||
vanishPlayers.add(vanishPlayer);
|
||||
return vanishPlayer;
|
||||
|
||||
}
|
||||
|
||||
public void createVanishPlayer(Player player, boolean itemPickUps) {
|
||||
VanishPlayer vanishPlayer = new VanishPlayer(player, this, itemPickUps);
|
||||
|
||||
final VanishPlayer vanishPlayer = new VanishPlayer(player, this, itemPickUps);
|
||||
vanishPlayers.add(vanishPlayer);
|
||||
|
||||
}
|
||||
|
||||
public void removeVanishPlayer(VanishPlayer vanishPlayer) {
|
||||
|
||||
vanishPlayers.remove(vanishPlayer);
|
||||
|
||||
}
|
||||
|
||||
public void sendMessage(CommandSender p, String messagesYmlPath, Object... additionalPlayerInfo) {
|
||||
|
||||
String message;
|
||||
if (!messagesYmlPath.contains(" "))
|
||||
if (!StringUtils.contains(messagesYmlPath, " ") && getMessage(messagesYmlPath) != null) {
|
||||
|
||||
message = getMessage(messagesYmlPath);
|
||||
else message = messagesYmlPath;
|
||||
if (message.equalsIgnoreCase("") || messagesYmlPath.equalsIgnoreCase(""))
|
||||
|
||||
} else {
|
||||
|
||||
message = messagesYmlPath;
|
||||
|
||||
}
|
||||
|
||||
if (StringUtils.equalsIgnoreCase("", message) || StringUtils.equalsIgnoreCase("", messagesYmlPath)) {
|
||||
|
||||
return;
|
||||
message = replacePlaceholders(message, additionalPlayerInfo);
|
||||
p.sendMessage(message);
|
||||
|
||||
}
|
||||
|
||||
if (p instanceof Player player) {
|
||||
|
||||
UtilitiesOG.trueogMessage(player, expandPlaceholders(player, message, additionalPlayerInfo));
|
||||
|
||||
} else {
|
||||
|
||||
p.sendMessage(LegacyComponentSerializer.legacySection()
|
||||
.serialize(expandPlaceholders(p, message, additionalPlayerInfo)));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean canSee(Player viewer, Player viewed) {
|
||||
|
||||
if (!isPersistedVanished(viewed)) {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return !visibilityChanger.getHider().isHidden(viewed, viewer);
|
||||
|
||||
}
|
||||
|
||||
public void reconcileVisibility(Player subject) {
|
||||
|
||||
for (Player viewer : Bukkit.getOnlinePlayers()) {
|
||||
|
||||
reconcileVisibility(subject, viewer);
|
||||
if (subject != viewer) {
|
||||
|
||||
reconcileVisibility(viewer, subject);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void reconcileAllVisibilities() {
|
||||
|
||||
for (Player subject : Bukkit.getOnlinePlayers()) {
|
||||
|
||||
for (Player viewer : Bukkit.getOnlinePlayers()) {
|
||||
|
||||
reconcileVisibility(subject, viewer);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void forceShowAllPlayers() {
|
||||
|
||||
forceShowAllPlayers(false);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param aggressive when true, also clears legacy (null-plugin-ref) hide state
|
||||
* left behind by plugins using the deprecated
|
||||
* {@code Player#hidePlayer(Player)} API (Essentials is the
|
||||
* common culprit). Only used by {@code /sv cleanup}, which is
|
||||
* the documented escape hatch — normal reload/disable paths
|
||||
* must not touch other plugins' hide state.
|
||||
*/
|
||||
public void forceShowAllPlayers(boolean aggressive) {
|
||||
|
||||
if (visibilityChanger == null) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
for (Player subject : Bukkit.getOnlinePlayers()) {
|
||||
|
||||
for (Player viewer : Bukkit.getOnlinePlayers()) {
|
||||
|
||||
if (subject == viewer) {
|
||||
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
if (aggressive) {
|
||||
|
||||
BukkitPlayerHidingUtil.showPlayerAggressive(subject, viewer, this);
|
||||
|
||||
} else {
|
||||
|
||||
BukkitPlayerHidingUtil.showPlayer(subject, viewer, this);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void reconcileVisibility(Player subject, Player viewer) {
|
||||
|
||||
if (subject == viewer) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
boolean hidden = isPersistedVanished(subject) && !hasPermissionToSee(viewer, subject);
|
||||
visibilityChanger.getHider().setHidden(subject, viewer, hidden);
|
||||
|
||||
}
|
||||
|
||||
public boolean isPersistedVanished(Player player) {
|
||||
|
||||
return isPersistedVanished(player.getUniqueId());
|
||||
|
||||
}
|
||||
|
||||
public boolean isPersistedVanished(UUID uuid) {
|
||||
|
||||
return vanishStateMgr != null && vanishStateMgr.hasPersistedVanishEntry(uuid);
|
||||
|
||||
}
|
||||
|
||||
public boolean hasPermissionToVanish(CommandSender sender) {
|
||||
|
||||
return layeredPermissionChecker.hasPermissionToVanish(sender);
|
||||
|
||||
}
|
||||
|
||||
public boolean hasPermissionToSee(Player viewer, Player viewed) {
|
||||
|
||||
return layeredPermissionChecker.hasPermissionToSee(viewer, viewed);
|
||||
|
||||
}
|
||||
|
||||
public int getLayeredPermissionLevel(CommandSender sender, String permission) {
|
||||
|
||||
return layeredPermissionChecker.getLayeredPermissionLevel(sender, permission);
|
||||
|
||||
}
|
||||
|
||||
public FileConfiguration getSettings() {
|
||||
|
||||
return configMgr.getSettings();
|
||||
|
||||
}
|
||||
|
||||
public FileConfiguration getMessages() {
|
||||
return configMgr.getMessages();
|
||||
}
|
||||
|
||||
public FileConfiguration getPlayerData() {
|
||||
return configMgr.getPlayerData();
|
||||
return configMgr.getMessages();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileConfiguration getConfig() {
|
||||
|
||||
return getSettings();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(Level level, String msg) {
|
||||
|
||||
getLogger().log(level, msg);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(Level level, String msg, Throwable ex) {
|
||||
|
||||
getLogger().log(level, msg, ex);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logException(Throwable e) {
|
||||
|
||||
ExceptionLogger.logException(e, this);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isUseProtocolLib() {
|
||||
|
||||
return useProtocolLib;
|
||||
|
||||
}
|
||||
|
||||
public ActionBarMgr getActionBarMgr() {
|
||||
|
||||
return actionBarMgr;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public VanishStateMgr getVanishStateMgr() {
|
||||
|
||||
return vanishStateMgr;
|
||||
|
||||
}
|
||||
|
||||
public VersionUtil getVersionUtil() {
|
||||
|
||||
return versionUtil;
|
||||
|
||||
}
|
||||
|
||||
public ConfigMgr getConfigMgr() {
|
||||
|
||||
return configMgr;
|
||||
|
||||
}
|
||||
|
||||
public FeatureMgr getFeatureMgr() {
|
||||
|
||||
return featureMgr;
|
||||
|
||||
}
|
||||
|
||||
public PlaceholderConverter getPlaceholderConverter() {
|
||||
|
||||
return placeholderConverter;
|
||||
|
||||
}
|
||||
|
||||
public VanishCommand getCommand() {
|
||||
|
||||
return command;
|
||||
|
||||
}
|
||||
|
||||
public VisibilityChanger getVisibilityChanger() {
|
||||
|
||||
return visibilityChanger;
|
||||
|
||||
}
|
||||
|
||||
public LoginListener getLoginListener() {
|
||||
|
||||
return loginListener;
|
||||
|
||||
}
|
||||
|
||||
public LayeredPermissionChecker getLayeredPermissionChecker() {
|
||||
|
||||
return layeredPermissionChecker;
|
||||
|
||||
}
|
||||
|
||||
public PluginHookMgr getPluginHookMgr() {
|
||||
|
||||
return pluginHookMgr;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,4 +24,5 @@ public interface SuperVanishPlugin {
|
||||
void logException(Throwable e);
|
||||
|
||||
VanishStateMgr getVanishStateMgr();
|
||||
|
||||
}
|
||||
@@ -10,51 +10,88 @@ package de.myzelyam.supervanish;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Wrapped org.bukkit.entity.Player
|
||||
* Holds additional information about players in the context of vanishing
|
||||
*/
|
||||
public class VanishPlayer {
|
||||
|
||||
private final SuperVanish plugin;
|
||||
@Getter
|
||||
private Player player;
|
||||
@Setter
|
||||
private final UUID playerUUID;
|
||||
private boolean itemPickUps;
|
||||
@Getter
|
||||
private int seePermissionLevel, usePermissionLevel;
|
||||
|
||||
VanishPlayer(Player player, SuperVanish plugin, boolean itemPickUps) {
|
||||
|
||||
this.plugin = plugin;
|
||||
this.player = player;
|
||||
this.playerUUID = player.getUniqueId();
|
||||
this.itemPickUps = itemPickUps;
|
||||
if (plugin.getSettings().getBoolean("IndicationFeatures.LayeredPermissions.LayeredSeeAndUsePermissions", false)) {
|
||||
if (plugin.getSettings().getBoolean("IndicationFeatures.LayeredPermissions.LayeredSeeAndUsePermissions",
|
||||
false))
|
||||
{
|
||||
|
||||
seePermissionLevel = plugin.getLayeredPermissionLevel(player, "see");
|
||||
usePermissionLevel = plugin.getLayeredPermissionLevel(player, "use");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean isOnlineVanished() {
|
||||
return plugin.getVanishStateMgr().isVanished(player.getUniqueId());
|
||||
|
||||
return plugin.getVanishStateMgr().isVanished(playerUUID);
|
||||
|
||||
}
|
||||
|
||||
public boolean hasItemPickUpsEnabled() {
|
||||
|
||||
return itemPickUps;
|
||||
|
||||
}
|
||||
|
||||
public UUID getPlayerUUID() {
|
||||
|
||||
return playerUUID;
|
||||
|
||||
}
|
||||
|
||||
public void setItemPickUps(boolean itemPickUps) {
|
||||
|
||||
this.itemPickUps = itemPickUps;
|
||||
|
||||
}
|
||||
|
||||
public int getSeePermissionLevel() {
|
||||
|
||||
return seePermissionLevel;
|
||||
|
||||
}
|
||||
|
||||
public int getUsePermissionLevel() {
|
||||
|
||||
return usePermissionLevel;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
VanishPlayer that = (VanishPlayer) o;
|
||||
return player != null ? player.getUniqueId().equals(that.player.getUniqueId()) : that.player == null;
|
||||
return Objects.equals(playerUUID, that.playerUUID);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return player != null ? player.getUniqueId().hashCode() : 0;
|
||||
|
||||
return Objects.hash(playerUUID);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,89 +16,69 @@ import org.bukkit.command.CommandSender;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public enum CommandAction {
|
||||
VANISH_SELF(
|
||||
"sv.use",
|
||||
false,
|
||||
"/sv [on|off]",
|
||||
"Toggles your visibility") {
|
||||
|
||||
VANISH_SELF("sv.use", false, "/sv [on|off]", "Toggles your visibility") {
|
||||
|
||||
@Override
|
||||
public boolean checkPermission(CommandSender sender, SuperVanish plugin) {
|
||||
|
||||
Validation.checkNotNull(plugin, "plugin cannot be null");
|
||||
return plugin.hasPermissionToVanish(sender);
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
VANISH_OTHER(
|
||||
"sv.others",
|
||||
true,
|
||||
"/sv [on|off] <player>",
|
||||
"Shows or hides a player"),
|
||||
VANISHED_LIST(
|
||||
"sv.list",
|
||||
true,
|
||||
"/sv list",
|
||||
"Shows a list of vanished players"),
|
||||
BROADCAST_LOGIN(
|
||||
"sv.login",
|
||||
false,
|
||||
"/sv login",
|
||||
"Broadcasts a fake login message"),
|
||||
BROADCAST_LOGOUT(
|
||||
"sv.logout",
|
||||
false,
|
||||
"/sv logout",
|
||||
"Broadcasts a fake logout message"),
|
||||
TOGGLE_ITEM_PICKUPS(
|
||||
"sv.toggleitems",
|
||||
false,
|
||||
"/sv tipu",
|
||||
"Toggles picking up items") {
|
||||
VANISH_OTHER("sv.others", true, "/sv [on|off] <player>", "Shows or hides a player"),
|
||||
VANISHED_LIST("sv.list", true, "/sv list", "Shows a list of vanished players"),
|
||||
BROADCAST_LOGIN("sv.login", false, "/sv login", "Broadcasts a fake login message"),
|
||||
BROADCAST_LOGOUT("sv.logout", false, "/sv logout", "Broadcasts a fake logout message"),
|
||||
TOGGLE_ITEM_PICKUPS("sv.toggleitems", false, "/sv tipu", "Toggles picking up items")
|
||||
{
|
||||
|
||||
@Override
|
||||
public boolean checkPermission(CommandSender sender, SuperVanish plugin) {
|
||||
|
||||
return sender.hasPermission(getMainPermission()) || sender.hasPermission("sv.toggleitempickups");
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
RECREATE_FILES(
|
||||
"sv.recreatefiles",
|
||||
true,
|
||||
"/sv recreatefiles",
|
||||
"Recreates the config") {
|
||||
RECREATE_FILES("sv.recreatefiles", true, "/sv recreatefiles", "Recreates the config")
|
||||
{
|
||||
|
||||
@Override
|
||||
public boolean checkPermission(CommandSender sender, SuperVanish plugin) {
|
||||
|
||||
return sender.hasPermission(getMainPermission()) || sender.hasPermission("sv.updatecfg");
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
RELOAD(
|
||||
"sv.reload",
|
||||
true,
|
||||
"/sv reload",
|
||||
"Reloads all settings and messages"),
|
||||
PRINT_STACKTRACE(
|
||||
"sv.stacktrace",
|
||||
true,
|
||||
"/sv stacktrace",
|
||||
"Logs info for a bug report"),
|
||||
SHOW_HELP(
|
||||
"sv.help",
|
||||
true,
|
||||
"/sv help",
|
||||
"Shows this help page");
|
||||
RELOAD("sv.reload", true, "/sv reload", "Reloads all settings and messages"),
|
||||
CLEANUP("sv.cleanup", true, "/sv cleanup", "Clears all vanish state and forces everyone visible"),
|
||||
PRINT_STACKTRACE("sv.stacktrace", true, "/sv stacktrace", "Logs info for a bug report"),
|
||||
SHOW_HELP("sv.help", true, "/sv help", "Shows this help page");
|
||||
|
||||
/**
|
||||
* Use {@link #checkPermission(CommandSender, SuperVanish)} to check whether a {@link CommandSender} has
|
||||
* permission to perform an action or not
|
||||
* Use {@link #checkPermission(CommandSender, SuperVanish)} to check whether a
|
||||
* {@link CommandSender} has permission to perform an action or not
|
||||
*/
|
||||
@Getter
|
||||
private final String mainPermission;
|
||||
private final boolean console;
|
||||
@Getter
|
||||
private final String usage, description;
|
||||
|
||||
CommandAction(String mainPermission, boolean console, String usage, String description) {
|
||||
|
||||
this.mainPermission = mainPermission;
|
||||
this.console = console;
|
||||
this.usage = usage;
|
||||
this.description = description;
|
||||
|
||||
}
|
||||
|
||||
static List<String> getAvailableFirstArguments(CommandSender sender, SuperVanish plugin) {
|
||||
|
||||
Validation.checkNotNull(plugin, "plugin cannot be null");
|
||||
List<String> list = new ArrayList<>();
|
||||
if (SHOW_HELP.checkPermission(sender, plugin))
|
||||
@@ -107,6 +87,8 @@ public enum CommandAction {
|
||||
list.add("recreatefiles");
|
||||
if (RELOAD.checkPermission(sender, plugin))
|
||||
list.add("reload");
|
||||
if (CLEANUP.checkPermission(sender, plugin))
|
||||
list.add("cleanup");
|
||||
if (VANISHED_LIST.checkPermission(sender, plugin))
|
||||
list.add("list");
|
||||
if (VANISH_SELF.checkPermission(sender, plugin))
|
||||
@@ -118,20 +100,46 @@ public enum CommandAction {
|
||||
if (PRINT_STACKTRACE.checkPermission(sender, plugin))
|
||||
list.add("stacktrace");
|
||||
return list;
|
||||
|
||||
}
|
||||
|
||||
public static boolean hasAnyCmdPermission(CommandSender sender, SuperVanish plugin) {
|
||||
|
||||
for (CommandAction action : CommandAction.values())
|
||||
if (action.checkPermission(sender, plugin))
|
||||
return true;
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public boolean checkPermission(CommandSender sender, SuperVanish plugin) {
|
||||
|
||||
return sender.hasPermission(getMainPermission());
|
||||
|
||||
}
|
||||
|
||||
public boolean usableByConsole() {
|
||||
|
||||
return console;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public String getMainPermission() {
|
||||
|
||||
return mainPermission;
|
||||
|
||||
}
|
||||
|
||||
public String getUsage() {
|
||||
|
||||
return usage;
|
||||
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
|
||||
return description;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,4 +14,5 @@ import org.bukkit.command.CommandSender;
|
||||
public interface Executable {
|
||||
|
||||
void execute(Command cmd, CommandSender sender, String[] args, String label);
|
||||
|
||||
}
|
||||
@@ -21,42 +21,61 @@ public abstract class SubCommand implements Executable {
|
||||
protected final SuperVanish plugin;
|
||||
|
||||
public SubCommand(SuperVanish plugin) {
|
||||
|
||||
this.plugin = plugin;
|
||||
|
||||
}
|
||||
|
||||
protected Collection<UUID> getAllVanishedPlayers() {
|
||||
|
||||
return plugin.getVanishStateMgr().getVanishedPlayers();
|
||||
|
||||
}
|
||||
|
||||
protected Collection<UUID> getOnlineVanishedPlayers() {
|
||||
|
||||
return plugin.getVanishStateMgr().getOnlineVanishedPlayers();
|
||||
|
||||
}
|
||||
|
||||
public void hidePlayer(Player player) {
|
||||
|
||||
plugin.getVisibilityChanger().hidePlayer(player);
|
||||
|
||||
}
|
||||
|
||||
public void showPlayer(Player player) {
|
||||
|
||||
plugin.getVisibilityChanger().showPlayer(player);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public boolean isVanished(UUID uuid) {
|
||||
|
||||
return plugin.getVanishStateMgr().isVanished(uuid);
|
||||
|
||||
}
|
||||
|
||||
public boolean canDo(CommandSender sender, CommandAction action, boolean sendErrors) {
|
||||
|
||||
if (!(sender instanceof Player))
|
||||
if (!action.usableByConsole()) {
|
||||
|
||||
if (sendErrors)
|
||||
plugin.sendMessage(sender, "InvalidSender", sender);
|
||||
return false;
|
||||
|
||||
}
|
||||
if (!action.checkPermission(sender, plugin)) {
|
||||
|
||||
if (sendErrors)
|
||||
plugin.sendMessage(sender, "NoPermission", sender);
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,18 +9,7 @@
|
||||
package de.myzelyam.supervanish.commands;
|
||||
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
import de.myzelyam.supervanish.commands.subcommands.BroadcastLogin;
|
||||
import de.myzelyam.supervanish.commands.subcommands.BroadcastLogout;
|
||||
import de.myzelyam.supervanish.commands.subcommands.InvalidUsage;
|
||||
import de.myzelyam.supervanish.commands.subcommands.PrintStacktrace;
|
||||
import de.myzelyam.supervanish.commands.subcommands.RecreateFiles;
|
||||
import de.myzelyam.supervanish.commands.subcommands.Reload;
|
||||
import de.myzelyam.supervanish.commands.subcommands.ShowHelp;
|
||||
import de.myzelyam.supervanish.commands.subcommands.ToggleItemPickups;
|
||||
import de.myzelyam.supervanish.commands.subcommands.VanishOther;
|
||||
import de.myzelyam.supervanish.commands.subcommands.VanishSelf;
|
||||
import de.myzelyam.supervanish.commands.subcommands.VanishedList;
|
||||
|
||||
import de.myzelyam.supervanish.commands.subcommands.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -36,117 +25,149 @@ public class SubCommandMgr {
|
||||
private SuperVanish plugin;
|
||||
|
||||
public SubCommandMgr(SuperVanish plugin) {
|
||||
|
||||
this.plugin = plugin;
|
||||
|
||||
}
|
||||
|
||||
public void execute(Command cmd, CommandSender sender, String[] args, String label) {
|
||||
|
||||
try {
|
||||
|
||||
// invalid usage by default
|
||||
Executable executable = new InvalidUsage(plugin);
|
||||
// vanish self
|
||||
// vanish self #1
|
||||
if (args.length == 0) {
|
||||
|
||||
if (sender instanceof Player)
|
||||
executable = new VanishSelf(plugin);
|
||||
executable.execute(cmd, sender, args, label);
|
||||
return;
|
||||
|
||||
}
|
||||
if ((args[0].equalsIgnoreCase("on")
|
||||
|| args[0].equalsIgnoreCase("off")
|
||||
|| args[0].equalsIgnoreCase("vanish")
|
||||
|| args[0].equalsIgnoreCase("reappear")
|
||||
|| args[0].equalsIgnoreCase("enable")
|
||||
|| args[0].equalsIgnoreCase("disable")
|
||||
|| args[0].equalsIgnoreCase("-s"))
|
||||
&& args.length == 1) {
|
||||
executable = new VanishSelf(plugin);
|
||||
}
|
||||
//
|
||||
if (args[0].equalsIgnoreCase("help")
|
||||
|| args[0].equalsIgnoreCase("commands")
|
||||
|| args[0].equalsIgnoreCase("?")) {
|
||||
executable = new ShowHelp(plugin);
|
||||
}
|
||||
if (args[0].equalsIgnoreCase("printstacktrace")
|
||||
|| args[0].equalsIgnoreCase("logstacktrace")
|
||||
|| args[0].equalsIgnoreCase("dumpstacktrace")
|
||||
|| args[0].equalsIgnoreCase("stacktrace")) {
|
||||
executable = new PrintStacktrace(plugin);
|
||||
}
|
||||
if (args[0].equalsIgnoreCase("toggleitempickups")
|
||||
|| args[0].equalsIgnoreCase("toggleitempickup")
|
||||
|| args[0].equalsIgnoreCase("toggleitem")
|
||||
|| args[0].equalsIgnoreCase("toggleitems")
|
||||
|| args[0].equalsIgnoreCase("togglepickup")
|
||||
|| args[0].equalsIgnoreCase("togglepickups")
|
||||
|| args[0].equalsIgnoreCase("pickup")
|
||||
|| args[0].equalsIgnoreCase("pickups")
|
||||
|| args[0].equalsIgnoreCase("tipu")
|
||||
|| args[0].equalsIgnoreCase("tip")) {
|
||||
executable = new ToggleItemPickups(plugin);
|
||||
}
|
||||
if (args[0].equalsIgnoreCase("recreatecfg")
|
||||
|| args[0].equalsIgnoreCase("rccfg")
|
||||
|| args[0].equalsIgnoreCase("recreateconfig")
|
||||
|| args[0].equalsIgnoreCase("rcconfig")
|
||||
|| args[0].equalsIgnoreCase("recreate")
|
||||
|| args[0].equalsIgnoreCase("updatecfg")
|
||||
|| args[0].equalsIgnoreCase("recreate")
|
||||
|| args[0].equalsIgnoreCase("recreatefiles")
|
||||
|| args[0].equalsIgnoreCase("rf")
|
||||
|| args[0].equalsIgnoreCase("rcf")
|
||||
|| args[0].equalsIgnoreCase("refi")) {
|
||||
executable = new RecreateFiles(plugin);
|
||||
}
|
||||
if (args[0].equalsIgnoreCase("reload")
|
||||
|| args[0].equalsIgnoreCase("rl")
|
||||
|| args[0].equalsIgnoreCase("re")
|
||||
|| args[0].equalsIgnoreCase("rlc")
|
||||
|| args[0].equalsIgnoreCase("rlcfg")
|
||||
|| args[0].equalsIgnoreCase("reloadconfig")
|
||||
|| args[0].equalsIgnoreCase("rlp")
|
||||
|| args[0].equalsIgnoreCase("rlpl")
|
||||
|| args[0].equalsIgnoreCase("reloadplugin")) {
|
||||
executable = new Reload(plugin);
|
||||
}
|
||||
if (args[0].equalsIgnoreCase("list")) {
|
||||
executable = new VanishedList(plugin);
|
||||
}
|
||||
if (args[0].equalsIgnoreCase("login")) {
|
||||
executable = new BroadcastLogin(plugin);
|
||||
}
|
||||
if (args[0].equalsIgnoreCase("logout")) {
|
||||
executable = new BroadcastLogout(plugin);
|
||||
}
|
||||
|
||||
// vanish other
|
||||
if ((args[0].equalsIgnoreCase("on")
|
||||
|| args[0].equalsIgnoreCase("off")
|
||||
|| args[0].equalsIgnoreCase("vanish")
|
||||
|| args[0].equalsIgnoreCase("reappear")
|
||||
|| args[0].equalsIgnoreCase("enable")
|
||||
|| args[0].equalsIgnoreCase("disable"))
|
||||
&& args.length > 1
|
||||
|| Bukkit.getPlayer(args[0]) != null) {
|
||||
if ((args[0].equalsIgnoreCase("on") || args[0].equalsIgnoreCase("off") || args[0].equalsIgnoreCase("vanish")
|
||||
|| args[0].equalsIgnoreCase("reappear") || args[0].equalsIgnoreCase("enable")
|
||||
|| args[0].equalsIgnoreCase("disable")) && args.length > 1 || Bukkit.getPlayer(args[0]) != null)
|
||||
{
|
||||
|
||||
executable = Bukkit.getPlayer(args[0]) != null
|
||||
&& !(args[0].equalsIgnoreCase("on")
|
||||
|| args[0].equalsIgnoreCase("off")
|
||||
|| args[0].equalsIgnoreCase("vanish")
|
||||
|| args[0].equalsIgnoreCase("reappear")
|
||||
|| args[0].equalsIgnoreCase("enable")
|
||||
|| args[0].equalsIgnoreCase("disable"))
|
||||
? new VanishOther(Bukkit.getPlayer(args[0]), plugin)
|
||||
: new VanishOther(plugin);
|
||||
&& !(args[0].equalsIgnoreCase("on") || args[0].equalsIgnoreCase("off")
|
||||
|| args[0].equalsIgnoreCase("vanish") || args[0].equalsIgnoreCase("reappear")
|
||||
|| args[0].equalsIgnoreCase("enable") || args[0].equalsIgnoreCase("disable"))
|
||||
? new VanishOther(Bukkit.getPlayer(args[0]), plugin)
|
||||
: new VanishOther(plugin);
|
||||
|
||||
}
|
||||
|
||||
// vanish self #2
|
||||
if ((args[0].equalsIgnoreCase("on") || args[0].equalsIgnoreCase("off") || args[0].equalsIgnoreCase("vanish")
|
||||
|| args[0].equalsIgnoreCase("reappear") || args[0].equalsIgnoreCase("enable")
|
||||
|| args[0].equalsIgnoreCase("disable") || args[0].equalsIgnoreCase("-s")) && args.length == 1)
|
||||
{
|
||||
|
||||
executable = new VanishSelf(plugin);
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
if (args[0].equalsIgnoreCase("help") || args[0].equalsIgnoreCase("commands")
|
||||
|| args[0].equalsIgnoreCase("?"))
|
||||
{
|
||||
|
||||
executable = new ShowHelp(plugin);
|
||||
|
||||
}
|
||||
|
||||
if (args[0].equalsIgnoreCase("printstacktrace") || args[0].equalsIgnoreCase("logstacktrace")
|
||||
|| args[0].equalsIgnoreCase("dumpstacktrace") || args[0].equalsIgnoreCase("stacktrace"))
|
||||
{
|
||||
|
||||
executable = new PrintStacktrace(plugin);
|
||||
|
||||
}
|
||||
|
||||
if (args[0].equalsIgnoreCase("toggleitempickups") || args[0].equalsIgnoreCase("toggleitempickup")
|
||||
|| args[0].equalsIgnoreCase("toggleitem") || args[0].equalsIgnoreCase("toggleitems")
|
||||
|| args[0].equalsIgnoreCase("togglepickup") || args[0].equalsIgnoreCase("togglepickups")
|
||||
|| args[0].equalsIgnoreCase("pickup") || args[0].equalsIgnoreCase("pickups")
|
||||
|| args[0].equalsIgnoreCase("tipu") || args[0].equalsIgnoreCase("tip"))
|
||||
{
|
||||
|
||||
executable = new ToggleItemPickups(plugin);
|
||||
|
||||
}
|
||||
|
||||
if (args[0].equalsIgnoreCase("recreatecfg") || args[0].equalsIgnoreCase("rccfg")
|
||||
|| args[0].equalsIgnoreCase("recreateconfig") || args[0].equalsIgnoreCase("rcconfig")
|
||||
|| args[0].equalsIgnoreCase("updatecfg") || args[0].equalsIgnoreCase("recreate")
|
||||
|| args[0].equalsIgnoreCase("recreatefiles") || args[0].equalsIgnoreCase("rf")
|
||||
|| args[0].equalsIgnoreCase("rcf") || args[0].equalsIgnoreCase("refi"))
|
||||
{
|
||||
|
||||
executable = new RecreateFiles(plugin);
|
||||
|
||||
}
|
||||
|
||||
if (args[0].equalsIgnoreCase("reload") || args[0].equalsIgnoreCase("rl") || args[0].equalsIgnoreCase("re")
|
||||
|| args[0].equalsIgnoreCase("rlc") || args[0].equalsIgnoreCase("rlcfg")
|
||||
|| args[0].equalsIgnoreCase("reloadconfig") || args[0].equalsIgnoreCase("rlp")
|
||||
|| args[0].equalsIgnoreCase("rlpl") || args[0].equalsIgnoreCase("reloadplugin"))
|
||||
{
|
||||
|
||||
executable = new Reload(plugin);
|
||||
|
||||
}
|
||||
|
||||
if (args[0].equalsIgnoreCase("list")) {
|
||||
|
||||
executable = new VanishedList(plugin);
|
||||
|
||||
}
|
||||
|
||||
if (args[0].equalsIgnoreCase("cleanup") || args[0].equalsIgnoreCase("clearall")
|
||||
|| args[0].equalsIgnoreCase("flush"))
|
||||
{
|
||||
|
||||
executable = new Cleanup(plugin);
|
||||
|
||||
}
|
||||
|
||||
if (args[0].equalsIgnoreCase("login")) {
|
||||
|
||||
executable = new BroadcastLogin(plugin);
|
||||
|
||||
}
|
||||
|
||||
if (args[0].equalsIgnoreCase("logout")) {
|
||||
|
||||
executable = new BroadcastLogout(plugin);
|
||||
|
||||
}
|
||||
|
||||
executable.execute(cmd, sender, args, label);
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
plugin.logException(e);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public List<String> onTabComplete(Command command, CommandSender sender,
|
||||
String alias, String[] args) {
|
||||
public List<String> onTabComplete(Command command, CommandSender sender, String alias, String[] args) {
|
||||
|
||||
// don't provide any help at all if user doesn't have permission to
|
||||
// execute '/sv help'
|
||||
if (!CommandAction.hasAnyCmdPermission(sender, plugin)) {
|
||||
|
||||
return Collections.emptyList();
|
||||
|
||||
}
|
||||
|
||||
if (args.length == 1) {
|
||||
|
||||
String toComplete = args[0];
|
||||
// didn't start to type first argument
|
||||
if (toComplete.equalsIgnoreCase(""))
|
||||
@@ -154,34 +175,48 @@ public class SubCommandMgr {
|
||||
// started to type it, only show args that start with given argument
|
||||
List<String> matchingFirstArguments = new ArrayList<>();
|
||||
for (String arg : CommandAction.getAvailableFirstArguments(sender, plugin)) {
|
||||
|
||||
if (arg.toLowerCase(Locale.ENGLISH).startsWith(toComplete.toLowerCase(Locale.ENGLISH)))
|
||||
matchingFirstArguments.add(arg);
|
||||
|
||||
}
|
||||
|
||||
if (matchingFirstArguments.isEmpty())
|
||||
return getOnlinePlayerNameTabCompletions(toComplete);
|
||||
return matchingFirstArguments;
|
||||
|
||||
// extra commands
|
||||
} else if (args.length == 2) {
|
||||
|
||||
// vanish other player tab completion
|
||||
if ((args[0].equalsIgnoreCase("on")
|
||||
|| args[0].equalsIgnoreCase("off")
|
||||
|| args[0].equalsIgnoreCase("vanish")
|
||||
|| args[0].equalsIgnoreCase("reappear")
|
||||
|| args[0].equalsIgnoreCase("enable")
|
||||
if ((args[0].equalsIgnoreCase("on") || args[0].equalsIgnoreCase("off") || args[0].equalsIgnoreCase("vanish")
|
||||
|| args[0].equalsIgnoreCase("reappear") || args[0].equalsIgnoreCase("enable")
|
||||
|| args[0].equalsIgnoreCase("disable"))
|
||||
&& CommandAction.VANISH_OTHER.checkPermission(sender, plugin)) {
|
||||
&& CommandAction.VANISH_OTHER.checkPermission(sender, plugin))
|
||||
{
|
||||
|
||||
return getOnlinePlayerNameTabCompletions(args[1]);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
|
||||
}
|
||||
|
||||
private List<String> getOnlinePlayerNameTabCompletions(String arg) {
|
||||
|
||||
List<String> playerNames = new ArrayList<>();
|
||||
for (Player p : plugin.getServer().getOnlinePlayers()) {
|
||||
|
||||
if (p.getName().toLowerCase(Locale.ENGLISH).startsWith(arg.toLowerCase(Locale.ENGLISH)))
|
||||
playerNames.add(p.getName());
|
||||
|
||||
}
|
||||
|
||||
return playerNames;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,29 +8,33 @@
|
||||
|
||||
package de.myzelyam.supervanish.commands;
|
||||
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.List;
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
|
||||
public class VanishCommand {
|
||||
|
||||
private final SuperVanish plugin;
|
||||
private final SubCommandMgr subCommandMgr;
|
||||
|
||||
public VanishCommand(SuperVanish plugin) {
|
||||
this.plugin = plugin;
|
||||
|
||||
subCommandMgr = new SubCommandMgr(plugin);
|
||||
|
||||
}
|
||||
|
||||
public void execute(Command command, CommandSender sender, String commandLabel, String[] args) {
|
||||
|
||||
subCommandMgr.execute(command, sender, args, commandLabel);
|
||||
|
||||
}
|
||||
|
||||
public List<String> tabComplete(Command command, CommandSender sender, String alias, String[] args)
|
||||
throws IllegalArgumentException {
|
||||
public List<String> tabComplete(Command command, CommandSender sender, String alias, String[] args) {
|
||||
|
||||
return subCommandMgr.onTabComplete(command, sender, alias, args);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,14 +20,21 @@ import org.bukkit.entity.Player;
|
||||
public class BroadcastLogin extends SubCommand {
|
||||
|
||||
public BroadcastLogin(SuperVanish plugin) {
|
||||
|
||||
super(plugin);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Command cmd, CommandSender p, String[] args, String label) {
|
||||
|
||||
if (canDo(p, CommandAction.BROADCAST_LOGIN, true)) {
|
||||
|
||||
for (Player onlinePlayer : Bukkit.getOnlinePlayers())
|
||||
plugin.sendMessage(onlinePlayer, "ReappearMessage", p, onlinePlayer);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,14 +20,21 @@ import org.bukkit.entity.Player;
|
||||
public class BroadcastLogout extends SubCommand {
|
||||
|
||||
public BroadcastLogout(SuperVanish plugin) {
|
||||
|
||||
super(plugin);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Command cmd, CommandSender p, String[] args, String label) {
|
||||
|
||||
if (canDo(p, CommandAction.BROADCAST_LOGOUT, true)) {
|
||||
|
||||
for (Player onlinePlayer : Bukkit.getOnlinePlayers())
|
||||
plugin.sendMessage(onlinePlayer, "VanishMessage", p, onlinePlayer);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package de.myzelyam.supervanish.commands.subcommands;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
import de.myzelyam.supervanish.commands.CommandAction;
|
||||
import de.myzelyam.supervanish.commands.SubCommand;
|
||||
import net.trueog.utilitiesog.UtilitiesOG;
|
||||
|
||||
public class Cleanup extends SubCommand {
|
||||
|
||||
public Cleanup(SuperVanish plugin) {
|
||||
|
||||
super(plugin);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Command cmd, CommandSender p, String[] args, String label) {
|
||||
|
||||
if (!canDo(p, CommandAction.CLEANUP, true)) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
plugin.getVanishStateMgr().clearAllVanishState();
|
||||
|
||||
// Must run before forceShowAllPlayers: Essentials' setVanished(false)
|
||||
// internally calls the deprecated showPlayer(Player) for every online
|
||||
// user, and we want our aggressive pass to finish after that so nothing
|
||||
// sneaks back in.
|
||||
if (plugin.getPluginHookMgr() != null) {
|
||||
|
||||
plugin.getPluginHookMgr().onCleanup();
|
||||
|
||||
}
|
||||
|
||||
if (plugin.getVisibilityChanger() != null) {
|
||||
|
||||
// Aggressive mode also drops the null-plugin-ref hide that Essentials
|
||||
// and other deprecated-API users leave in CraftPlayer's
|
||||
// invertedVisibilityEntities. Without it, CraftPlayer#canSee still
|
||||
// returns false because the set for the target UUID is non-empty.
|
||||
plugin.forceShowAllPlayers(true);
|
||||
plugin.getVisibilityChanger().getHider().clearHiddenState();
|
||||
|
||||
}
|
||||
|
||||
for (Player online : Bukkit.getOnlinePlayers()) {
|
||||
|
||||
for (Plugin other : Bukkit.getPluginManager().getPlugins()) {
|
||||
|
||||
// Each plugin owns its own "vanished" metadata entry; leaving any
|
||||
// of them populated keeps TAB-OG and other consumers treating the
|
||||
// player as vanished even though Vanish-OG has been wiped.
|
||||
online.removeMetadata("vanished", other);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
plugin.reconcileAllVisibilities();
|
||||
|
||||
final String msg = "&aVanish state cleared. All players should now be visible and mutually damageable again.";
|
||||
if (p instanceof Player player) {
|
||||
|
||||
UtilitiesOG.trueogMessage(player, msg);
|
||||
|
||||
} else {
|
||||
|
||||
p.sendMessage(msg);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,15 +18,23 @@ import org.bukkit.command.CommandSender;
|
||||
public class InvalidUsage extends SubCommand {
|
||||
|
||||
public InvalidUsage(SuperVanish plugin) {
|
||||
|
||||
super(plugin);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Command cmd, CommandSender sender, String[] args, String label) {
|
||||
|
||||
if (!CommandAction.hasAnyCmdPermission(sender, plugin)) {
|
||||
|
||||
plugin.sendMessage(sender, "NoPermission", sender);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
plugin.sendMessage(sender, "InvalidUsage", sender);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,14 +18,21 @@ import org.bukkit.command.CommandSender;
|
||||
public class PrintStacktrace extends SubCommand {
|
||||
|
||||
public PrintStacktrace(SuperVanish plugin) {
|
||||
|
||||
super(plugin);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Command cmd, CommandSender sender, String[] args, String label) {
|
||||
|
||||
if (canDo(sender, CommandAction.PRINT_STACKTRACE, true)) {
|
||||
|
||||
plugin.sendMessage(sender, "PrintedStacktrace", sender);
|
||||
plugin.logException(null);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,103 +8,136 @@
|
||||
|
||||
package de.myzelyam.supervanish.commands.subcommands;
|
||||
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
import de.myzelyam.supervanish.commands.CommandAction;
|
||||
import de.myzelyam.supervanish.commands.SubCommand;
|
||||
import java.io.File;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.File;
|
||||
import de.myzelyam.supervanish.PlaceholderConverter;
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
import de.myzelyam.supervanish.commands.CommandAction;
|
||||
import de.myzelyam.supervanish.commands.SubCommand;
|
||||
import net.trueog.utilitiesog.UtilitiesOG;
|
||||
|
||||
public class RecreateFiles extends SubCommand {
|
||||
|
||||
public RecreateFiles(SuperVanish plugin) {
|
||||
|
||||
super(plugin);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Command cmd, CommandSender p, String[] args, String label) {
|
||||
if (canDo(p, CommandAction.RECREATE_FILES, true)) {
|
||||
String updates;
|
||||
String changes;
|
||||
if (plugin.getConfigMgr().isSettingsUpdateRequired()
|
||||
&& plugin.getConfigMgr().isMessagesUpdateRequired()) {
|
||||
updates = "the config and the messages file";
|
||||
changes = "all settings and messages";
|
||||
} else if (plugin.getConfigMgr().isSettingsUpdateRequired()) {
|
||||
updates = "the config";
|
||||
changes = "all settings";
|
||||
} else {
|
||||
updates = "the messages file";
|
||||
changes = "all messages";
|
||||
}
|
||||
if (args.length != 2) {
|
||||
if (!plugin.getConfigMgr().isSettingsUpdateRequired()
|
||||
&& !plugin.getConfigMgr().isMessagesUpdateRequired()) {
|
||||
plugin.sendMessage(p, "NoConfigUpdateAvailable", p);
|
||||
return;
|
||||
}
|
||||
plugin.sendMessage(p, plugin.getMessage("UpdateWarning").replace("%changes%", changes)
|
||||
.replace("%updates%", updates), p);
|
||||
|
||||
if (!canDo(p, CommandAction.RECREATE_FILES, true)) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
String files = "the messages file";
|
||||
String changes = "all messages";
|
||||
|
||||
if (args.length != 2) {
|
||||
|
||||
if (!plugin.getConfigMgr().isMessagesUpdateRequired()) {
|
||||
|
||||
plugin.sendMessage(p, "NoConfigUpdateAvailable", p);
|
||||
return;
|
||||
|
||||
}
|
||||
if (args[1].equalsIgnoreCase("confirm") || args[1].equalsIgnoreCase("force")) {
|
||||
if (!plugin.getConfigMgr().isSettingsUpdateRequired()
|
||||
&& !plugin.getConfigMgr().isMessagesUpdateRequired()
|
||||
&& !args[1].equalsIgnoreCase("force")) {
|
||||
plugin.sendMessage(p, "NoConfigUpdateAvailable", p);
|
||||
return;
|
||||
}
|
||||
if (args[1].equalsIgnoreCase("force")) {
|
||||
updates = "the config and the messages file";
|
||||
changes = "all settings and messages";
|
||||
}
|
||||
// delete necessary files
|
||||
boolean success = false;
|
||||
if (plugin.getConfigMgr().isSettingsUpdateRequired()
|
||||
|| args[1].equalsIgnoreCase("force")) {
|
||||
File file = new File(plugin.getDataFolder().getPath() + File.separator + "config.yml");
|
||||
success = file.delete();
|
||||
plugin.getConfigMgr().getSettingsFile().save();
|
||||
plugin.getConfigMgr().getSettingsFile().reload();
|
||||
plugin.getConfigMgr().setSettings(plugin.getConfigMgr().getSettingsFile().getConfig());
|
||||
}
|
||||
if (plugin.getConfigMgr().isMessagesUpdateRequired()
|
||||
|| args[1].equalsIgnoreCase("force")) {
|
||||
File file2 = new File(plugin.getDataFolder().getPath() + File.separator + "messages.yml");
|
||||
success &= file2.delete();
|
||||
plugin.getConfigMgr().getMessagesFile().save();
|
||||
plugin.getConfigMgr().getMessagesFile().reload();
|
||||
plugin.getConfigMgr().setMessages(plugin.getConfigMgr().getMessagesFile().getConfig());
|
||||
|
||||
plugin.sendMessage(p, plugin.getMessage("UpdateWarning"), p,
|
||||
PlaceholderConverter.placeholder("changes", changes),
|
||||
PlaceholderConverter.placeholder("files", files));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (StringUtils.equalsIgnoreCase("confirm", args[1]) || StringUtils.equalsIgnoreCase(args[1], "force")) {
|
||||
|
||||
if (!plugin.getConfigMgr().isMessagesUpdateRequired() && !StringUtils.equalsIgnoreCase(args[1], "force")) {
|
||||
|
||||
plugin.sendMessage(p, "NoConfigUpdateAvailable", p);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (StringUtils.equalsIgnoreCase(args[1], "force")) {
|
||||
|
||||
files = "the config and the messages file";
|
||||
changes = "all settings and messages";
|
||||
|
||||
}
|
||||
|
||||
// Delete necessary files.
|
||||
boolean success = true;
|
||||
if (StringUtils.equalsIgnoreCase(args[1], "force")) {
|
||||
|
||||
final File file = new File(plugin.getDataFolder().getPath() + File.separator + "config.yml");
|
||||
success = file.delete();
|
||||
plugin.getConfigMgr().getSettingsFile().save();
|
||||
plugin.getConfigMgr().getSettingsFile().reload();
|
||||
plugin.getConfigMgr().setSettings(plugin.getConfigMgr().getSettingsFile().getConfig());
|
||||
|
||||
}
|
||||
|
||||
if (plugin.getConfigMgr().isMessagesUpdateRequired() || StringUtils.equalsIgnoreCase(args[1], "force")) {
|
||||
|
||||
final File file2 = new File(plugin.getDataFolder().getPath() + File.separator + "messages.yml");
|
||||
success &= file2.delete();
|
||||
|
||||
plugin.getConfigMgr().getMessagesFile().save();
|
||||
plugin.getConfigMgr().getMessagesFile().reload();
|
||||
plugin.getConfigMgr().setMessages(plugin.getConfigMgr().getMessagesFile().getConfig());
|
||||
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
|
||||
final String failMsg = "&cERROR: Cannot recreate files because one of them could not be deleted. Are the file permissions valid?";
|
||||
if (p instanceof Player player) {
|
||||
|
||||
UtilitiesOG.trueogMessage(player, failMsg);
|
||||
|
||||
} else {
|
||||
|
||||
p.sendMessage(failMsg);
|
||||
|
||||
}
|
||||
if (!success) {
|
||||
p.sendMessage(ChatColor.RED +
|
||||
"Cannot update config, failed to delete file. Are the file permissions valid?");
|
||||
return;
|
||||
}
|
||||
plugin.sendMessage(p, plugin.getMessage("RecreatedConfig")
|
||||
.replace("%changes%", changes)
|
||||
.replace("%updates%", updates), p);
|
||||
// update update-information
|
||||
plugin.getConfigMgr().checkFilesForLeftOvers();
|
||||
} else if (args[1].equalsIgnoreCase("dismiss")) {
|
||||
String currentVersion = plugin.getDescription().getVersion();
|
||||
boolean isDismissed =
|
||||
plugin.getPlayerData().getBoolean("PlayerData." + (p instanceof Player ? ((Player) p)
|
||||
.getUniqueId()
|
||||
.toString() : "CONSOLE") + ".dismissed." + currentVersion.replace(".", "_"), false);
|
||||
plugin.getPlayerData().set("PlayerData." + (p instanceof Player ? ((Player) p).getUniqueId().toString()
|
||||
: "CONSOLE") + ".dismissed." + currentVersion.replace(".", "_"), !isDismissed);
|
||||
plugin.getConfigMgr().getPlayerDataFile().save();
|
||||
if (!isDismissed)
|
||||
plugin.sendMessage(p, "DismissedRecreationWarning", p);
|
||||
else
|
||||
plugin.sendMessage(p, "UndismissedRecreationWarning", p);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
plugin.sendMessage(p, plugin.getMessage("RecreatedConfig"), p,
|
||||
PlaceholderConverter.placeholder("changes", changes),
|
||||
PlaceholderConverter.placeholder("files", files));
|
||||
|
||||
// Refresh recreation status after regenerating the files.
|
||||
plugin.getConfigMgr().checkFilesForLeftOvers();
|
||||
|
||||
} else if (StringUtils.equalsIgnoreCase("dismiss", args[1])) {
|
||||
|
||||
final String currentVersion = plugin.getPluginMeta().getVersion();
|
||||
final String dismissId = p instanceof Player ? ((Player) p).getUniqueId().toString() : "CONSOLE";
|
||||
final boolean isDismissed = plugin.getVanishStateMgr().isDismissed(dismissId, currentVersion);
|
||||
plugin.getVanishStateMgr().setDismissed(dismissId, currentVersion, !isDismissed);
|
||||
if (!isDismissed) {
|
||||
|
||||
plugin.sendMessage(p, "DismissedRecreationWarning", p);
|
||||
|
||||
} else {
|
||||
|
||||
plugin.sendMessage(p, "UndismissedRecreationWarning", p);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,35 +8,57 @@
|
||||
|
||||
package de.myzelyam.supervanish.commands.subcommands;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import de.myzelyam.supervanish.PlaceholderConverter;
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
import de.myzelyam.supervanish.commands.CommandAction;
|
||||
import de.myzelyam.supervanish.commands.SubCommand;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import net.trueog.utilitiesog.UtilitiesOG;
|
||||
|
||||
public class Reload extends SubCommand {
|
||||
|
||||
public Reload(SuperVanish plugin) {
|
||||
|
||||
super(plugin);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Command cmd, CommandSender p, String[] args, String label) {
|
||||
if (canDo(p, CommandAction.RELOAD, true)) {
|
||||
long before = System.currentTimeMillis();
|
||||
plugin.reload();
|
||||
if (!Bukkit.getPluginManager().isPluginEnabled(plugin)) {
|
||||
p.sendMessage(ChatColor.RED +
|
||||
"Failed to reload SuperVanish since it failed to restart itself " +
|
||||
"(Probably because of invalid MySQL credentials). More information is in the " +
|
||||
"console. (" + (System.currentTimeMillis() - before) + "ms)");
|
||||
return;
|
||||
}
|
||||
plugin.sendMessage(p, plugin.getMessage("PluginReloaded").replace("%time%",
|
||||
(System.currentTimeMillis() - before) + ""), p);
|
||||
|
||||
if (!canDo(p, CommandAction.RELOAD, true)) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
final long before = System.currentTimeMillis();
|
||||
plugin.reload();
|
||||
if (!Bukkit.getPluginManager().isPluginEnabled(plugin)) {
|
||||
|
||||
final String failMsg = "&cERROR: Failed to reload Vanish-OG since it failed to restart itself. "
|
||||
+ "More information is in the console. (" + (System.currentTimeMillis() - before) + "ms)";
|
||||
if (p instanceof Player player) {
|
||||
|
||||
UtilitiesOG.trueogMessage(player, failMsg);
|
||||
|
||||
} else {
|
||||
|
||||
p.sendMessage(failMsg);
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
plugin.sendMessage(p, plugin.getMessage("PluginReloaded"), p,
|
||||
PlaceholderConverter.placeholder("time", System.currentTimeMillis() - before));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
package de.myzelyam.supervanish.commands.subcommands;
|
||||
|
||||
|
||||
import de.myzelyam.supervanish.PlaceholderConverter;
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
import de.myzelyam.supervanish.commands.CommandAction;
|
||||
import de.myzelyam.supervanish.commands.SubCommand;
|
||||
@@ -19,21 +19,32 @@ import org.bukkit.command.CommandSender;
|
||||
public class ShowHelp extends SubCommand {
|
||||
|
||||
public ShowHelp(SuperVanish plugin) {
|
||||
|
||||
super(plugin);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Command cmd, CommandSender sender, String[] args, String label) {
|
||||
|
||||
if (canDo(sender, CommandAction.SHOW_HELP, true)) {
|
||||
|
||||
plugin.sendMessage(sender, "HelpHeader", sender);
|
||||
for (CommandAction action : CommandAction.values()) {
|
||||
|
||||
if (canDo(sender, action, false)) {
|
||||
plugin.sendMessage(sender, plugin.getMessage("HelpFormat")
|
||||
.replace("%usage%", action.getUsage())
|
||||
.replace("%description%", action.getDescription())
|
||||
.replace("%permission%", action.getMainPermission()), sender);
|
||||
|
||||
plugin.sendMessage(sender, plugin.getMessage("HelpFormat"), sender,
|
||||
PlaceholderConverter.placeholder("usage", action.getUsage()),
|
||||
PlaceholderConverter.placeholder("description", action.getDescription()),
|
||||
PlaceholderConverter.placeholder("permission", action.getMainPermission()));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,31 +20,31 @@ import org.bukkit.entity.Player;
|
||||
public class ToggleItemPickups extends SubCommand {
|
||||
|
||||
public ToggleItemPickups(SuperVanish plugin) {
|
||||
|
||||
super(plugin);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Command cmd, CommandSender sender, String[] args, String label) {
|
||||
|
||||
if (canDo(sender, CommandAction.TOGGLE_ITEM_PICKUPS, true)) {
|
||||
|
||||
Player p = (Player) sender;
|
||||
plugin.sendMessage(p, plugin.getMessage("ToggledPickingUpItems"
|
||||
+ (toggleState(plugin.getVanishPlayer(p)) ? "On" : "Off")), p);
|
||||
plugin.sendMessage(p, plugin
|
||||
.getMessage("ToggledPickingUpItems" + (toggleState(plugin.getVanishPlayer(p)) ? "On" : "Off")), p);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean toggleState(VanishPlayer p) {
|
||||
boolean hasEnabled = plugin.getPlayerData().getBoolean("PlayerData."
|
||||
+ p.getPlayer().getUniqueId() + ".itemPickUps");
|
||||
plugin.getPlayerData().set("PlayerData." + p.getPlayer().getUniqueId() + ".itemPickUps", !hasEnabled);
|
||||
p.setItemPickUps(!hasEnabled);
|
||||
plugin.getConfigMgr().getPlayerDataFile().save();
|
||||
// fix /sv tipu
|
||||
try {
|
||||
//noinspection deprecation
|
||||
p.getPlayer().spigot().setCollidesWithEntities(!hasEnabled);
|
||||
} catch (NoClassDefFoundError | NoSuchMethodError ignored) {
|
||||
}
|
||||
//
|
||||
private boolean toggleState(VanishPlayer vp) {
|
||||
|
||||
boolean hasEnabled = plugin.getVanishStateMgr().getItemPickUps(vp.getPlayerUUID(), false);
|
||||
plugin.getVanishStateMgr().setItemPickUps(vp.getPlayerUUID(), !hasEnabled);
|
||||
vp.setItemPickUps(!hasEnabled);
|
||||
return !hasEnabled;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,82 +24,126 @@ public class VanishOther extends SubCommand {
|
||||
private Player specifiedPlayer;
|
||||
|
||||
public VanishOther(SuperVanish plugin) {
|
||||
|
||||
this(null, plugin);
|
||||
|
||||
}
|
||||
|
||||
public VanishOther(Player specifiedPlayer, SuperVanish plugin) {
|
||||
|
||||
super(plugin);
|
||||
this.specifiedPlayer = specifiedPlayer;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Command cmd, CommandSender sender, String[] args, String label) {
|
||||
|
||||
if (canDo(sender, CommandAction.VANISH_OTHER, true)) {
|
||||
|
||||
boolean hide = false, offline = false, silent = false;
|
||||
Player target;
|
||||
String name;
|
||||
UUID uuid;
|
||||
if (specifiedPlayer == null) {
|
||||
|
||||
if (args[0].equalsIgnoreCase("on") || args[0].equalsIgnoreCase("enable")
|
||||
|| args[0].equalsIgnoreCase("vanish"))
|
||||
hide = true;
|
||||
target = Bukkit.getPlayer(args[1]);
|
||||
name = target == null ? args[1] : target.getName();
|
||||
|
||||
} else {
|
||||
|
||||
target = specifiedPlayer;
|
||||
name = specifiedPlayer.getName();
|
||||
hide = !isVanished(target.getUniqueId());
|
||||
|
||||
}
|
||||
|
||||
if (target == null) {
|
||||
|
||||
offline = true;
|
||||
uuid = plugin.getVanishStateMgr().getVanishedUUIDFromNameOnFile(name);
|
||||
uuid = plugin.getVanishStateMgr().getVanishedUUIDFromName(name);
|
||||
if (uuid == null) {
|
||||
|
||||
plugin.sendMessage(sender, "PlayerNonExistent", sender, name);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
name = target.getName();
|
||||
uuid = target.getUniqueId();
|
||||
|
||||
}
|
||||
if (!offline && sender instanceof Player && sender != target
|
||||
&& target.hasPermission("sv.notoggle")) {
|
||||
|
||||
if (!offline && sender instanceof Player && sender != target && target.hasPermission("sv.notoggle")) {
|
||||
|
||||
plugin.sendMessage(sender, "CannotHideOtherPlayer", sender, name);
|
||||
return;
|
||||
|
||||
}
|
||||
if (plugin.getSettings().getBoolean(
|
||||
"IndicationFeatures.LayeredPermissions.HideInvisibleInCommands", false) && target != null
|
||||
&& sender instanceof Player && !plugin.hasPermissionToSee((Player) sender, target)) {
|
||||
|
||||
if (plugin.getSettings().getBoolean("IndicationFeatures.LayeredPermissions.HideInvisibleInCommands", false)
|
||||
&& target != null && sender instanceof Player
|
||||
&& !plugin.hasPermissionToSee((Player) sender, target))
|
||||
{
|
||||
|
||||
plugin.sendMessage(sender, "PlayerNonExistent", sender, name);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (hide && (offline ? isVanished(uuid) : isVanished(uuid))) {
|
||||
|
||||
plugin.sendMessage(sender, "AlreadyInvisibleMessage", sender, name);
|
||||
return;
|
||||
|
||||
} else if (!hide && !(offline ? isVanished(uuid) : isVanished(uuid))) {
|
||||
|
||||
plugin.sendMessage(sender, "AlreadyVisibleMessage", sender, name);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (args.length == 3)
|
||||
silent = args[2].equalsIgnoreCase("-s");
|
||||
else if (args.length == 2)
|
||||
silent = args[1].equalsIgnoreCase("-s");
|
||||
if (!offline) {
|
||||
|
||||
if (hide) {
|
||||
|
||||
plugin.getVisibilityChanger().hidePlayer(target, sender.getName(), silent);
|
||||
plugin.sendMessage(sender, "HideOtherMessage", sender, name);
|
||||
|
||||
} else {
|
||||
|
||||
plugin.getVisibilityChanger().showPlayer(target, sender.getName());
|
||||
plugin.sendMessage(sender, "ShowOtherMessage", sender, name, silent);
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (hide) {
|
||||
|
||||
plugin.getVanishStateMgr().setVanishedState(uuid, name, true, sender.getName());
|
||||
plugin.sendMessage(sender, "HideOtherMessage", sender, name);
|
||||
|
||||
} else {
|
||||
|
||||
plugin.getVanishStateMgr().setVanishedState(uuid, name, false, sender.getName());
|
||||
plugin.sendMessage(sender, "ShowOtherMessage", sender, name);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,40 +19,63 @@ import org.bukkit.entity.Player;
|
||||
public class VanishSelf extends SubCommand {
|
||||
|
||||
public VanishSelf(SuperVanish plugin) {
|
||||
|
||||
super(plugin);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Command cmd, CommandSender s, String[] args, String label) {
|
||||
|
||||
if (canDo(s, CommandAction.VANISH_SELF, true)) {
|
||||
|
||||
Player p = (Player) s;
|
||||
if (args.length == 0) {
|
||||
|
||||
if (isVanished(p.getUniqueId()))
|
||||
showPlayer(p);
|
||||
else
|
||||
hidePlayer(p);
|
||||
|
||||
} else if (args.length == 1) {
|
||||
if (args[0].equalsIgnoreCase("off")
|
||||
|| args[0].equalsIgnoreCase("reappear")
|
||||
|| args[0].equalsIgnoreCase("disable")) {
|
||||
|
||||
if (args[0].equalsIgnoreCase("off") || args[0].equalsIgnoreCase("reappear")
|
||||
|| args[0].equalsIgnoreCase("disable"))
|
||||
{
|
||||
|
||||
if (!isVanished(p.getUniqueId())) {
|
||||
|
||||
plugin.sendMessage(p, "NotVanishedError", p);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
showPlayer(p);
|
||||
|
||||
} else if (args[0].equalsIgnoreCase("-s")) {
|
||||
|
||||
if (isVanished(p.getUniqueId()))
|
||||
plugin.getVisibilityChanger().showPlayer(p, null, true);
|
||||
else
|
||||
plugin.getVisibilityChanger().hidePlayer(p, null, true);
|
||||
|
||||
} else {
|
||||
|
||||
if (isVanished(p.getUniqueId())) {
|
||||
|
||||
plugin.sendMessage(p, "AlreadyVanishedError", p);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
hidePlayer(p);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,12 +10,14 @@ package de.myzelyam.supervanish.commands.subcommands;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import de.myzelyam.supervanish.PlaceholderConverter;
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
import de.myzelyam.supervanish.commands.CommandAction;
|
||||
import de.myzelyam.supervanish.commands.SubCommand;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
@@ -25,30 +27,53 @@ import java.util.UUID;
|
||||
public class VanishedList extends SubCommand {
|
||||
|
||||
public VanishedList(SuperVanish plugin) {
|
||||
|
||||
super(plugin);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Command cmd, final CommandSender sender, final String[] args, String label) {
|
||||
if (canDo(sender, CommandAction.VANISHED_LIST, true)) {
|
||||
String listMessage = plugin.getMessage("ListMessagePrefix");
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
List<UUID> allInvisiblePlayerUUIDs = ImmutableList.copyOf(getAllVanishedPlayers());
|
||||
if (allInvisiblePlayerUUIDs.isEmpty()) {
|
||||
stringBuilder = stringBuilder.append("none");
|
||||
}
|
||||
for (int i = 0; i < allInvisiblePlayerUUIDs.size(); i++) {
|
||||
UUID playerUUID = allInvisiblePlayerUUIDs.get(i);
|
||||
String name = Bukkit.getOfflinePlayer(playerUUID).getName();
|
||||
if (Bukkit.getPlayer(playerUUID) == null) {
|
||||
name = name + ChatColor.RED + "[offline]" + ChatColor.WHITE;
|
||||
}
|
||||
stringBuilder = stringBuilder.append(name);
|
||||
if (i != allInvisiblePlayerUUIDs.size() - 1)
|
||||
stringBuilder = stringBuilder.append(ChatColor.GREEN).append(", ").append(ChatColor.WHITE);
|
||||
}
|
||||
listMessage = listMessage.replace("%l", stringBuilder.toString());
|
||||
plugin.sendMessage(sender, listMessage, sender);
|
||||
|
||||
if (!canDo(sender, CommandAction.VANISHED_LIST, true)) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
String listMessage = plugin.getMessage("ListMessagePrefix");
|
||||
final StringBuilder stringBuilder = new StringBuilder();
|
||||
final List<UUID> allInvisiblePlayerUUIDs = ImmutableList.copyOf(getAllVanishedPlayers());
|
||||
if (allInvisiblePlayerUUIDs.isEmpty()) {
|
||||
|
||||
stringBuilder.append("none");
|
||||
|
||||
}
|
||||
|
||||
for (int i = 0; i < allInvisiblePlayerUUIDs.size(); i++) {
|
||||
|
||||
final UUID playerUUID = allInvisiblePlayerUUIDs.get(i);
|
||||
String name = Bukkit.getOfflinePlayer(playerUUID).getName();
|
||||
if (Bukkit.getPlayer(playerUUID) == null) {
|
||||
|
||||
name = LegacyComponentSerializer.legacySection()
|
||||
.serialize(MiniMessage.miniMessage().deserialize(name + "<red>[offline]<white>"));
|
||||
|
||||
}
|
||||
|
||||
stringBuilder.append(name);
|
||||
if (i != allInvisiblePlayerUUIDs.size() - 1) {
|
||||
|
||||
stringBuilder.append(LegacyComponentSerializer.legacySection()
|
||||
.serialize(MiniMessage.miniMessage().deserialize("<green>, <white>")));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
plugin.sendMessage(sender, listMessage, sender,
|
||||
PlaceholderConverter.placeholder("vanished_list", stringBuilder.toString()));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,89 +10,128 @@ package de.myzelyam.supervanish.config;
|
||||
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import static de.myzelyam.supervanish.SuperVanish.*;
|
||||
|
||||
@Data
|
||||
public class ConfigMgr {
|
||||
|
||||
private final SuperVanish plugin;
|
||||
private final FileMgr fileMgr;
|
||||
private boolean settingsUpdateRequired, messagesUpdateRequired;
|
||||
private FileConfiguration settings, messages, playerData;
|
||||
private ConfigurableFile messagesFile, settingsFile;
|
||||
private StorageFile playerDataFile;
|
||||
private boolean messagesUpdateRequired;
|
||||
private FileConfiguration settings;
|
||||
private FileConfiguration messages;
|
||||
private ConfigurableFile messagesFile;
|
||||
private ConfigurableFile settingsFile;
|
||||
|
||||
public ConfigMgr(SuperVanish plugin) {
|
||||
|
||||
this.plugin = plugin;
|
||||
fileMgr = new FileMgr(plugin);
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void prepareFiles() {
|
||||
|
||||
// messages
|
||||
messagesFile = (ConfigurableFile) fileMgr.addFile("messages", FileMgr.FileType.CONFIG);
|
||||
messagesFile = (ConfigurableFile) fileMgr.addFile("messages");
|
||||
messages = messagesFile.getConfig();
|
||||
// settings
|
||||
settingsFile = (ConfigurableFile) fileMgr.addFile("config", FileMgr.FileType.CONFIG);
|
||||
settingsFile = (ConfigurableFile) fileMgr.addFile("config");
|
||||
settings = settingsFile.getConfig();
|
||||
// data
|
||||
playerDataFile = (StorageFile) fileMgr.addFile("data", FileMgr.FileType.STORAGE);
|
||||
playerData = playerDataFile.getConfig();
|
||||
playerData.addDefault("InvisiblePlayers", Collections.emptyList());
|
||||
playerData.options().copyDefaults(true);
|
||||
playerData.options().header("SuperVanish v" + plugin.getDescription().getVersion() + " - Data file");
|
||||
playerDataFile.save();
|
||||
|
||||
checkFilesForLeftOvers();
|
||||
}
|
||||
|
||||
public void checkFilesForLeftOvers() {
|
||||
|
||||
try {
|
||||
String currentSettingsVersion = settings.getString("ConfigVersion");
|
||||
String newestVersion = plugin.getDescription().getVersion();
|
||||
|
||||
String newestVersion = plugin.getPluginMeta().getVersion();
|
||||
String currentMessagesVersion = messages.getString("MessagesVersion");
|
||||
messagesUpdateRequired = fileRequiresRecreation(currentMessagesVersion, false);
|
||||
settingsUpdateRequired = fileRequiresRecreation(currentSettingsVersion, true);
|
||||
if (newestVersion.equals(currentSettingsVersion))
|
||||
settingsUpdateRequired = false;
|
||||
messagesUpdateRequired = fileRequiresRecreation(currentMessagesVersion);
|
||||
if (newestVersion.equals(currentMessagesVersion))
|
||||
messagesUpdateRequired = false;
|
||||
if (settingsUpdateRequired || messagesUpdateRequired) {
|
||||
String currentVersion = plugin.getDescription().getVersion();
|
||||
boolean isDismissed = playerData.getBoolean("PlayerData.CONSOLE.dismissed."
|
||||
+ currentVersion.replace(".", "_"), false);
|
||||
if (!isDismissed) plugin.log(Level.WARNING, "At least one config file is outdated, " +
|
||||
"it's recommended to regenerate it using '/sv recreatefiles'");
|
||||
}
|
||||
if (currentSettingsVersion.startsWith("1.5.") || currentSettingsVersion.startsWith("1.4.")) {
|
||||
Bukkit.getConsoleSender().sendMessage(ChatColor.YELLOW + "You have a very outdated " +
|
||||
"config file, your settings will not work until you regenerate your SV-files " +
|
||||
"using /sv recreatefiles");
|
||||
if (messagesUpdateRequired) {
|
||||
|
||||
String currentVersion = plugin.getPluginMeta().getVersion();
|
||||
boolean isDismissed = plugin.getVanishStateMgr().isDismissed("CONSOLE", currentVersion);
|
||||
if (!isDismissed)
|
||||
plugin.log(Level.WARNING,
|
||||
"Messages file needs to be recreated. " + "Use '/sv recreatefiles' to regenerate it.");
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
plugin.logException(e);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean fileRequiresRecreation(String currentVersion, boolean isSettingsFile) {
|
||||
if (currentVersion == null) return true;
|
||||
for (String ignoredVersion : isSettingsFile ? NON_REQUIRED_SETTINGS_UPDATES
|
||||
: NON_REQUIRED_MESSAGES_UPDATES) {
|
||||
if (currentVersion.equalsIgnoreCase(ignoredVersion)) return false;
|
||||
private boolean fileRequiresRecreation(String currentVersion) {
|
||||
|
||||
if (currentVersion == null)
|
||||
return true;
|
||||
for (String ignoredVersion : NON_REQUIRED_MESSAGES_UPDATES) {
|
||||
|
||||
if (currentVersion.equalsIgnoreCase(ignoredVersion))
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public FileMgr getFileMgr() {
|
||||
|
||||
return fileMgr;
|
||||
|
||||
}
|
||||
|
||||
public boolean isMessagesUpdateRequired() {
|
||||
|
||||
return messagesUpdateRequired;
|
||||
|
||||
}
|
||||
|
||||
public FileConfiguration getSettings() {
|
||||
|
||||
return settings;
|
||||
|
||||
}
|
||||
|
||||
public FileConfiguration getMessages() {
|
||||
|
||||
return messages;
|
||||
|
||||
}
|
||||
|
||||
public void setSettings(FileConfiguration settings) {
|
||||
|
||||
this.settings = settings;
|
||||
|
||||
}
|
||||
|
||||
public void setMessages(FileConfiguration messages) {
|
||||
|
||||
this.messages = messages;
|
||||
|
||||
}
|
||||
|
||||
public ConfigurableFile getMessagesFile() {
|
||||
|
||||
return messagesFile;
|
||||
|
||||
}
|
||||
|
||||
public ConfigurableFile getSettingsFile() {
|
||||
|
||||
return settingsFile;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,47 +27,72 @@ public class ConfigurableFile implements PluginFile<FileConfiguration> {
|
||||
private FileConfiguration defaultFileConfiguration;
|
||||
|
||||
public ConfigurableFile(String name, SuperVanish plugin) {
|
||||
|
||||
this.name = name + ".yml";
|
||||
this.plugin = plugin;
|
||||
setup();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
|
||||
return name;
|
||||
|
||||
}
|
||||
|
||||
private void setup() {
|
||||
|
||||
file = new File(plugin.getDataFolder(), name);
|
||||
try (Reader reader = new InputStreamReader(plugin.getResource(name))) {
|
||||
|
||||
defaultFileConfiguration = YamlConfiguration.loadConfiguration(reader);
|
||||
|
||||
} catch (IOException e) {
|
||||
|
||||
e.printStackTrace();
|
||||
|
||||
}
|
||||
|
||||
save();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
|
||||
fileConfiguration = YamlConfiguration.loadConfiguration(file);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileConfiguration getConfig() {
|
||||
|
||||
if (fileConfiguration == null) {
|
||||
|
||||
reload();
|
||||
|
||||
}
|
||||
|
||||
return fileConfiguration;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
|
||||
if (!file.exists()) {
|
||||
|
||||
plugin.saveResource(name, false);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public FileConfiguration getDefaultConfig() {
|
||||
|
||||
return defaultFileConfiguration;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,40 +20,37 @@ public class FileMgr {
|
||||
private Map<String, PluginFile<?>> files;
|
||||
|
||||
public FileMgr(SuperVanishPlugin plugin) {
|
||||
|
||||
this.plugin = plugin;
|
||||
files = new HashMap<>();
|
||||
|
||||
}
|
||||
|
||||
public PluginFile<?> addFile(String name, FileType type) {
|
||||
public PluginFile<?> addFile(String name) {
|
||||
|
||||
if (name == null)
|
||||
throw new IllegalArgumentException("The file name cannot be null!");
|
||||
if (type == FileType.STORAGE) {
|
||||
StorageFile file = new StorageFile(name, (SuperVanish) plugin);
|
||||
files.put(name, file);
|
||||
return file;
|
||||
} else if (type == FileType.CONFIG) {
|
||||
ConfigurableFile file = new ConfigurableFile(name, (SuperVanish) plugin);
|
||||
files.put(name, file);
|
||||
return file;
|
||||
} else {
|
||||
throw new IllegalArgumentException("The FileType cannot be null!");
|
||||
}
|
||||
ConfigurableFile file = new ConfigurableFile(name, (SuperVanish) plugin);
|
||||
files.put(name, file);
|
||||
return file;
|
||||
|
||||
}
|
||||
|
||||
public void reloadFile(String fileName) {
|
||||
|
||||
PluginFile<?> file = files.get(fileName);
|
||||
if (file != null)
|
||||
file.reload();
|
||||
else
|
||||
throw new IllegalArgumentException("Specified file doesn't exist!");
|
||||
|
||||
}
|
||||
|
||||
public void reloadAll() {
|
||||
|
||||
for (String fileName : files.keySet())
|
||||
reloadFile(fileName);
|
||||
|
||||
}
|
||||
|
||||
public enum FileType {
|
||||
STORAGE, CONFIG
|
||||
}
|
||||
}
|
||||
@@ -17,4 +17,5 @@ public interface PluginFile<CT> {
|
||||
CT getConfig();
|
||||
|
||||
void save();
|
||||
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package de.myzelyam.supervanish.config;
|
||||
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class StorageFile implements PluginFile<FileConfiguration> {
|
||||
|
||||
private final SuperVanish plugin;
|
||||
private String name;
|
||||
private File file;
|
||||
private FileConfiguration config;
|
||||
|
||||
public StorageFile(String name, SuperVanish plugin) {
|
||||
this.name = name;
|
||||
this.plugin = plugin;
|
||||
setup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
private void setup() {
|
||||
file = new File(plugin.getDataFolder().getPath() + File.separator
|
||||
+ name + ".yml");
|
||||
config = YamlConfiguration.loadConfiguration(file);
|
||||
save();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
setup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileConfiguration getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
try {
|
||||
config.save(file);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package de.myzelyam.supervanish.features;
|
||||
|
||||
import de.myzelyam.api.vanish.PlayerShowEvent;
|
||||
import de.myzelyam.api.vanish.PostPlayerHideEvent;
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
|
||||
public class Broadcast extends Feature {
|
||||
|
||||
public Broadcast(SuperVanish plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
public static void announceSilentJoin(Player vanished, SuperVanish plugin) {
|
||||
if (plugin.getSettings().getBoolean("MessageOptions.AnnounceRealJoinQuitToAdmins", true)) {
|
||||
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
|
||||
if (vanished == onlinePlayer)
|
||||
continue;
|
||||
if (plugin.canSee(onlinePlayer, vanished)) {
|
||||
plugin.sendMessage(onlinePlayer, "SilentJoinMessageForAdmins", vanished, onlinePlayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void announceSilentQuit(Player p, SuperVanish plugin) {
|
||||
if (plugin.getSettings().getBoolean("MessageOptions.AnnounceRealJoinQuitToAdmins", true)) {
|
||||
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
|
||||
if (p == onlinePlayer)
|
||||
continue;
|
||||
if (plugin.canSee(onlinePlayer, p)) {
|
||||
plugin.sendMessage(onlinePlayer, "SilentQuitMessageForAdmins", p, onlinePlayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return plugin.getSettings().getBoolean("MessageOptions.FakeJoinQuitMessages.BroadcastFakeQuitOnVanish")
|
||||
|| plugin.getSettings().getBoolean("MessageOptions.FakeJoinQuitMessages" +
|
||||
".BroadcastFakeQuitOnReappear");
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onVanish(PostPlayerHideEvent e) {
|
||||
final Player p = e.getPlayer();
|
||||
if (plugin.getSettings().getBoolean("MessageOptions.FakeJoinQuitMessages.BroadcastFakeQuitOnVanish")
|
||||
&& !e.isSilent()) {
|
||||
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
|
||||
if (!plugin.canSee(onlinePlayer, p)) {
|
||||
if (!plugin.getSettings().getBoolean(
|
||||
"MessageOptions.FakeJoinQuitMessages.SendMessageOnlyToAdmins"))
|
||||
plugin.sendMessage(onlinePlayer, "VanishMessage", p, onlinePlayer);
|
||||
} else if (!plugin.getSettings().getBoolean(
|
||||
"MessageOptions.FakeJoinQuitMessages.SendMessageOnlyToUsers"))
|
||||
if (!plugin.getSettings().getBoolean(
|
||||
"MessageOptions.FakeJoinQuitMessages.AnnounceVanishReappearToAdmins"))
|
||||
plugin.sendMessage(onlinePlayer, "VanishMessage", p, onlinePlayer);
|
||||
else if (onlinePlayer == p && !plugin.getSettings().getBoolean(
|
||||
"MessageOptions.FakeJoinQuitMessages.SendMessageOnlyToAdmins"))
|
||||
plugin.sendMessage(onlinePlayer, "VanishMessage", p, onlinePlayer);
|
||||
else if (onlinePlayer != p)
|
||||
plugin.sendMessage(onlinePlayer, "VanishMessageWithPermission", p, onlinePlayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onReappear(PlayerShowEvent e) {
|
||||
Player p = e.getPlayer();
|
||||
if (plugin.getSettings().getBoolean(
|
||||
"MessageOptions.FakeJoinQuitMessages.BroadcastFakeJoinOnReappear") && !e.isSilent()) {
|
||||
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
|
||||
if (!plugin.canSee(onlinePlayer, p)) {
|
||||
if (!plugin.getSettings().getBoolean(
|
||||
"MessageOptions.FakeJoinQuitMessages.SendMessageOnlyToAdmins"))
|
||||
plugin.sendMessage(onlinePlayer, "ReappearMessage", p, onlinePlayer);
|
||||
} else if (!plugin.getSettings().getBoolean(
|
||||
"MessageOptions.FakeJoinQuitMessages.SendMessageOnlyToUsers"))
|
||||
if (!plugin.getSettings().getBoolean(
|
||||
"MessageOptions.FakeJoinQuitMessages.AnnounceVanishReappearToAdmins"))
|
||||
plugin.sendMessage(onlinePlayer, "ReappearMessageWithPermission", p, onlinePlayer);
|
||||
else if (onlinePlayer == p && !plugin.getSettings().getBoolean(
|
||||
"MessageOptions.FakeJoinQuitMessages.SendMessageOnlyToAdmins"))
|
||||
plugin.sendMessage(onlinePlayer, "ReappearMessage", p, onlinePlayer);
|
||||
else if (onlinePlayer != p)
|
||||
plugin.sendMessage(onlinePlayer, "ReappearMessageWithPermission", p, onlinePlayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,18 +20,25 @@ public abstract class Feature implements Listener {
|
||||
protected final SuperVanish plugin;
|
||||
|
||||
public Feature(SuperVanish plugin) {
|
||||
|
||||
this.plugin = plugin;
|
||||
|
||||
}
|
||||
|
||||
public void onEnable() {
|
||||
|
||||
}
|
||||
|
||||
public void onDisable() {
|
||||
|
||||
}
|
||||
|
||||
public abstract boolean isActive();
|
||||
|
||||
protected void delay(Runnable runnable) {
|
||||
|
||||
plugin.getServer().getScheduler().runTaskLater(plugin, runnable, 1);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,12 +8,6 @@
|
||||
|
||||
package de.myzelyam.supervanish.features;
|
||||
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
import de.myzelyam.supervanish.utils.Requirement;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@@ -23,95 +17,149 @@ import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import lombok.Data;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
import de.myzelyam.supervanish.utils.Requirement;
|
||||
|
||||
public class FeatureMgr {
|
||||
|
||||
private static Requirement<FeatureInfo> protocolLibInstalled = new Requirement<FeatureInfo>() {
|
||||
@Override
|
||||
public boolean fulfilledBy(FeatureInfo featureInfo) {
|
||||
return Bukkit.getPluginManager().isPluginEnabled("ProtocolLib");
|
||||
}
|
||||
}, oneDotEightOrHigher = new Requirement<FeatureInfo>() {
|
||||
@Override
|
||||
public boolean fulfilledBy(FeatureInfo featureInfo) {
|
||||
return featureInfo.getPlugin().getVersionUtil().isOneDotXOrHigher(8);
|
||||
}
|
||||
};
|
||||
private static final Requirement<FeatureInfo> protocolLibInstalled = featureInfo -> Bukkit.getPluginManager()
|
||||
.isPluginEnabled("ProtocolLib");
|
||||
private static final Requirement<FeatureInfo> oneDotEightOrHigher = featureInfo -> featureInfo.getPlugin()
|
||||
.getVersionUtil().isOneDotXOrHigher(8);
|
||||
private static final Requirement<FeatureInfo> oneDotSeventeenOrHigher = featureInfo -> featureInfo.getPlugin()
|
||||
.getVersionUtil().isOneDotXOrHigher(17);
|
||||
private static final Requirement<FeatureInfo> supportedServer = featureInfo -> "Paper"
|
||||
.equals(Bukkit.getServer().getName()) || "Purpur".equals(Bukkit.getServer().getName());
|
||||
private final Map<String, FeatureInfo> registeredFeatures = new HashMap<>();
|
||||
private final Set<Feature> activeFeatures = new HashSet<>();
|
||||
private final SuperVanish plugin;
|
||||
|
||||
public FeatureMgr(SuperVanish plugin) {
|
||||
|
||||
this.plugin = plugin;
|
||||
registeredFeatures.put("SilentOpenChest", new FeatureInfo(SilentOpenChest.class, plugin,
|
||||
Arrays.asList(protocolLibInstalled, oneDotEightOrHigher)));
|
||||
registeredFeatures.put("NightVision", new FeatureInfo(NightVision.class, plugin,
|
||||
Arrays.asList(protocolLibInstalled, oneDotEightOrHigher)));
|
||||
registeredFeatures.put("NightVision",
|
||||
new FeatureInfo(NightVision.class, plugin, Arrays.asList(protocolLibInstalled, oneDotEightOrHigher)));
|
||||
registeredFeatures.put("VanishIndication", new FeatureInfo(VanishIndication.class, plugin,
|
||||
Arrays.asList(protocolLibInstalled, oneDotEightOrHigher)));
|
||||
registeredFeatures.put("Broadcast", new FeatureInfo(Broadcast.class, plugin));
|
||||
registeredFeatures.put("NoSculkSensorDetection", new FeatureInfo(NoSculkSensorDetection.class, plugin,
|
||||
Collections.singletonList(oneDotSeventeenOrHigher)));
|
||||
registeredFeatures.put("NoTurtleEggBreaking",
|
||||
new FeatureInfo(NoTurtleEggBreaking.class, plugin, Collections.singletonList(oneDotSeventeenOrHigher)));
|
||||
registeredFeatures.put("NoDripLeafTilt",
|
||||
new FeatureInfo(NoDripLeafTilt.class, plugin, Collections.singletonList(oneDotSeventeenOrHigher)));
|
||||
registeredFeatures.put("NoRaidTrigger",
|
||||
new FeatureInfo(NoRaidTrigger.class, plugin, Collections.singletonList(oneDotSeventeenOrHigher)));
|
||||
registeredFeatures.put("NoMobSpawn",
|
||||
new FeatureInfo(NoMobSpawn.class, plugin, Collections.singletonList(supportedServer)));
|
||||
|
||||
}
|
||||
|
||||
public void enableFeatures() {
|
||||
featureLoop:
|
||||
for (String id : registeredFeatures.keySet()) {
|
||||
FeatureInfo featureInfo = registeredFeatures.get(id);
|
||||
|
||||
featureLoop: for (String id : registeredFeatures.keySet()) {
|
||||
|
||||
final FeatureInfo featureInfo = registeredFeatures.get(id);
|
||||
for (Requirement<FeatureInfo> requirement : featureInfo.getRequirements()) {
|
||||
if (!requirement.fulfilledBy(featureInfo)) continue featureLoop;
|
||||
|
||||
if (!requirement.fulfilledBy(featureInfo)) {
|
||||
|
||||
continue featureLoop;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Feature feature;
|
||||
|
||||
final Feature feature;
|
||||
try {
|
||||
|
||||
feature = featureInfo.getFeatureClass().getConstructor(SuperVanish.class).newInstance(plugin);
|
||||
} catch (NoSuchMethodException | InvocationTargetException
|
||||
| InstantiationException | IllegalAccessException e) {
|
||||
|
||||
} catch (NoSuchMethodException | InvocationTargetException | InstantiationException
|
||||
| IllegalAccessException e)
|
||||
{
|
||||
|
||||
plugin.logException(e);
|
||||
continue;
|
||||
|
||||
}
|
||||
if (!feature.isActive()) continue;
|
||||
|
||||
if (!feature.isActive()) {
|
||||
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
activeFeatures.add(feature);
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(feature, plugin);
|
||||
|
||||
feature.onEnable();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void disableFeatures() {
|
||||
for (Feature feature : activeFeatures) {
|
||||
|
||||
activeFeatures.forEach(feature -> {
|
||||
|
||||
feature.onDisable();
|
||||
HandlerList.unregisterAll(feature);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
activeFeatures.clear();
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Feature> T getFeature(Class<T> featureClass) {
|
||||
for (Feature feature : activeFeatures) {
|
||||
if (feature.getClass().equals(featureClass)) {
|
||||
//noinspection unchecked
|
||||
return (T) feature;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
// noinspection unchecked on purpose
|
||||
return activeFeatures.stream().filter(feature -> feature.getClass().equals(featureClass)).findFirst()
|
||||
.map(feature -> (T) feature).orElse(null);
|
||||
|
||||
}
|
||||
|
||||
public Set<Feature> getActiveFeatures() {
|
||||
|
||||
return activeFeatures;
|
||||
|
||||
}
|
||||
|
||||
@Data
|
||||
private static class FeatureInfo {
|
||||
private final Class<? extends Feature> featureClass;
|
||||
private final Collection<Requirement<FeatureInfo>> requirements;
|
||||
private final SuperVanish plugin;
|
||||
|
||||
FeatureInfo(Class<? extends Feature> featureClass, SuperVanish plugin,
|
||||
Collection<Requirement<FeatureInfo>> requirements) {
|
||||
this.featureClass = featureClass;
|
||||
this.requirements = requirements;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
private record FeatureInfo(Class<? extends Feature> featureClass, SuperVanish plugin,
|
||||
Collection<Requirement<FeatureInfo>> requirements)
|
||||
{
|
||||
|
||||
FeatureInfo(Class<? extends Feature> featureClass, SuperVanish plugin) {
|
||||
this(featureClass, plugin, Collections.<Requirement<FeatureInfo>>emptySet());
|
||||
|
||||
this(featureClass, plugin, Collections.emptySet());
|
||||
|
||||
}
|
||||
|
||||
public Class<? extends Feature> getFeatureClass() {
|
||||
|
||||
return featureClass;
|
||||
|
||||
}
|
||||
|
||||
public Collection<Requirement<FeatureInfo>> getRequirements() {
|
||||
|
||||
return requirements;
|
||||
|
||||
}
|
||||
|
||||
public SuperVanish getPlugin() {
|
||||
|
||||
return plugin;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,130 +8,162 @@
|
||||
|
||||
package de.myzelyam.supervanish.features;
|
||||
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
|
||||
import de.myzelyam.api.vanish.PlayerHideEvent;
|
||||
import de.myzelyam.api.vanish.PlayerShowEvent;
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.player.PlayerChangedWorldEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.comphenix.protocol.PacketType.Play.Server.*;
|
||||
|
||||
public class NightVision extends Feature implements Runnable {
|
||||
|
||||
public static final int INFINITE_POTION_EFFECT_LENGTH = 32767;
|
||||
|
||||
private final Map<UUID, PotionEffect> playerPreviousPotionEffectMap = new HashMap<>();
|
||||
|
||||
public NightVision(SuperVanish plugin) {
|
||||
|
||||
super(plugin);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
|
||||
plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, this, 20 * 60 * 2, 20 * 60 * 2);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
|
||||
return plugin.getSettings().getBoolean("InvisibilityFeatures.NightVisionEffect");
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onVanish(PlayerHideEvent e) {
|
||||
|
||||
Player p = e.getPlayer();
|
||||
sendAddPotionEffect(p, new PotionEffect(PotionEffectType.NIGHT_VISION,
|
||||
INFINITE_POTION_EFFECT_LENGTH, 0));
|
||||
// getPotionEffect(..) is 1.10+ API
|
||||
if (plugin.getVersionUtil().isOneDotXOrHigher(10)) {
|
||||
|
||||
if (p.getPotionEffect(PotionEffectType.NIGHT_VISION) != null) {
|
||||
|
||||
playerPreviousPotionEffectMap.put(p.getUniqueId(), p.getPotionEffect(PotionEffectType.NIGHT_VISION));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sendAddPotionEffect(p);
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onReappear(PlayerShowEvent e) {
|
||||
|
||||
Player p = e.getPlayer();
|
||||
sendRemovePotionEffect(p, PotionEffectType.NIGHT_VISION);
|
||||
sendRemovePotionEffect(p);
|
||||
if (playerPreviousPotionEffectMap.containsKey(p.getUniqueId())) {
|
||||
|
||||
p.addPotionEffect(playerPreviousPotionEffectMap.remove(p.getUniqueId()));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(PlayerJoinEvent e) {
|
||||
|
||||
Player p = e.getPlayer();
|
||||
if (!plugin.getVanishStateMgr().isVanished(p.getUniqueId())) {
|
||||
|
||||
if (playerPreviousPotionEffectMap.containsKey(p.getUniqueId())) {
|
||||
|
||||
p.addPotionEffect(playerPreviousPotionEffectMap.remove(p.getUniqueId()));
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
sendAddPotionEffect(p);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onQuit(PlayerQuitEvent e) {
|
||||
|
||||
Player p = e.getPlayer();
|
||||
if (!plugin.getVanishStateMgr().isVanished(p.getUniqueId()))
|
||||
return;
|
||||
sendAddPotionEffect(p, new PotionEffect(PotionEffectType.NIGHT_VISION,
|
||||
INFINITE_POTION_EFFECT_LENGTH, 0));
|
||||
sendRemovePotionEffect(p);
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onTeleport(PlayerTeleportEvent e) {
|
||||
|
||||
Player p = e.getPlayer();
|
||||
if (!plugin.getVanishStateMgr().isVanished(p.getUniqueId()))
|
||||
return;
|
||||
if (e.getFrom().getWorld() == null || e.getTo() == null || e.getTo().getWorld() == null
|
||||
|| e.getFrom().getWorld().getName().equals(e.getTo().getWorld().getName()))
|
||||
return;
|
||||
sendRemovePotionEffect(p);
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onWorldChange(PlayerChangedWorldEvent e) {
|
||||
|
||||
Player p = e.getPlayer();
|
||||
if (!plugin.getVanishStateMgr().isVanished(p.getUniqueId()))
|
||||
return;
|
||||
sendAddPotionEffect(p, new PotionEffect(PotionEffectType.NIGHT_VISION,
|
||||
INFINITE_POTION_EFFECT_LENGTH, 0));
|
||||
sendAddPotionEffect(p);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
// renew every now and then to prevent blinking bug
|
||||
for (UUID uuid : plugin.getVanishStateMgr().getOnlineVanishedPlayers()) {
|
||||
|
||||
Player p = Bukkit.getPlayer(uuid);
|
||||
if (p == null) continue;
|
||||
sendRemovePotionEffect(p, PotionEffectType.NIGHT_VISION);
|
||||
sendAddPotionEffect(p, new PotionEffect(PotionEffectType.NIGHT_VISION,
|
||||
INFINITE_POTION_EFFECT_LENGTH, 0));
|
||||
if (p == null)
|
||||
continue;
|
||||
sendRemovePotionEffect(p);
|
||||
sendAddPotionEffect(p);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void sendAddPotionEffect(Player p, PotionEffect effect) {
|
||||
PacketContainer packet = new PacketContainer(ENTITY_EFFECT);
|
||||
//noinspection deprecation
|
||||
int effectID = effect.getType().getId();
|
||||
int amplifier = effect.getAmplifier();
|
||||
int duration = effect.getDuration();
|
||||
int entityID = p.getEntityId();
|
||||
packet.getIntegers().write(0, entityID);
|
||||
packet.getBytes().write(0, (byte) effectID);
|
||||
packet.getBytes().write(1, (byte) amplifier);
|
||||
packet.getIntegers().write(1, duration);
|
||||
// hide particles in 1.9
|
||||
packet.getBytes().write(2, (byte) 0);
|
||||
try {
|
||||
ProtocolLibrary.getProtocolManager().sendServerPacket(p, packet);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new RuntimeException("Cannot send packet", e);
|
||||
}
|
||||
private void sendAddPotionEffect(Player p) {
|
||||
|
||||
p.addPotionEffect(
|
||||
new PotionEffect(PotionEffectType.NIGHT_VISION, INFINITE_POTION_EFFECT_LENGTH, 0, true, false));
|
||||
|
||||
}
|
||||
|
||||
private void sendRemovePotionEffect(Player p, PotionEffectType type) {
|
||||
PacketContainer packet = new PacketContainer(REMOVE_ENTITY_EFFECT);
|
||||
//noinspection deprecation
|
||||
final int effectID = type.getId();
|
||||
final int entityID = p.getEntityId();
|
||||
// 1.7 and below
|
||||
if (!plugin.getVersionUtil().isOneDotXOrHigher(8)) {
|
||||
packet.getIntegers().write(0, entityID);
|
||||
packet.getBytes().write(0, (byte) effectID);
|
||||
} else if (plugin.getVersionUtil().isOneDotX(8)) {
|
||||
// 1.8
|
||||
packet.getIntegers().write(0, entityID);
|
||||
packet.getIntegers().write(1, effectID);
|
||||
} else {
|
||||
// 1.9 and higher
|
||||
packet.getEffectTypes().write(0, type);
|
||||
packet.getIntegers().write(0, entityID);
|
||||
}
|
||||
try {
|
||||
ProtocolLibrary.getProtocolManager().sendServerPacket(p, packet);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new RuntimeException("Cannot send packet", e);
|
||||
}
|
||||
private void sendRemovePotionEffect(Player p) {
|
||||
|
||||
p.removePotionEffect(PotionEffectType.NIGHT_VISION);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package de.myzelyam.supervanish.features;
|
||||
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
|
||||
public class NoDripLeafTilt extends Feature {
|
||||
|
||||
public NoDripLeafTilt(SuperVanish plugin) {
|
||||
|
||||
super(plugin);
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onInteract(PlayerInteractEvent e) {
|
||||
|
||||
Player p = e.getPlayer();
|
||||
if (!plugin.getVanishStateMgr().isVanished(p.getUniqueId()))
|
||||
return;
|
||||
if (!e.getAction().equals(Action.PHYSICAL) || e.getClickedBlock() == null
|
||||
|| !e.getClickedBlock().getType().toString().equals("BIG_DRIPLEAF"))
|
||||
return;
|
||||
e.setCancelled(true);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
|
||||
return plugin.getSettings().getBoolean("InvisibilityFeatures.DisableDripLeaf", true);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
package de.myzelyam.supervanish.features;
|
||||
|
||||
import com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent;
|
||||
import com.destroystokyo.paper.event.entity.PreSpawnerSpawnEvent;
|
||||
import com.destroystokyo.paper.event.entity.SkeletonHorseTrapEvent;
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class NoMobSpawn extends Feature {
|
||||
|
||||
private boolean suppressErrors = false;
|
||||
|
||||
public NoMobSpawn(SuperVanish plugin) {
|
||||
|
||||
super(plugin);
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onSkeletonHorseTrap(SkeletonHorseTrapEvent e) {
|
||||
|
||||
try {
|
||||
|
||||
List<HumanEntity> humans = e.getEligibleHumans();
|
||||
int humansCount = humans.size();
|
||||
for (HumanEntity human : humans) {
|
||||
|
||||
if (human instanceof Player) {
|
||||
|
||||
Player p = (Player) human;
|
||||
if (plugin.getVanishStateMgr().isVanished(p.getUniqueId())) {
|
||||
|
||||
humansCount--;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (humansCount == 0)
|
||||
e.setCancelled(true);
|
||||
|
||||
} catch (Exception er) {
|
||||
|
||||
if (!suppressErrors) {
|
||||
|
||||
plugin.logException(er);
|
||||
suppressErrors = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onEntitySpawn(PlayerNaturallySpawnCreaturesEvent e) {
|
||||
|
||||
try {
|
||||
|
||||
if (plugin.getVanishStateMgr().isVanished(e.getPlayer().getUniqueId()))
|
||||
e.setCancelled(true);
|
||||
|
||||
} catch (Exception er) {
|
||||
|
||||
if (!suppressErrors) {
|
||||
|
||||
plugin.logException(er);
|
||||
suppressErrors = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onEntitySpawnerSpawn(PreSpawnerSpawnEvent e) {
|
||||
|
||||
try {
|
||||
|
||||
// First check if a non-spectator vanished player is in range
|
||||
boolean vanishedPlayerInRange = false;
|
||||
for (UUID vanishedUUID : plugin.getVanishStateMgr().getOnlineVanishedPlayers()) {
|
||||
|
||||
Player p = Bukkit.getPlayer(vanishedUUID);
|
||||
if (p == null)
|
||||
continue;
|
||||
if (p.getWorld().equals(e.getSpawnerLocation().getWorld())
|
||||
&& p.getLocation().distanceSquared(e.getSpawnerLocation()) <= 256
|
||||
&& p.getGameMode() != GameMode.SPECTATOR)
|
||||
vanishedPlayerInRange = true;
|
||||
|
||||
}
|
||||
|
||||
if (!vanishedPlayerInRange)
|
||||
return;
|
||||
|
||||
// If so, only cancel if no non-vanished player is in range
|
||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||
|
||||
if (p.getWorld().equals(e.getSpawnerLocation().getWorld())
|
||||
&& p.getLocation().distanceSquared(e.getSpawnerLocation()) <= 256
|
||||
&& p.getGameMode() != GameMode.SPECTATOR
|
||||
&& !plugin.getVanishStateMgr().isVanished(p.getUniqueId()))
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
e.setCancelled(true);
|
||||
|
||||
} catch (Exception er) {
|
||||
|
||||
if (!suppressErrors) {
|
||||
|
||||
plugin.logException(er);
|
||||
suppressErrors = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
|
||||
return plugin.getSettings().getBoolean("InvisibilityFeatures.PreventMobSpawning", true);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -23,56 +23,82 @@ import org.bukkit.scoreboard.Team;
|
||||
public class NoPush extends Feature {
|
||||
|
||||
public NoPush(SuperVanish plugin) {
|
||||
|
||||
super(plugin);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
|
||||
return plugin.getSettings().getBoolean("InvisibilityFeatures.DisablePush");
|
||||
|
||||
}
|
||||
|
||||
public void setCantPush(Player p) {
|
||||
|
||||
Team team = p.getScoreboard().getTeam("Vanished");
|
||||
if (team == null) {
|
||||
|
||||
team = p.getScoreboard().registerNewTeam("Vanished");
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
team.setOption(Team.Option.COLLISION_RULE, Team.OptionStatus.NEVER);
|
||||
team.addEntry(p.getName());
|
||||
|
||||
} catch (NoSuchMethodError | NoClassDefFoundError ignored) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setCanPush(Player p) {
|
||||
|
||||
Team team = p.getScoreboard().getTeam("Vanished");
|
||||
if (team != null)
|
||||
team.removeEntry(p.getName());
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onVanish(PlayerHideEvent e) {
|
||||
|
||||
setCantPush(e.getPlayer());
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onReappear(PlayerShowEvent e) {
|
||||
|
||||
setCanPush(e.getPlayer());
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(final PlayerJoinEvent e) {
|
||||
|
||||
if (plugin.getVanishStateMgr().isVanished(e.getPlayer().getUniqueId()))
|
||||
new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
setCantPush(e.getPlayer());
|
||||
|
||||
}
|
||||
|
||||
}.runTaskLater(plugin, 5);
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onQuit(PlayerQuitEvent e) {
|
||||
|
||||
setCanPush(e.getPlayer());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package de.myzelyam.supervanish.features;
|
||||
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.raid.RaidTriggerEvent;
|
||||
|
||||
public class NoRaidTrigger extends Feature {
|
||||
|
||||
public NoRaidTrigger(SuperVanish plugin) {
|
||||
|
||||
super(plugin);
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onInteract(RaidTriggerEvent e) {
|
||||
|
||||
Player p = e.getPlayer();
|
||||
if (!plugin.getVanishStateMgr().isVanished(p.getUniqueId()))
|
||||
return;
|
||||
e.setCancelled(true);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
|
||||
return plugin.getSettings().getBoolean("InvisibilityFeatures.PreventRaidTriggering", true);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package de.myzelyam.supervanish.features;
|
||||
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.block.BlockReceiveGameEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
|
||||
public class NoSculkSensorDetection extends Feature {
|
||||
|
||||
public NoSculkSensorDetection(SuperVanish plugin) {
|
||||
|
||||
super(plugin);
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onSculkSensorTrigger(BlockReceiveGameEvent e) {
|
||||
|
||||
if (!(e.getEntity() instanceof Player))
|
||||
return;
|
||||
Player p = (Player) e.getEntity();
|
||||
if (!plugin.getVanishStateMgr().isVanished(p.getUniqueId()))
|
||||
return;
|
||||
e.setCancelled(true);
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onInteract(PlayerInteractEvent e) {
|
||||
|
||||
Player p = e.getPlayer();
|
||||
if (!plugin.getVanishStateMgr().isVanished(p.getUniqueId()))
|
||||
return;
|
||||
if (!e.getAction().equals(Action.PHYSICAL) || e.getClickedBlock() == null)
|
||||
return;
|
||||
if (!e.getClickedBlock().getType().toString().matches("SCULK_SENSOR|CALIBRATED_SCULK_SENSOR|SCULK_SHRIEKER"))
|
||||
return;
|
||||
e.setCancelled(true);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
|
||||
return plugin.getSettings().getBoolean("InvisibilityFeatures.PreventSculkSensorActivation", true);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package de.myzelyam.supervanish.features;
|
||||
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
|
||||
public class NoTurtleEggBreaking extends Feature {
|
||||
|
||||
public NoTurtleEggBreaking(SuperVanish plugin) {
|
||||
|
||||
super(plugin);
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onInteract(PlayerInteractEvent e) {
|
||||
|
||||
Player p = e.getPlayer();
|
||||
if (!plugin.getVanishStateMgr().isVanished(p.getUniqueId()))
|
||||
return;
|
||||
if (!e.getAction().equals(Action.PHYSICAL) || e.getClickedBlock() == null
|
||||
|| !e.getClickedBlock().getType().toString().equals("TURTLE_EGG"))
|
||||
return;
|
||||
e.setCancelled(true);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
|
||||
return plugin.getSettings().getBoolean("InvisibilityFeatures.PreventTurtleEggBreaking", true);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,20 +8,36 @@
|
||||
|
||||
package de.myzelyam.supervanish.features;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import static org.bukkit.Material.BLACK_SHULKER_BOX;
|
||||
import static org.bukkit.Material.BLUE_SHULKER_BOX;
|
||||
import static org.bukkit.Material.BROWN_SHULKER_BOX;
|
||||
import static org.bukkit.Material.CHEST;
|
||||
import static org.bukkit.Material.CYAN_SHULKER_BOX;
|
||||
import static org.bukkit.Material.ENDER_CHEST;
|
||||
import static org.bukkit.Material.GRAY_SHULKER_BOX;
|
||||
import static org.bukkit.Material.GREEN_SHULKER_BOX;
|
||||
import static org.bukkit.Material.ITEM_FRAME;
|
||||
import static org.bukkit.Material.LIGHT_BLUE_SHULKER_BOX;
|
||||
import static org.bukkit.Material.LIGHT_GRAY_SHULKER_BOX;
|
||||
import static org.bukkit.Material.LIME_SHULKER_BOX;
|
||||
import static org.bukkit.Material.MAGENTA_SHULKER_BOX;
|
||||
import static org.bukkit.Material.ORANGE_SHULKER_BOX;
|
||||
import static org.bukkit.Material.PINK_SHULKER_BOX;
|
||||
import static org.bukkit.Material.PURPLE_SHULKER_BOX;
|
||||
import static org.bukkit.Material.RED_SHULKER_BOX;
|
||||
import static org.bukkit.Material.SHULKER_BOX;
|
||||
import static org.bukkit.Material.TRAPPED_CHEST;
|
||||
import static org.bukkit.Material.WHITE_SHULKER_BOX;
|
||||
import static org.bukkit.Material.YELLOW_SHULKER_BOX;
|
||||
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.events.ListenerPriority;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
||||
import com.comphenix.protocol.wrappers.PlayerInfoData;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import de.myzelyam.api.vanish.PlayerShowEvent;
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -38,276 +54,403 @@ import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import static com.comphenix.protocol.PacketType.Play.Server.*;
|
||||
import static org.bukkit.Material.*;
|
||||
import de.myzelyam.api.vanish.PlayerShowEvent;
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
import de.myzelyam.supervanish.hooks.OpenInvHook;
|
||||
|
||||
public class SilentOpenChest extends Feature {
|
||||
|
||||
private final Map<Player, StateInfo> playerStateInfoMap = new HashMap<>();
|
||||
|
||||
private final Collection<Material> shulkerBoxes;
|
||||
private final Collection<Material> additionalChestMaterials;
|
||||
|
||||
public SilentOpenChest(SuperVanish plugin) {
|
||||
|
||||
super(plugin);
|
||||
shulkerBoxes = new ArrayList<>();
|
||||
additionalChestMaterials = new ArrayList<>();
|
||||
if (plugin.getVersionUtil().isOneDotXOrHigher(11)) {
|
||||
|
||||
try {
|
||||
//noinspection unused
|
||||
InventoryType testInvType = InventoryType.SHULKER_BOX;
|
||||
shulkerBoxes.addAll(Arrays.asList(BLACK_SHULKER_BOX, BLUE_SHULKER_BOX, BROWN_SHULKER_BOX,
|
||||
CYAN_SHULKER_BOX, GRAY_SHULKER_BOX, GREEN_SHULKER_BOX, LIGHT_BLUE_SHULKER_BOX,
|
||||
LIME_SHULKER_BOX, MAGENTA_SHULKER_BOX, ORANGE_SHULKER_BOX, PINK_SHULKER_BOX,
|
||||
PURPLE_SHULKER_BOX, RED_SHULKER_BOX, SILVER_SHULKER_BOX, WHITE_SHULKER_BOX,
|
||||
YELLOW_SHULKER_BOX));
|
||||
} catch (NoSuchFieldError ignored) {
|
||||
|
||||
additionalChestMaterials.addAll(Arrays.asList(BLACK_SHULKER_BOX, BLUE_SHULKER_BOX, BROWN_SHULKER_BOX,
|
||||
CYAN_SHULKER_BOX, GRAY_SHULKER_BOX, GREEN_SHULKER_BOX, LIGHT_BLUE_SHULKER_BOX, LIME_SHULKER_BOX,
|
||||
MAGENTA_SHULKER_BOX, ORANGE_SHULKER_BOX, PINK_SHULKER_BOX, PURPLE_SHULKER_BOX, RED_SHULKER_BOX,
|
||||
WHITE_SHULKER_BOX, YELLOW_SHULKER_BOX));
|
||||
try {
|
||||
|
||||
additionalChestMaterials.add(LIGHT_GRAY_SHULKER_BOX);
|
||||
|
||||
} catch (NoSuchFieldError e) {
|
||||
|
||||
// Old name.
|
||||
additionalChestMaterials.add(Material.valueOf("SILVER_SHULKER_BOX"));
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
additionalChestMaterials.add(SHULKER_BOX);
|
||||
|
||||
} catch (NoSuchFieldError ignored) {
|
||||
|
||||
// no standard shulker box in old versions
|
||||
}
|
||||
|
||||
if (plugin.getVersionUtil().isOneDotXOrHigher(14)) {
|
||||
|
||||
additionalChestMaterials.add(Material.valueOf("BARREL"));
|
||||
|
||||
}
|
||||
|
||||
} catch (NoSuchFieldError | IllegalArgumentException ignored) {
|
||||
|
||||
// no shulker box support in very old versions
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
|
||||
for (Player p : playerStateInfoMap.keySet()) {
|
||||
StateInfo stateInfo = playerStateInfoMap.remove(p);
|
||||
if (stateInfo == null) continue;
|
||||
|
||||
final StateInfo stateInfo = playerStateInfoMap.remove(p);
|
||||
if (stateInfo == null) {
|
||||
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
restoreState(stateInfo, p);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onSpectatorClick(InventoryClickEvent e) {
|
||||
if (!(e.getWhoClicked() instanceof Player))
|
||||
|
||||
if (!(e.getWhoClicked() instanceof Player)) {
|
||||
|
||||
return;
|
||||
Player p = (Player) e.getWhoClicked();
|
||||
if (!plugin.getVanishStateMgr().isVanished(p.getUniqueId())) return;
|
||||
if (!playerStateInfoMap.containsKey(p)) return;
|
||||
if (p.getGameMode() != GameMode.SURVIVAL && p.getGameMode() != GameMode.ADVENTURE
|
||||
&& p.getGameMode() != GameMode.CREATIVE) {
|
||||
e.setCancelled(false);
|
||||
|
||||
}
|
||||
|
||||
final Player p = (Player) e.getWhoClicked();
|
||||
if (!plugin.getVanishStateMgr().isVanished(p.getUniqueId())) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (!playerStateInfoMap.containsKey(p)) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (p.getGameMode() == GameMode.SPECTATOR) {
|
||||
|
||||
e.setCancelled(false);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onQuit(PlayerQuitEvent e) {
|
||||
Player p = e.getPlayer();
|
||||
StateInfo stateInfo = playerStateInfoMap.remove(p);
|
||||
if (stateInfo == null) return;
|
||||
|
||||
final Player p = e.getPlayer();
|
||||
final StateInfo stateInfo = playerStateInfoMap.remove(p);
|
||||
if (stateInfo == null) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
restoreState(stateInfo, p);
|
||||
|
||||
playerStateInfoMap.remove(p);
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onTeleport(PlayerTeleportEvent e) {
|
||||
Player p = e.getPlayer();
|
||||
if (playerStateInfoMap.containsKey(p)
|
||||
&& e.getCause() == PlayerTeleportEvent.TeleportCause.SPECTATE) {
|
||||
|
||||
final Player p = e.getPlayer();
|
||||
if (playerStateInfoMap.containsKey(p) && e.getCause() == PlayerTeleportEvent.TeleportCause.SPECTATE) {
|
||||
|
||||
e.setCancelled(true);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onReappear(PlayerShowEvent e) {
|
||||
Player p = e.getPlayer();
|
||||
StateInfo stateInfo = playerStateInfoMap.remove(p);
|
||||
if (stateInfo == null) return;
|
||||
|
||||
final Player p = e.getPlayer();
|
||||
final StateInfo stateInfo = playerStateInfoMap.remove(p);
|
||||
if (stateInfo == null) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
p.closeInventory();
|
||||
|
||||
restoreState(stateInfo, p);
|
||||
|
||||
playerStateInfoMap.remove(p);
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onMove(PlayerMoveEvent e) {
|
||||
Player p = e.getPlayer();
|
||||
if (playerStateInfoMap.containsKey(p)) {
|
||||
if (!(p.getOpenInventory().getType() == InventoryType.CHEST ||
|
||||
plugin.getVersionUtil().isOneDotXOrHigher(11)
|
||||
&& isShulkerBox(p.getOpenInventory()))) {
|
||||
restoreState(playerStateInfoMap.get(p), p);
|
||||
playerStateInfoMap.remove(p);
|
||||
}
|
||||
|
||||
final Player p = e.getPlayer();
|
||||
if (!playerStateInfoMap.containsKey(p)) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
final Location loc = e.getTo() != null ? e.getTo() : e.getFrom();
|
||||
if (playerStateInfoMap.get(p).openLoc.distance(loc) <= .5) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
p.closeInventory();
|
||||
|
||||
restoreState(playerStateInfoMap.get(p), p);
|
||||
|
||||
playerStateInfoMap.remove(p);
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
@EventHandler(priority = EventPriority.NORMAL)
|
||||
public void onGameModeChange(PlayerGameModeChangeEvent e) {
|
||||
Player p = e.getPlayer();
|
||||
if (playerStateInfoMap.containsKey(p) && e.getNewGameMode() != GameMode.SPECTATOR) {
|
||||
// Don't let low-priority event listeners cancel the gamemode change
|
||||
if (e.isCancelled()) e.setCancelled(false);
|
||||
|
||||
final Player p = e.getPlayer();
|
||||
final boolean condition = playerStateInfoMap.containsKey(p) && e.getNewGameMode() != GameMode.SPECTATOR
|
||||
&& e.isCancelled();
|
||||
// Don't let low-priority event listeners cancel the gamemode change.
|
||||
if (condition) {
|
||||
|
||||
e.setCancelled(false);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onChestInteract(PlayerInteractEvent e) {
|
||||
Player p = e.getPlayer();
|
||||
if (!plugin.getVanishStateMgr().isVanished(p.getUniqueId())) return;
|
||||
if (e.getAction() != Action.RIGHT_CLICK_BLOCK) return;
|
||||
if (p.getGameMode() == GameMode.SPECTATOR) return;
|
||||
//noinspection deprecation
|
||||
if (p.isSneaking() && p.getItemInHand() != null
|
||||
&& p.getItemInHand().getType().isBlock()
|
||||
&& p.getItemInHand().getType() != Material.AIR)
|
||||
|
||||
final Player p = e.getPlayer();
|
||||
if (!plugin.getVanishStateMgr().isVanished(p.getUniqueId()) || !p.hasPermission("sv.silentchest")) {
|
||||
|
||||
return;
|
||||
Block block = e.getClickedBlock();
|
||||
if (block == null) return;
|
||||
|
||||
}
|
||||
|
||||
if (e.getAction() != Action.RIGHT_CLICK_BLOCK) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (p.getGameMode() == GameMode.SPECTATOR) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
final ItemStack heldItem = p.getInventory().getItemInMainHand();
|
||||
if (p.isSneaking() && heldItem != null && (heldItem.getType().isBlock() || heldItem.getType() == ITEM_FRAME)
|
||||
&& heldItem.getType() != Material.AIR)
|
||||
{
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
final Block block = e.getClickedBlock();
|
||||
if (block == null) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (block.getType() == ENDER_CHEST) {
|
||||
|
||||
e.setCancelled(true);
|
||||
p.openInventory(p.getEnderChest());
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (!(block.getType() == CHEST || block.getType() == TRAPPED_CHEST
|
||||
|| plugin.getVersionUtil().isOneDotXOrHigher(11) && shulkerBoxes.contains(block.getType())))
|
||||
|| plugin.getVersionUtil().isOneDotXOrHigher(11) && additionalChestMaterials.contains(block.getType())))
|
||||
{
|
||||
|
||||
return;
|
||||
StateInfo stateInfo = StateInfo.extract(p);
|
||||
|
||||
}
|
||||
|
||||
final StateInfo stateInfo = StateInfo.extract(p);
|
||||
|
||||
p.setVelocity(new Vector(0, 0, 0));
|
||||
|
||||
playerStateInfoMap.put(p, stateInfo);
|
||||
|
||||
p.setGameMode(GameMode.SPECTATOR);
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onChestClose(InventoryCloseEvent e) {
|
||||
if (!(e.getPlayer() instanceof Player))
|
||||
return;
|
||||
final Player p = (Player) e.getPlayer();
|
||||
if (!playerStateInfoMap.containsKey(p)) return;
|
||||
if (!(p.getInventory().getType() == InventoryType.CHEST ||
|
||||
plugin.getVersionUtil().isOneDotXOrHigher(11)
|
||||
&& isShulkerBox(p.getInventory()))) {
|
||||
|
||||
if (!(e.getPlayer() instanceof Player)) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
final Player p = (Player) e.getPlayer();
|
||||
if (!playerStateInfoMap.containsKey(p)) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (!isSilentOpenInventory(e.getView())) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
StateInfo stateInfo = playerStateInfoMap.get(p);
|
||||
if (stateInfo == null) return;
|
||||
|
||||
final StateInfo stateInfo = playerStateInfoMap.get(p);
|
||||
if (stateInfo == null) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
restoreState(stateInfo, p);
|
||||
|
||||
playerStateInfoMap.remove(p);
|
||||
|
||||
}
|
||||
|
||||
}.runTaskLater(plugin, 1);
|
||||
|
||||
}
|
||||
|
||||
private void restoreState(StateInfo stateInfo, Player p) {
|
||||
|
||||
p.setGameMode(stateInfo.gameMode);
|
||||
p.setAllowFlight(stateInfo.canFly);
|
||||
p.setFlying(stateInfo.isFlying);
|
||||
p.teleport(p.getLocation().add(0, 0.2, 0));
|
||||
new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
p.setAllowFlight(stateInfo.canFly);
|
||||
p.setFlying(stateInfo.isFlying);
|
||||
|
||||
}
|
||||
|
||||
}.runTaskLater(plugin, 1);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return plugin.getSettings().getBoolean("InvisibilityFeatures.OpenChestsSilently");
|
||||
|
||||
return plugin.getSettings().getBoolean("InvisibilityFeatures.OpenChestsSilently")
|
||||
&& !(plugin.getPluginHookMgr() != null && plugin.getPluginHookMgr().isHookActive(OpenInvHook.class));
|
||||
|
||||
}
|
||||
|
||||
private boolean isShulkerBox(Inventory inv) {
|
||||
|
||||
try {
|
||||
|
||||
return inv.getType() == InventoryType.SHULKER_BOX;
|
||||
|
||||
} catch (NoSuchFieldError e) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean isShulkerBox(InventoryView inv) {
|
||||
|
||||
return isShulkerBox(inv.getTopInventory());
|
||||
|
||||
}
|
||||
|
||||
private boolean isBarrel(InventoryView inv) {
|
||||
|
||||
try {
|
||||
return inv.getType() == InventoryType.SHULKER_BOX;
|
||||
|
||||
return inv.getType() == InventoryType.BARREL;
|
||||
|
||||
} catch (NoSuchFieldError e) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean isSilentOpenInventory(InventoryView inv) {
|
||||
|
||||
return inv.getType() == InventoryType.CHEST || inv.getType() == InventoryType.ENDER_CHEST || isShulkerBox(inv)
|
||||
|| isBarrel(inv);
|
||||
|
||||
}
|
||||
|
||||
public boolean hasSilentlyOpenedChest(Player p) {
|
||||
|
||||
return playerStateInfoMap.containsKey(p);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(
|
||||
new PacketAdapter(plugin, ListenerPriority.LOW, PLAYER_INFO, GAME_STATE_CHANGE, ABILITIES,
|
||||
ENTITY_METADATA) {
|
||||
@Override
|
||||
public void onPacketSending(PacketEvent event) {
|
||||
try {
|
||||
if (event.getPacketType() == PLAYER_INFO) {
|
||||
// multiple events share same packet object
|
||||
event.setPacket(event.getPacket().shallowClone());
|
||||
|
||||
List<PlayerInfoData> infoDataList = new ArrayList<>(
|
||||
event.getPacket().getPlayerInfoDataLists().read(0));
|
||||
Player receiver = event.getPlayer();
|
||||
for (PlayerInfoData infoData : ImmutableList.copyOf(infoDataList)) {
|
||||
if (!SilentOpenChest.this.plugin.getVisibilityChanger().getHider()
|
||||
.isHidden(infoData.getProfile().getUUID(), receiver)
|
||||
&& SilentOpenChest.this.plugin.getVanishStateMgr()
|
||||
.isVanished(infoData.getProfile().getUUID())) {
|
||||
Player vanishedTabPlayer = Bukkit.getPlayer(infoData.getProfile().getUUID());
|
||||
if (infoData.getGameMode() == EnumWrappers.NativeGameMode.SPECTATOR
|
||||
&& hasSilentlyOpenedChest(vanishedTabPlayer)
|
||||
&& event.getPacket().getPlayerInfoAction().read(0)
|
||||
== EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE) {
|
||||
int latency;
|
||||
try {
|
||||
latency = infoData.getLatency();
|
||||
} catch (NoSuchMethodError e) {
|
||||
latency = 21;
|
||||
}
|
||||
PlayerInfoData newData = new PlayerInfoData(infoData.getProfile(),
|
||||
latency, EnumWrappers.NativeGameMode.SURVIVAL,
|
||||
infoData.getDisplayName());
|
||||
infoDataList.remove(infoData);
|
||||
infoDataList.add(newData);
|
||||
}
|
||||
}
|
||||
}
|
||||
event.getPacket().getPlayerInfoDataLists().write(0, infoDataList);
|
||||
} else if (event.getPacketType() == GAME_STATE_CHANGE) {
|
||||
if (SilentOpenChest.this.plugin.getVanishStateMgr().isVanished(
|
||||
event.getPlayer().getUniqueId())) {
|
||||
if (event.getPacket().getIntegers().read(0) != 3) return;
|
||||
if (!hasSilentlyOpenedChest(event.getPlayer())) return;
|
||||
event.setCancelled(true);
|
||||
}
|
||||
} else if (event.getPacketType() == ABILITIES) {
|
||||
if (SilentOpenChest.this.plugin.getVanishStateMgr().isVanished(
|
||||
event.getPlayer().getUniqueId())) {
|
||||
if (!hasSilentlyOpenedChest(event.getPlayer())) return;
|
||||
event.setCancelled(true);
|
||||
}
|
||||
} else if (event.getPacketType() == ENTITY_METADATA) {
|
||||
int entityID = event.getPacket().getIntegers().read(0);
|
||||
if (entityID == event.getPlayer().getEntityId()) {
|
||||
if (SilentOpenChest.this.plugin.getVanishStateMgr().isVanished(
|
||||
event.getPlayer().getUniqueId())) {
|
||||
if (!hasSilentlyOpenedChest(event.getPlayer())) return;
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (e.getMessage() == null
|
||||
|| !e.getMessage().endsWith("is not supported for temporary players.")) {
|
||||
SilentOpenChest.this.plugin.logException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
// ProtocolLib 5.0 maps PLAYER_INFO to ClientboundPlayerInfoUpdatePacket
|
||||
final SilentOpenChestPacketAdapter packetAdapter = new SilentOpenChestPacketAdapter(this);
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(packetAdapter);
|
||||
|
||||
}
|
||||
|
||||
@Data
|
||||
private static class StateInfo {
|
||||
|
||||
private final boolean canFly, isFlying;
|
||||
private final GameMode gameMode;
|
||||
private record StateInfo(boolean canFly, boolean isFlying, GameMode gameMode, Location openLoc) {
|
||||
|
||||
static StateInfo extract(Player p) {
|
||||
return new StateInfo(
|
||||
p.getAllowFlight(),
|
||||
p.isFlying(),
|
||||
p.getGameMode()
|
||||
);
|
||||
|
||||
return new StateInfo(p.getAllowFlight(), p.isFlying(), p.getGameMode(), p.getLocation());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* license, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package de.myzelyam.supervanish.features;
|
||||
|
||||
import com.comphenix.protocol.events.ListenerPriority;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.reflect.FieldAccessException;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
||||
import com.comphenix.protocol.wrappers.PlayerInfoData;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.comphenix.protocol.PacketType.Play.Server.*;
|
||||
|
||||
/**
|
||||
* Adapter that masks a vanished player's silent-chest spectator state from
|
||||
* other clients. On Purpur 1.19.4 ProtocolLib's PLAYER_INFO type maps to
|
||||
* ClientboundPlayerInfoUpdatePacket which carries a Set<Action> instead of the
|
||||
* legacy single action; ViaSuite handles client-side re-encoding for connected
|
||||
* versions 1.8-1.21.x.
|
||||
*/
|
||||
public class SilentOpenChestPacketAdapter extends PacketAdapter {
|
||||
|
||||
private final SilentOpenChest silentOpenChest;
|
||||
|
||||
private boolean suppressErrors = false;
|
||||
|
||||
public SilentOpenChestPacketAdapter(SilentOpenChest silentOpenChest) {
|
||||
|
||||
super(silentOpenChest.plugin, ListenerPriority.LOW, PLAYER_INFO, ABILITIES, ENTITY_METADATA);
|
||||
this.silentOpenChest = silentOpenChest;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketSending(PacketEvent event) {
|
||||
|
||||
try {
|
||||
|
||||
Player receiver = event.getPlayer();
|
||||
if (receiver == null)
|
||||
return;
|
||||
if (event.getPacketType() == PLAYER_INFO) {
|
||||
|
||||
// multiple events share same packet object
|
||||
event.setPacket(event.getPacket().shallowClone());
|
||||
|
||||
if (!isGameModeUpdate(event))
|
||||
return;
|
||||
|
||||
List<PlayerInfoData> infoDataList = new ArrayList<>(event.getPacket().getPlayerInfoDataLists().read(0));
|
||||
boolean modified = false;
|
||||
for (PlayerInfoData infoData : ImmutableList.copyOf(infoDataList)) {
|
||||
|
||||
UUID uuid = extractUUID(infoData);
|
||||
if (uuid == null)
|
||||
continue;
|
||||
if (silentOpenChest.plugin.getVisibilityChanger().getHider().isHidden(uuid, receiver))
|
||||
continue;
|
||||
if (!silentOpenChest.plugin.getVanishStateMgr().isVanished(uuid))
|
||||
continue;
|
||||
if (infoData.getGameMode() != EnumWrappers.NativeGameMode.SPECTATOR)
|
||||
continue;
|
||||
|
||||
Player vanishedTabPlayer = Bukkit.getPlayer(uuid);
|
||||
if (vanishedTabPlayer == null || !silentOpenChest.hasSilentlyOpenedChest(vanishedTabPlayer))
|
||||
continue;
|
||||
|
||||
PlayerInfoData newData = new PlayerInfoData(uuid, infoData.getLatency(), infoData.isListed(),
|
||||
EnumWrappers.NativeGameMode.SURVIVAL, infoData.getProfile(), infoData.getDisplayName(),
|
||||
infoData.getRemoteChatSessionData());
|
||||
int index = infoDataList.indexOf(infoData);
|
||||
infoDataList.set(index, newData);
|
||||
modified = true;
|
||||
|
||||
}
|
||||
|
||||
if (modified)
|
||||
event.getPacket().getPlayerInfoDataLists().write(0, infoDataList);
|
||||
|
||||
} else if (event.getPacketType() == GAME_STATE_CHANGE) {
|
||||
|
||||
// Currently unused due to ProtocolLib class loading bug
|
||||
if (silentOpenChest.plugin.getVanishStateMgr().isVanished(receiver.getUniqueId())) {
|
||||
|
||||
try {
|
||||
|
||||
if (event.getPacket().getIntegers().read(0) != 3)
|
||||
return;
|
||||
|
||||
} catch (FieldAccessException e) {
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
if (!silentOpenChest.hasSilentlyOpenedChest(receiver))
|
||||
return;
|
||||
event.setCancelled(true);
|
||||
|
||||
}
|
||||
|
||||
} else if (event.getPacketType() == ABILITIES) {
|
||||
|
||||
if (silentOpenChest.plugin.getVanishStateMgr().isVanished(receiver.getUniqueId())) {
|
||||
|
||||
if (!silentOpenChest.hasSilentlyOpenedChest(receiver))
|
||||
return;
|
||||
event.setCancelled(true);
|
||||
|
||||
}
|
||||
|
||||
} else if (event.getPacketType() == ENTITY_METADATA) {
|
||||
|
||||
int entityID = event.getPacket().getIntegers().read(0);
|
||||
if (entityID == receiver.getEntityId()) {
|
||||
|
||||
if (silentOpenChest.plugin.getVanishStateMgr().isVanished(receiver.getUniqueId())) {
|
||||
|
||||
if (!silentOpenChest.hasSilentlyOpenedChest(receiver))
|
||||
return;
|
||||
event.setCancelled(true);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception | NoClassDefFoundError e) {
|
||||
|
||||
if (!suppressErrors) {
|
||||
|
||||
if (e.getMessage() == null || !e.getMessage().endsWith("is not supported for temporary players.")) {
|
||||
|
||||
silentOpenChest.plugin.logException(e);
|
||||
silentOpenChest.plugin.getLogger()
|
||||
.warning("IMPORTANT: Please make sure that you are using the latest "
|
||||
+ "dev-build of ProtocolLib and that your server is up-to-date! This error likely "
|
||||
+ "happened inside of ProtocolLib code which is out of Vanish-OG's control. It's part "
|
||||
+ "of an optional feature module and can be removed safely by disabling "
|
||||
+ "OpenChestsSilently in the config file. Please report this "
|
||||
+ "error if you can reproduce it on an up-to-date server with only latest "
|
||||
+ "ProtocolLib and latest Vanish-OG installed.");
|
||||
suppressErrors = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean isGameModeUpdate(PacketEvent event) {
|
||||
|
||||
// 1.19.3+: ClientboundPlayerInfoUpdatePacket exposes Set<Action>
|
||||
try {
|
||||
|
||||
Set<EnumWrappers.PlayerInfoAction> actions = event.getPacket().getPlayerInfoActions().read(0);
|
||||
if (actions != null)
|
||||
return actions.contains(EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE);
|
||||
|
||||
} catch (FieldAccessException | IllegalArgumentException ignored) {
|
||||
|
||||
// legacy single-action packet on pre-1.19.3
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
EnumWrappers.PlayerInfoAction action = event.getPacket().getPlayerInfoAction().read(0);
|
||||
return action == EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE;
|
||||
|
||||
} catch (FieldAccessException | IllegalArgumentException ignored) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private UUID extractUUID(PlayerInfoData infoData) {
|
||||
|
||||
UUID uuid = infoData.getProfileId();
|
||||
if (uuid != null)
|
||||
return uuid;
|
||||
if (infoData.getProfile() != null)
|
||||
return infoData.getProfile().getUUID();
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,153 +8,309 @@
|
||||
|
||||
package de.myzelyam.supervanish.features;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.events.ListenerPriority;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.reflect.FieldAccessException;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
||||
import com.comphenix.protocol.wrappers.PlayerInfoData;
|
||||
import com.comphenix.protocol.wrappers.WrappedChatComponent;
|
||||
import com.comphenix.protocol.wrappers.WrappedGameProfile;
|
||||
|
||||
import com.comphenix.protocol.wrappers.WrappedRemoteChatSessionData;
|
||||
import de.myzelyam.api.vanish.PlayerShowEvent;
|
||||
import de.myzelyam.api.vanish.PostPlayerHideEvent;
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import static com.comphenix.protocol.PacketType.Play.Server.PLAYER_INFO;
|
||||
|
||||
/**
|
||||
* Marks visible vanished players as spectators in player info updates. On
|
||||
* Purpur 1.19.4 this operates on the server-native
|
||||
* ClientboundPlayerInfoUpdatePacket format and ViaSuite handles translation for
|
||||
* connected 1.8-1.21.x clients.
|
||||
*/
|
||||
public class VanishIndication extends Feature {
|
||||
|
||||
private boolean suppressErrors = false;
|
||||
|
||||
public VanishIndication(SuperVanish plugin) {
|
||||
|
||||
super(plugin);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
|
||||
return plugin.getSettings().getBoolean("IndicationFeatures.MarkVanishedPlayersAsSpectators");
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onVanish(PostPlayerHideEvent e) {
|
||||
|
||||
Player p = e.getPlayer();
|
||||
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
|
||||
|
||||
if (!plugin.getVisibilityChanger().getHider().isHidden(p, onlinePlayer) && p != onlinePlayer) {
|
||||
|
||||
sendPlayerInfoChangeGameModePacket(onlinePlayer, p, true);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onReappear(PlayerShowEvent e) {
|
||||
|
||||
final Player p = e.getPlayer();
|
||||
for (final Player onlinePlayer : Bukkit.getOnlinePlayers()) {
|
||||
|
||||
if (!plugin.getVisibilityChanger().getHider().isHidden(p, onlinePlayer) && p != onlinePlayer) {
|
||||
delay(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
sendPlayerInfoChangeGameModePacket(onlinePlayer, p, false);
|
||||
}
|
||||
});
|
||||
|
||||
delay(() -> sendPlayerInfoChangeGameModePacket(onlinePlayer, p, false));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(PlayerJoinEvent e) {
|
||||
|
||||
final Player p = e.getPlayer();
|
||||
delay(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// tell others that p is a spectator
|
||||
if (plugin.getVanishStateMgr().isVanished(p.getUniqueId()))
|
||||
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
|
||||
if (!plugin.getVisibilityChanger().getHider().isHidden(p, onlinePlayer)
|
||||
&& p != onlinePlayer) {
|
||||
sendPlayerInfoChangeGameModePacket(onlinePlayer, p, true);
|
||||
}
|
||||
}
|
||||
// tell p that others are spectators
|
||||
delay(() -> {
|
||||
|
||||
// tell others that p is a spectator
|
||||
if (plugin.getVanishStateMgr().isVanished(p.getUniqueId()))
|
||||
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
|
||||
if (!plugin.getVanishStateMgr().isVanished(onlinePlayer.getUniqueId())) continue;
|
||||
if (!plugin.getVisibilityChanger().getHider().isHidden(onlinePlayer, p)
|
||||
&& p != onlinePlayer) {
|
||||
sendPlayerInfoChangeGameModePacket(p, onlinePlayer, true);
|
||||
|
||||
if (!plugin.getVisibilityChanger().getHider().isHidden(p, onlinePlayer) && p != onlinePlayer) {
|
||||
|
||||
sendPlayerInfoChangeGameModePacket(onlinePlayer, p, true);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// tell p that others are spectators
|
||||
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
|
||||
|
||||
if (!plugin.getVanishStateMgr().isVanished(onlinePlayer.getUniqueId()))
|
||||
continue;
|
||||
if (!plugin.getVisibilityChanger().getHider().isHidden(onlinePlayer, p) && p != onlinePlayer) {
|
||||
|
||||
sendPlayerInfoChangeGameModePacket(p, onlinePlayer, true);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(
|
||||
new PacketAdapter(plugin, ListenerPriority.NORMAL, PacketType.Play.Server.PLAYER_INFO) {
|
||||
new PacketAdapter(plugin, ListenerPriority.NORMAL, PacketType.Play.Server.PLAYER_INFO)
|
||||
{
|
||||
|
||||
@Override
|
||||
public void onPacketSending(PacketEvent event) {
|
||||
// multiple events share same packet object
|
||||
event.setPacket(event.getPacket().shallowClone());
|
||||
List<PlayerInfoData> infoDataList = new ArrayList<>(
|
||||
event.getPacket().getPlayerInfoDataLists().read(0));
|
||||
Player receiver = event.getPlayer();
|
||||
for (PlayerInfoData infoData : ImmutableList.copyOf(infoDataList)) {
|
||||
if (!VanishIndication.this.plugin.getVisibilityChanger().getHider()
|
||||
.isHidden(infoData.getProfile().getUUID(), receiver)
|
||||
&& VanishIndication.this.plugin.getVanishStateMgr()
|
||||
.isVanished(infoData.getProfile().getUUID())) {
|
||||
if (!receiver.getUniqueId().equals(infoData.getProfile().getUUID()))
|
||||
if (infoData.getGameMode() != EnumWrappers.NativeGameMode.SPECTATOR) {
|
||||
int latency;
|
||||
try {
|
||||
latency = infoData.getLatency();
|
||||
} catch (NoSuchMethodError e) {
|
||||
latency = 21;
|
||||
}
|
||||
if (event.getPacket().getPlayerInfoAction().read(0)
|
||||
!= EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE) {
|
||||
continue;
|
||||
}
|
||||
PlayerInfoData newData = new PlayerInfoData(infoData.getProfile(),
|
||||
latency, EnumWrappers.NativeGameMode.SPECTATOR,
|
||||
infoData.getDisplayName());
|
||||
infoDataList.remove(infoData);
|
||||
infoDataList.add(newData);
|
||||
|
||||
try {
|
||||
|
||||
if (VanishIndication.this.plugin.getVanishStateMgr().getOnlineVanishedPlayers().isEmpty())
|
||||
return;
|
||||
|
||||
// multiple events share same packet object
|
||||
event.setPacket(event.getPacket().shallowClone());
|
||||
List<PlayerInfoData> infoDataList = new ArrayList<>(
|
||||
event.getPacket().getPlayerInfoDataLists().read(0));
|
||||
Player receiver = event.getPlayer();
|
||||
boolean modified = false;
|
||||
// Iterate a snapshot (ArrayList tolerates nulls; ImmutableList does not)
|
||||
// so we can safely set() on infoDataList during the loop. ProtocolLib
|
||||
// can hand back null entries during login packet flow on 1.19.4.
|
||||
for (PlayerInfoData infoData : new ArrayList<>(infoDataList)) {
|
||||
|
||||
try {
|
||||
|
||||
if (!isGameModeUpdate(event))
|
||||
break;
|
||||
|
||||
if (infoData == null)
|
||||
continue;
|
||||
if (extractUUID(infoData) == null)
|
||||
continue;
|
||||
if (!VanishIndication.this.plugin.getVisibilityChanger().getHider()
|
||||
.isHidden(extractUUID(infoData), receiver)
|
||||
&& VanishIndication.this.plugin.getVanishStateMgr()
|
||||
.isVanished(extractUUID(infoData)))
|
||||
{
|
||||
|
||||
if (!receiver.getUniqueId().equals(extractUUID(infoData)))
|
||||
if (infoData.getGameMode() != EnumWrappers.NativeGameMode.SPECTATOR) {
|
||||
|
||||
PlayerInfoData newData = createGameModeUpdate(infoData,
|
||||
EnumWrappers.NativeGameMode.SPECTATOR);
|
||||
int index = infoDataList.indexOf(infoData);
|
||||
infoDataList.set(index, newData);
|
||||
modified = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} catch (UnsupportedOperationException ignored) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Untouched packets must not be rewritten: writing back into
|
||||
// ClientboundPlayerInfoUpdatePacket on 1.19.3+ also rewrites its
|
||||
// final EnumSet<Action> field, which ProtocolLib cannot mutate.
|
||||
if (modified)
|
||||
event.getPacket().getPlayerInfoDataLists().write(0, infoDataList);
|
||||
|
||||
} catch (Exception | NoClassDefFoundError e) {
|
||||
|
||||
if (!suppressErrors) {
|
||||
|
||||
VanishIndication.this.plugin.logException(e);
|
||||
plugin.getLogger().warning("IMPORTANT: Please make sure that you are using the latest "
|
||||
+ "dev-build of ProtocolLib and that your server is up-to-date! This error likely "
|
||||
+ "happened inside of ProtocolLib code which is out of Vanish-OG's control. It's part "
|
||||
+ "of an optional feature module and can be removed safely by disabling "
|
||||
+ "MarkVanishedPlayersAsSpectators in the config file. Please report this "
|
||||
+ "error if you can reproduce it on an up-to-date server with only latest "
|
||||
+ "ProtocolLib and latest Vanish-OG installed.");
|
||||
suppressErrors = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
event.getPacket().getPlayerInfoDataLists().write(0, infoDataList);
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void sendPlayerInfoChangeGameModePacket(Player p, Player change, boolean spectator) {
|
||||
|
||||
PacketContainer packet = new PacketContainer(PLAYER_INFO);
|
||||
packet.getPlayerInfoAction().write(0, EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE);
|
||||
if (plugin.getVersionUtil().isOneDotXOrHigher(19)) {
|
||||
|
||||
packet.getPlayerInfoActions().write(0, EnumSet.of(EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE));
|
||||
|
||||
} else {
|
||||
|
||||
packet.getPlayerInfoAction().write(0, EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE);
|
||||
|
||||
}
|
||||
|
||||
List<PlayerInfoData> data = new ArrayList<>();
|
||||
int ping = ThreadLocalRandom.current().nextInt(20) + 15;
|
||||
data.add(new PlayerInfoData(WrappedGameProfile.fromPlayer(change), ping,
|
||||
spectator ? EnumWrappers.NativeGameMode.SPECTATOR
|
||||
: EnumWrappers.NativeGameMode.fromBukkit(change.getGameMode()),
|
||||
WrappedChatComponent.fromText(change.getPlayerListName())));
|
||||
EnumWrappers.NativeGameMode gameMode = spectator ? EnumWrappers.NativeGameMode.SPECTATOR
|
||||
: EnumWrappers.NativeGameMode.fromBukkit(change.getGameMode());
|
||||
WrappedChatComponent displayName = WrappedChatComponent
|
||||
.fromText(LegacyComponentSerializer.legacySection().serialize(change.playerListName()));
|
||||
WrappedGameProfile profile = WrappedGameProfile.fromPlayer(change);
|
||||
if (plugin.getVersionUtil().isOneDotXOrHigher(19)) {
|
||||
|
||||
data.add(new PlayerInfoData(change.getUniqueId(), ping, true, gameMode, profile, displayName,
|
||||
(WrappedRemoteChatSessionData) null));
|
||||
|
||||
} else {
|
||||
|
||||
data.add(new PlayerInfoData(profile, ping, gameMode, displayName));
|
||||
|
||||
}
|
||||
|
||||
packet.getPlayerInfoDataLists().write(0, data);
|
||||
try {
|
||||
|
||||
ProtocolLibrary.getProtocolManager().sendServerPacket(p, packet);
|
||||
} catch (InvocationTargetException e) {
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
throw new RuntimeException("Cannot send packet", e);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean isGameModeUpdate(PacketEvent event) {
|
||||
|
||||
try {
|
||||
|
||||
Set<EnumWrappers.PlayerInfoAction> actions = event.getPacket().getPlayerInfoActions().read(0);
|
||||
if (actions != null)
|
||||
return actions.contains(EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE);
|
||||
|
||||
} catch (FieldAccessException | IllegalArgumentException ignored) {
|
||||
|
||||
// legacy single-action packet on pre-1.19.3
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
EnumWrappers.PlayerInfoAction action = event.getPacket().getPlayerInfoAction().read(0);
|
||||
return action == EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE;
|
||||
|
||||
} catch (FieldAccessException | IllegalArgumentException ignored) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private UUID extractUUID(PlayerInfoData infoData) {
|
||||
|
||||
UUID uuid = infoData.getProfileId();
|
||||
if (uuid != null)
|
||||
return uuid;
|
||||
if (infoData.getProfile() != null)
|
||||
return infoData.getProfile().getUUID();
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
private PlayerInfoData createGameModeUpdate(PlayerInfoData infoData, EnumWrappers.NativeGameMode gameMode) {
|
||||
|
||||
UUID uuid = extractUUID(infoData);
|
||||
if (plugin.getVersionUtil().isOneDotXOrHigher(19)) {
|
||||
|
||||
return new PlayerInfoData(uuid, infoData.getLatency(), infoData.isListed(), gameMode, infoData.getProfile(),
|
||||
infoData.getDisplayName(), infoData.getRemoteChatSessionData());
|
||||
|
||||
}
|
||||
|
||||
return new PlayerInfoData(infoData.getProfile(), infoData.getLatency(), gameMode, infoData.getDisplayName());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,44 +26,62 @@ import java.util.UUID;
|
||||
|
||||
public class CitizensHook extends PluginHook {
|
||||
|
||||
|
||||
public CitizensHook(SuperVanish superVanish) {
|
||||
|
||||
super(superVanish);
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onNPCTarget(NPCSpeechEvent e) {
|
||||
|
||||
e.setCancelled(!checkContext(e.getContext()));
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onSpeechTargeted(SpeechEvent e) {
|
||||
|
||||
e.setCancelled(!checkContext(e.getContext()));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return FALSE if the event should be cancelled, TRUE otherwise
|
||||
*/
|
||||
private boolean checkContext(SpeechContext context) {
|
||||
|
||||
// don't let it talk about hidden players
|
||||
for (UUID uuid : superVanish.getVanishStateMgr().getOnlineVanishedPlayers()) {
|
||||
|
||||
if (context.getMessage().contains(Bukkit.getPlayer(uuid).getName())) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// don't let hidden players receive it
|
||||
Iterator<Talkable> iterator = context.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
|
||||
Talkable recipient = iterator.next();
|
||||
Entity entity = recipient.getEntity();
|
||||
if (!(entity instanceof Player))
|
||||
continue;
|
||||
Player player = (Player) entity;
|
||||
if (superVanish.getVanishStateMgr().isVanished(player.getUniqueId())) {
|
||||
|
||||
iterator.remove();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// cancel contexts with only hidden recipients
|
||||
return context.hasRecipients();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package de.myzelyam.supervanish.hooks;
|
||||
|
||||
import de.myzelyam.api.vanish.PlayerHideEvent;
|
||||
import de.myzelyam.api.vanish.PlayerShowEvent;
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.dynmap.bukkit.DynmapPlugin;
|
||||
|
||||
public class DynmapHook extends PluginHook {
|
||||
|
||||
public DynmapHook(SuperVanish superVanish) {
|
||||
super(superVanish);
|
||||
}
|
||||
|
||||
private void adjustVisibility(Player p, boolean hide) {
|
||||
try {
|
||||
DynmapPlugin dynmap = (DynmapPlugin) Bukkit.getPluginManager()
|
||||
.getPlugin("dynmap");
|
||||
SuperVanish plugin = superVanish;
|
||||
boolean sendJoinLeave
|
||||
= superVanish.getSettings().getBoolean("HookOptions.DynmapSendJoinLeaveMessages")
|
||||
&& !plugin.getMessage("DynmapFakeJoin").equals("");
|
||||
if (hide) {
|
||||
dynmap.setPlayerVisiblity(p, false);
|
||||
if (sendJoinLeave)
|
||||
dynmap.sendBroadcastToWeb("",
|
||||
plugin.replacePlaceholders(plugin.getMessage("DynmapFakeQuit"), p));
|
||||
} else {
|
||||
dynmap.setPlayerVisiblity(p, true);
|
||||
if (sendJoinLeave)
|
||||
dynmap.sendBroadcastToWeb("",
|
||||
plugin.replacePlaceholders(plugin.getMessage("DynmapFakeJoin"), p));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
superVanish.logException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onVanish(PlayerHideEvent e) {
|
||||
Player p = e.getPlayer();
|
||||
adjustVisibility(p, true);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onReappear(PlayerShowEvent e) {
|
||||
Player p = e.getPlayer();
|
||||
adjustVisibility(p, false);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(PlayerJoinEvent e) {
|
||||
Player p = e.getPlayer();
|
||||
if (superVanish.getVanishStateMgr().isVanished(p.getUniqueId())) {
|
||||
adjustVisibility(p, true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onQuit(PlayerQuitEvent e) {
|
||||
Player p = e.getPlayer();
|
||||
if (superVanish.getVanishStateMgr().isVanished(p.getUniqueId())) {
|
||||
adjustVisibility(p, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,12 +10,10 @@ package de.myzelyam.supervanish.hooks;
|
||||
|
||||
import com.earth2me.essentials.Essentials;
|
||||
import com.earth2me.essentials.User;
|
||||
|
||||
import de.myzelyam.api.vanish.PlayerHideEvent;
|
||||
import de.myzelyam.api.vanish.PostPlayerShowEvent;
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
import de.myzelyam.supervanish.commands.CommandAction;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@@ -39,87 +37,167 @@ public class EssentialsHook extends PluginHook {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
try {
|
||||
if (!Bukkit.getPluginManager().isPluginEnabled("Essentials")) return;
|
||||
|
||||
if (!Bukkit.getPluginManager().isPluginEnabled("Essentials"))
|
||||
return;
|
||||
for (UUID uuid : superVanish.getVanishStateMgr().getOnlineVanishedPlayers()) {
|
||||
|
||||
Player p = Bukkit.getPlayer(uuid);
|
||||
User user = essentials.getUser(p);
|
||||
if (user == null) continue;
|
||||
if (user == null)
|
||||
continue;
|
||||
if (!user.isHidden())
|
||||
user.setHidden(true);
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
cancel();
|
||||
superVanish.logException(e);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private BukkitTask forcedInvisibilityTask;
|
||||
|
||||
public EssentialsHook(SuperVanish superVanish) {
|
||||
|
||||
super(superVanish);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPluginEnable(Plugin plugin) {
|
||||
|
||||
essentials = (Essentials) plugin;
|
||||
forcedInvisibilityTask = forcedInvisibilityRunnable.runTaskTimer(superVanish, 0, 100);
|
||||
forcedInvisibilityRunnable.run();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPluginDisable(Plugin plugin) {
|
||||
|
||||
essentials = null;
|
||||
forcedInvisibilityTask.cancel();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Essentials tracks its own vanish list in {@code getVanishedPlayersNew()} and
|
||||
* re-hides its members from every new joiner via the deprecated
|
||||
* {@code hidePlayer(Player)} API (see EssentialsPlayerListener#onPlayerJoin).
|
||||
* That deprecated call parks a {@code null} plugin ref in CraftPlayer's
|
||||
* invertedVisibilityEntities map, which Vanish-OG's plugin-scoped
|
||||
* {@code showPlayer(Plugin, Player)} cannot clear. So {@code /sv cleanup} must
|
||||
* drive Essentials' state back to "not vanished" on every online user — that's
|
||||
* the only call that removes the entry from Essentials' list *and* fires the
|
||||
* deprecated {@code showPlayer(Player)} that drops the null ref.
|
||||
*/
|
||||
@Override
|
||||
public void onCleanup() {
|
||||
|
||||
if (essentials == null)
|
||||
return;
|
||||
for (Player online : Bukkit.getOnlinePlayers()) {
|
||||
|
||||
try {
|
||||
|
||||
User user = essentials.getUser(online);
|
||||
if (user == null)
|
||||
continue;
|
||||
if (user.isVanished())
|
||||
user.setVanished(false);
|
||||
if (user.isHidden())
|
||||
user.setHidden(false);
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
superVanish.logException(e);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onJoin(PlayerJoinEvent e) {
|
||||
|
||||
User user = essentials.getUser(e.getPlayer());
|
||||
if (user == null) return;
|
||||
if (user == null)
|
||||
return;
|
||||
if (superVanish.getVanishStateMgr().isVanished(e.getPlayer().getUniqueId()) && !user.isHidden())
|
||||
user.setHidden(true);
|
||||
else user.setHidden(false);
|
||||
else
|
||||
user.setHidden(false);
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onVanish(PlayerHideEvent e) {
|
||||
|
||||
User user = essentials.getUser(e.getPlayer());
|
||||
if (user == null) return;
|
||||
if (user.isVanished()) user.setVanished(false);
|
||||
if (user == null)
|
||||
return;
|
||||
if (user.isVanished())
|
||||
user.setVanished(false);
|
||||
preVanishHiddenPlayers.remove(e.getPlayer().getUniqueId());
|
||||
user.setHidden(true);
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onReappear(PostPlayerShowEvent e) {
|
||||
|
||||
User user = essentials.getUser(e.getPlayer());
|
||||
if (user == null) return;
|
||||
if (user == null)
|
||||
return;
|
||||
user.setHidden(false);
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onCommand(final PlayerCommandPreprocessEvent e) {
|
||||
if (!CommandAction.VANISH_SELF.checkPermission(e.getPlayer(), superVanish)) return;
|
||||
if (superVanish.getVanishStateMgr().isVanished(e.getPlayer().getUniqueId())) return;
|
||||
|
||||
if (!CommandAction.VANISH_SELF.checkPermission(e.getPlayer(), superVanish))
|
||||
return;
|
||||
if (superVanish.getVanishStateMgr().isVanished(e.getPlayer().getUniqueId()))
|
||||
return;
|
||||
String command = e.getMessage().toLowerCase(Locale.ENGLISH).split(" ")[0].replace("/", "")
|
||||
.toLowerCase(Locale.ENGLISH);
|
||||
if (command.contains(":")) command = command.split(":")[1];
|
||||
if (command.equals("supervanish") || command.equals("sv")
|
||||
|| command.equals("v") || command.equals("vanish")) {
|
||||
if (command.split(":").length > 1)
|
||||
command = command.split(":")[1];
|
||||
if (command.equals("supervanish") || command.equals("sv") || command.equals("v") || command.equals("vanish")) {
|
||||
|
||||
final User user = essentials.getUser(e.getPlayer());
|
||||
if (user == null || !user.isAfk()) return;
|
||||
if (user == null || !user.isAfk())
|
||||
return;
|
||||
user.setHidden(true);
|
||||
preVanishHiddenPlayers.add(e.getPlayer().getUniqueId());
|
||||
superVanish.getServer().getScheduler().runTaskLater(superVanish, new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
if (preVanishHiddenPlayers.remove(e.getPlayer().getUniqueId())) {
|
||||
|
||||
user.setHidden(false);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}, 1);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,14 +10,22 @@ package de.myzelyam.supervanish.hooks;
|
||||
|
||||
public class InvalidPluginHookException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public InvalidPluginHookException() {
|
||||
|
||||
}
|
||||
|
||||
public InvalidPluginHookException(String message) {
|
||||
|
||||
super(message);
|
||||
|
||||
}
|
||||
|
||||
public InvalidPluginHookException(Throwable cause) {
|
||||
|
||||
super(cause);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package de.myzelyam.supervanish.hooks;
|
||||
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.UUID;
|
||||
|
||||
import be.maximvdw.placeholderapi.PlaceholderAPI;
|
||||
import be.maximvdw.placeholderapi.PlaceholderReplaceEvent;
|
||||
import be.maximvdw.placeholderapi.PlaceholderReplacer;
|
||||
|
||||
|
||||
public class MVdWPlaceholderAPIHook extends PluginHook {
|
||||
|
||||
public MVdWPlaceholderAPIHook(SuperVanish superVanish) {
|
||||
super(superVanish);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPluginEnable(Plugin plugin) {
|
||||
PlaceholderAPI.registerPlaceholder(superVanish, "supervanish_isvanished",
|
||||
new PlaceholderReplacer() {
|
||||
@Override
|
||||
public String onPlaceholderReplace(PlaceholderReplaceEvent e) {
|
||||
try {
|
||||
Player p = e.getPlayer();
|
||||
if (p == null) return "No";
|
||||
try {
|
||||
return superVanish.getVanishStateMgr().isVanished(p.getUniqueId()) ? "Yes"
|
||||
: "No";
|
||||
} catch (Exception er) {
|
||||
superVanish.logException(er);
|
||||
}
|
||||
return null;
|
||||
} catch (Throwable t) {
|
||||
if (!(t instanceof NoClassDefFoundError || t instanceof
|
||||
ConcurrentModificationException))
|
||||
superVanish.logException(t);
|
||||
return "No";
|
||||
}
|
||||
}
|
||||
});
|
||||
PlaceholderAPI.registerPlaceholder(superVanish, "supervanish_vanishedplayers",
|
||||
new PlaceholderReplacer() {
|
||||
@Override
|
||||
public String onPlaceholderReplace(PlaceholderReplaceEvent e) {
|
||||
try {
|
||||
Player p = e.getPlayer();
|
||||
Collection<UUID> onlineVanishedPlayers = superVanish.getVanishStateMgr()
|
||||
.getOnlineVanishedPlayers();
|
||||
String playerListMessage = "";
|
||||
for (UUID uuid : onlineVanishedPlayers) {
|
||||
Player onlineVanished = Bukkit.getPlayer(uuid);
|
||||
if (onlineVanished == null) continue;
|
||||
if (p != null && superVanish.getSettings().getBoolean(
|
||||
"IndicationFeatures.LayeredPermissions.HideInvisibleInCommands", false)
|
||||
&& !superVanish.hasPermissionToSee(p, onlineVanished)) {
|
||||
continue;
|
||||
}
|
||||
playerListMessage = playerListMessage + onlineVanished.getName() + ", ";
|
||||
}
|
||||
return playerListMessage.length() > 3
|
||||
? playerListMessage.substring(0, playerListMessage.length() - 2)
|
||||
: playerListMessage;
|
||||
} catch (Throwable t) {
|
||||
if (!(t instanceof NoClassDefFoundError || t instanceof
|
||||
ConcurrentModificationException))
|
||||
superVanish.logException(t);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
});
|
||||
PlaceholderAPI.registerPlaceholder(superVanish, "supervanish_playercount",
|
||||
new PlaceholderReplacer() {
|
||||
@Override
|
||||
public String onPlaceholderReplace(PlaceholderReplaceEvent e) {
|
||||
try {
|
||||
Player p = e.getPlayer();
|
||||
int playercount = Bukkit.getOnlinePlayers().size();
|
||||
for (UUID uuid : superVanish.getVanishStateMgr()
|
||||
.getOnlineVanishedPlayers()) {
|
||||
Player onlineVanished = Bukkit.getPlayer(uuid);
|
||||
if (onlineVanished == null) continue;
|
||||
if (p == null || !superVanish.canSee(p, onlineVanished))
|
||||
playercount--;
|
||||
}
|
||||
return playercount + "";
|
||||
} catch (Throwable t) {
|
||||
if (!(t instanceof NoClassDefFoundError || t instanceof
|
||||
ConcurrentModificationException))
|
||||
superVanish.logException(t);
|
||||
return Bukkit.getOnlinePlayers().size() + "";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package de.myzelyam.supervanish.hooks;
|
||||
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
|
||||
import io.github.miniplaceholders.api.Expansion;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.tag.Tag;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
|
||||
public class MiniPlaceholdersHook extends PluginHook {
|
||||
|
||||
private static final LegacyComponentSerializer LEGACY_SERIALIZER = LegacyComponentSerializer.legacyAmpersand();
|
||||
|
||||
private final String yes, no, prefix, suffix;
|
||||
private Expansion expansion;
|
||||
|
||||
public MiniPlaceholdersHook(SuperVanish superVanish) {
|
||||
|
||||
super(superVanish);
|
||||
yes = superVanish.getMessage("PlaceholderIsVanishedYes");
|
||||
no = superVanish.getMessage("PlaceholderIsVanishedNo");
|
||||
prefix = superVanish.getMessage("PlaceholderVanishPrefix");
|
||||
suffix = superVanish.getMessage("PlaceholderVanishSuffix");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPluginEnable(Plugin plugin) {
|
||||
|
||||
expansion = Expansion.builder("supervanish")
|
||||
.audiencePlaceholder("isvanished", (audience, queue, ctx) -> textTag(isVanishedText(audience)))
|
||||
.audiencePlaceholder("vanishprefix",
|
||||
(audience, queue, ctx) -> componentTag(isVanished(audience) ? prefix : ""))
|
||||
.audiencePlaceholder("vanishsuffix",
|
||||
(audience, queue, ctx) -> componentTag(isVanished(audience) ? suffix : ""))
|
||||
.audiencePlaceholder("vanishedplayers", (audience, queue, ctx) -> textTag(getVanishedPlayers(audience)))
|
||||
.audiencePlaceholder("playercount",
|
||||
(audience, queue, ctx) -> textTag(String.valueOf(getPlayerCount(audience))))
|
||||
.build();
|
||||
expansion.register();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPluginDisable(Plugin plugin) {
|
||||
|
||||
if (expansion != null && expansion.registered()) {
|
||||
|
||||
expansion.unregister();
|
||||
|
||||
}
|
||||
|
||||
expansion = null;
|
||||
|
||||
}
|
||||
|
||||
private String isVanishedText(Object audience) {
|
||||
|
||||
return isVanished(audience) ? yes : no;
|
||||
|
||||
}
|
||||
|
||||
private boolean isVanished(Object audience) {
|
||||
|
||||
if (!(audience instanceof Player))
|
||||
return false;
|
||||
return superVanish.getVanishStateMgr().isVanished(((Player) audience).getUniqueId());
|
||||
|
||||
}
|
||||
|
||||
private String getVanishedPlayers(Object audience) {
|
||||
|
||||
Player viewer = audience instanceof Player ? (Player) audience : null;
|
||||
Collection<UUID> onlineVanishedPlayers = superVanish.getVanishStateMgr().getOnlineVanishedPlayers();
|
||||
StringBuilder playerListMessage = new StringBuilder();
|
||||
for (UUID uuid : onlineVanishedPlayers) {
|
||||
|
||||
Player onlineVanished = Bukkit.getPlayer(uuid);
|
||||
if (onlineVanished == null)
|
||||
continue;
|
||||
if (viewer != null
|
||||
&& superVanish.getSettings()
|
||||
.getBoolean("IndicationFeatures.LayeredPermissions.HideInvisibleInCommands", false)
|
||||
&& !superVanish.hasPermissionToSee(viewer, onlineVanished))
|
||||
{
|
||||
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
if (playerListMessage.length() > 0) {
|
||||
|
||||
playerListMessage.append(", ");
|
||||
|
||||
}
|
||||
|
||||
playerListMessage.append(onlineVanished.getName());
|
||||
|
||||
}
|
||||
|
||||
return playerListMessage.toString();
|
||||
|
||||
}
|
||||
|
||||
private int getPlayerCount(Object audience) {
|
||||
|
||||
Player viewer = audience instanceof Player ? (Player) audience : null;
|
||||
int playerCount = Bukkit.getOnlinePlayers().size();
|
||||
for (UUID uuid : superVanish.getVanishStateMgr().getOnlineVanishedPlayers()) {
|
||||
|
||||
Player onlineVanished = Bukkit.getPlayer(uuid);
|
||||
if (onlineVanished == null)
|
||||
continue;
|
||||
if (viewer == null || !superVanish.canSee(viewer, onlineVanished)) {
|
||||
|
||||
playerCount--;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return playerCount;
|
||||
|
||||
}
|
||||
|
||||
private Tag textTag(String value) {
|
||||
|
||||
return Tag.selfClosingInserting(Component.text(value));
|
||||
|
||||
}
|
||||
|
||||
private Tag componentTag(String value) {
|
||||
|
||||
return Tag.selfClosingInserting(LEGACY_SERIALIZER.deserialize(value));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
package de.myzelyam.supervanish.hooks;
|
||||
|
||||
import de.myzelyam.api.vanish.PlayerShowEvent;
|
||||
import de.myzelyam.api.vanish.PostPlayerHideEvent;
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class OpenInvHook extends PluginHook {
|
||||
|
||||
private boolean errorLogged = false;
|
||||
|
||||
private final Set<UUID> alreadyHiddenBeforeVanishing = new HashSet<>();
|
||||
|
||||
public OpenInvHook(SuperVanish superVanish) {
|
||||
|
||||
super(superVanish);
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onVanish(PostPlayerHideEvent e) {
|
||||
|
||||
try {
|
||||
|
||||
Player p = e.getPlayer();
|
||||
|
||||
if (getSilentContainerStatus(p)) {
|
||||
|
||||
alreadyHiddenBeforeVanishing.add(p.getUniqueId());
|
||||
|
||||
} else {
|
||||
|
||||
if (!p.hasPermission("sv.silentchest"))
|
||||
return;
|
||||
setSilentContainerStatus(p, true);
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception | NoSuchMethodError | NoClassDefFoundError er) {
|
||||
|
||||
if (!errorLogged) {
|
||||
|
||||
superVanish.logException(er);
|
||||
errorLogged = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onReappear(PlayerShowEvent e) {
|
||||
|
||||
try {
|
||||
|
||||
Player p = e.getPlayer();
|
||||
|
||||
if (!alreadyHiddenBeforeVanishing.remove(p.getUniqueId())) {
|
||||
|
||||
setSilentContainerStatus(p, false);
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception | NoSuchMethodError | NoClassDefFoundError er) {
|
||||
|
||||
if (!errorLogged) {
|
||||
|
||||
superVanish.logException(er);
|
||||
errorLogged = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onJoin(PlayerJoinEvent e) {
|
||||
|
||||
try {
|
||||
|
||||
Player p = e.getPlayer();
|
||||
|
||||
if (superVanish.getVanishStateMgr().isVanished(p.getUniqueId())) {
|
||||
|
||||
if (getSilentContainerStatus(p)) {
|
||||
|
||||
alreadyHiddenBeforeVanishing.add(p.getUniqueId());
|
||||
|
||||
} else {
|
||||
|
||||
if (!p.hasPermission("sv.silentchest"))
|
||||
return;
|
||||
setSilentContainerStatus(p, true);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception | NoSuchMethodError | NoClassDefFoundError er) {
|
||||
|
||||
if (!errorLogged) {
|
||||
|
||||
superVanish.logException(er);
|
||||
errorLogged = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onQuit(PlayerQuitEvent e) {
|
||||
|
||||
try {
|
||||
|
||||
Player p = e.getPlayer();
|
||||
|
||||
if (superVanish.getVanishStateMgr().isVanished(p.getUniqueId())) {
|
||||
|
||||
if (!alreadyHiddenBeforeVanishing.remove(p.getUniqueId())) {
|
||||
|
||||
setSilentContainerStatus(p, false);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception | NoSuchMethodError | NoClassDefFoundError er) {
|
||||
|
||||
if (!errorLogged) {
|
||||
|
||||
superVanish.logException(er);
|
||||
errorLogged = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean openPlayerInventory(Player vanished, Player target) {
|
||||
|
||||
try {
|
||||
|
||||
// OpenInv 4.2.0+: openInventory's second arg is ISpecialInventory,
|
||||
// not org.bukkit.inventory.Inventory. The interface isn't on our
|
||||
// compile classpath, so resolve it reflectively.
|
||||
Class<?> iSpecialInventory = Class.forName("com.lishid.openinv.internal.ISpecialInventory");
|
||||
Method getSpecialInventoryMethod = plugin.getClass().getMethod("getSpecialInventory", Player.class,
|
||||
boolean.class);
|
||||
Object specialInventory = getSpecialInventoryMethod.invoke(plugin, target, true);
|
||||
Method openInventoryMethod = plugin.getClass().getMethod("openInventory", Player.class, iSpecialInventory);
|
||||
openInventoryMethod.invoke(plugin, vanished, specialInventory);
|
||||
|
||||
} catch (Exception | NoSuchMethodError | NoClassDefFoundError e) {
|
||||
|
||||
if (!errorLogged) {
|
||||
|
||||
superVanish.logException(e);
|
||||
errorLogged = true;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
// OpenInv 4.2.0+ signatures take OfflinePlayer, not Player. Player extends
|
||||
// OfflinePlayer so the argument is compatible; only the reflected lookup
|
||||
// signature needed updating.
|
||||
private boolean getSilentContainerStatus(Player player) throws ReflectiveOperationException {
|
||||
|
||||
Method method = plugin.getClass().getMethod("getSilentContainerStatus", OfflinePlayer.class);
|
||||
return (Boolean) method.invoke(plugin, player);
|
||||
|
||||
}
|
||||
|
||||
private void setSilentContainerStatus(Player player, boolean status) throws ReflectiveOperationException {
|
||||
|
||||
Method method = plugin.getClass().getMethod("setSilentContainerStatus", OfflinePlayer.class, boolean.class);
|
||||
method.invoke(plugin, player, status);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package de.myzelyam.supervanish.hooks;
|
||||
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import me.clip.placeholderapi.PlaceholderHook;
|
||||
|
||||
public class PlaceholderAPIHook extends PluginHook {
|
||||
|
||||
public PlaceholderAPIHook(SuperVanish superVanish) {
|
||||
super(superVanish);
|
||||
}
|
||||
|
||||
public static String translatePlaceholders(String msg, Player p) {
|
||||
return PlaceholderAPI.setPlaceholders(p, msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPluginEnable(Plugin plugin) {
|
||||
PlaceholderAPI.unregisterPlaceholderHook(superVanish);
|
||||
PlaceholderAPI.registerPlaceholderHook(superVanish, new PlaceholderHook() {
|
||||
@Override
|
||||
public String onPlaceholderRequest(Player p, String id) {
|
||||
try {
|
||||
if (id.equalsIgnoreCase("isvanished")
|
||||
|| id.equalsIgnoreCase("isinvisible")
|
||||
|| id.equalsIgnoreCase("vanished")
|
||||
|| id.equalsIgnoreCase("invisible"))
|
||||
return superVanish.getVanishStateMgr().isVanished(p.getUniqueId()) ? "Yes"
|
||||
: "No";
|
||||
if (id.equalsIgnoreCase("onlinevanishedplayers")
|
||||
|| id.equalsIgnoreCase("onlinevanished")
|
||||
|| id.equalsIgnoreCase("invisibleplayers")
|
||||
|| id.equalsIgnoreCase("vanishedplayers")
|
||||
|| id.equalsIgnoreCase("hiddenplayers")) {
|
||||
Collection<UUID> onlineVanishedPlayers = superVanish.getVanishStateMgr()
|
||||
.getOnlineVanishedPlayers();
|
||||
String playerListMessage = "";
|
||||
for (UUID uuid : onlineVanishedPlayers) {
|
||||
Player onlineVanished = Bukkit.getPlayer(uuid);
|
||||
if (onlineVanished == null) continue;
|
||||
if (superVanish.getSettings().getBoolean(
|
||||
"IndicationFeatures.LayeredPermissions.HideInvisibleInCommands", false)
|
||||
&& !superVanish.hasPermissionToSee(p, onlineVanished)) {
|
||||
continue;
|
||||
}
|
||||
playerListMessage = playerListMessage + onlineVanished.getName() + ", ";
|
||||
}
|
||||
return playerListMessage.length() > 3
|
||||
? playerListMessage.substring(0, playerListMessage.length() - 2)
|
||||
: playerListMessage;
|
||||
}
|
||||
if (id.equalsIgnoreCase("playercount")
|
||||
|| id.equalsIgnoreCase("onlineplayers")) {
|
||||
int playercount = Bukkit.getOnlinePlayers().size();
|
||||
for (UUID uuid : superVanish.getVanishStateMgr()
|
||||
.getOnlineVanishedPlayers()) {
|
||||
Player onlineVanished = Bukkit.getPlayer(uuid);
|
||||
if (onlineVanished == null) continue;
|
||||
if (!superVanish.canSee(p, onlineVanished)) playercount--;
|
||||
}
|
||||
return playercount + "";
|
||||
}
|
||||
} catch (Exception e) {
|
||||
superVanish.logException(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -14,8 +14,8 @@ import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* Represents a hook into a plugin to support its functionality or make it support SuperVanish's
|
||||
* functionality
|
||||
* Represents a hook into a plugin to support its functionality or make it
|
||||
* support SuperVanish's functionality
|
||||
*/
|
||||
public abstract class PluginHook implements Listener {
|
||||
|
||||
@@ -23,20 +23,39 @@ public abstract class PluginHook implements Listener {
|
||||
protected Plugin plugin;
|
||||
|
||||
public PluginHook(SuperVanish superVanish) {
|
||||
|
||||
this.superVanish = superVanish;
|
||||
|
||||
}
|
||||
|
||||
public void onPluginEnable(Plugin plugin) {
|
||||
|
||||
}
|
||||
|
||||
public void onPluginDisable(Plugin plugin) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by {@code /sv cleanup} so hooks can drop any hide state they are
|
||||
* responsible for. Default is a no-op — hooks that keep their own vanish
|
||||
* tracking (Essentials' {@code getVanishedPlayersNew} + deprecated
|
||||
* {@code hidePlayer(Player)} calls) override this to reset it.
|
||||
*/
|
||||
public void onCleanup() {
|
||||
|
||||
}
|
||||
|
||||
public Plugin getPlugin() {
|
||||
|
||||
return plugin;
|
||||
|
||||
}
|
||||
|
||||
void setPlugin(Plugin plugin) {
|
||||
|
||||
this.plugin = plugin;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,89 +25,176 @@ import java.util.logging.Level;
|
||||
|
||||
public class PluginHookMgr implements Listener {
|
||||
|
||||
private static final Map<String, Class<? extends PluginHook>> REGISTERED_HOOKS
|
||||
= new HashMap<String, Class<? extends PluginHook>>() {{
|
||||
put("Essentials", EssentialsHook.class);
|
||||
put("Citizens", CitizensHook.class);
|
||||
put("PlaceholderAPI", PlaceholderAPIHook.class);
|
||||
put("dynmap", DynmapHook.class);
|
||||
put("SuperTrails", SuperTrailsHook.class);
|
||||
put("TrailGUI", TrailGUIHook.class);
|
||||
put("MVdWPlaceholderAPI", MVdWPlaceholderAPIHook.class);
|
||||
}};
|
||||
private static final Map<String, Class<? extends PluginHook>> REGISTERED_HOOKS = new HashMap<String, Class<? extends PluginHook>>() {
|
||||
|
||||
{
|
||||
|
||||
put("Essentials", EssentialsHook.class);
|
||||
put("Citizens", CitizensHook.class);
|
||||
put("Utilities-OG", MiniPlaceholdersHook.class);
|
||||
put("TrailGUI", TrailGUIHook.class);
|
||||
put("OpenInv", OpenInvHook.class);
|
||||
put("TAB-OG", TabOGHook.class);
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
private final SuperVanish plugin;
|
||||
private Set<PluginHook> activeHooks = new HashSet<>();
|
||||
|
||||
public PluginHookMgr(SuperVanish plugin) {
|
||||
|
||||
this.plugin = plugin;
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
for (Plugin alreadyEnabledPlugin : Bukkit.getPluginManager().getPlugins())
|
||||
if (alreadyEnabledPlugin.isEnabled())
|
||||
onPluginEnable(new PluginEnableEvent(alreadyEnabledPlugin));
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPluginEnable(PluginEnableEvent e) {
|
||||
|
||||
Plugin plugin = e.getPlugin();
|
||||
if (REGISTERED_HOOKS.get(plugin.getName()) == null) return;
|
||||
if (isHookDisabled(plugin.getName())) return;
|
||||
if (REGISTERED_HOOKS.get(plugin.getName()) == null)
|
||||
return;
|
||||
if (isHookDisabled(plugin.getName()))
|
||||
return;
|
||||
PluginHook hook = null;
|
||||
try {
|
||||
hook = REGISTERED_HOOKS.get(plugin.getName()).getConstructor(SuperVanish.class).
|
||||
newInstance(PluginHookMgr.this.plugin);
|
||||
|
||||
hook = REGISTERED_HOOKS.get(plugin.getName()).getConstructor(SuperVanish.class)
|
||||
.newInstance(PluginHookMgr.this.plugin);
|
||||
hook.setPlugin(plugin);
|
||||
hook.onPluginEnable(plugin);
|
||||
Bukkit.getPluginManager().registerEvents(hook, plugin);
|
||||
activeHooks.add(hook);
|
||||
PluginHookMgr.this.plugin.log(
|
||||
Level.INFO, "Hooked into " + plugin.getName());
|
||||
PluginHookMgr.this.plugin.log(Level.INFO, "Hooked into " + plugin.getName());
|
||||
|
||||
} catch (NoClassDefFoundError er) {
|
||||
Bukkit.getLogger().warning("NoClassDefFoundError for SV-Hook(v"
|
||||
+ this.plugin.getDescription().getVersion() + ") "
|
||||
+ (hook != null ? hook.getClass().getSimpleName() : "?") + " of plugin "
|
||||
+ plugin.getName() + " v" + plugin.getDescription().getVersion()
|
||||
+ ", please report this if you are using the latest version of that" +
|
||||
" plugin!");
|
||||
|
||||
Bukkit.getLogger()
|
||||
.warning("NoClassDefFoundError for SV-Hook(v" + this.plugin.getPluginMeta().getVersion() + ") "
|
||||
+ (hook != null ? hook.getClass().getSimpleName() : "?") + " of plugin " + plugin.getName()
|
||||
+ " v" + plugin.getPluginMeta().getVersion()
|
||||
+ ", please report this if you are using the latest version of that" + " plugin!");
|
||||
|
||||
} catch (Exception er) {
|
||||
if (er.getMessage() != null
|
||||
&& er.getMessage().contains("Unable to find handler list for event")) {
|
||||
this.plugin.log(Level.WARNING, "" + er.getMessage()
|
||||
+ "; This is not an issue with SuperVanish");
|
||||
|
||||
if (er.getMessage() != null && er.getMessage().contains("Unable to find handler list for event")) {
|
||||
|
||||
this.plugin.log(Level.WARNING, "" + er.getMessage() + "; This is not an issue with Vanish-OG");
|
||||
return;
|
||||
} else if (er.getCause() != null && er.getCause().getMessage() != null && er.getCause()
|
||||
.getMessage().contains("Unable to find handler list for event ")) {
|
||||
this.plugin.log(Level.WARNING, "" + er.getCause()
|
||||
.getMessage() + "; This is not an issue with SuperVanish");
|
||||
|
||||
} else if (er.getCause() != null && er.getCause().getMessage() != null
|
||||
&& er.getCause().getMessage().contains("Unable to find handler list for event "))
|
||||
{
|
||||
|
||||
this.plugin.log(Level.WARNING,
|
||||
"" + er.getCause().getMessage() + "; This is not an issue with Vanish-OG");
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
this.plugin.logException(new InvalidPluginHookException(er));
|
||||
this.plugin.log(Level.WARNING, "Affected by this error is only the "
|
||||
+ plugin.getName() + "-Hook, all other hooks and features aren't affected.");
|
||||
this.plugin.log(Level.WARNING, "Affected by this error is only the " + plugin.getName()
|
||||
+ "-Hook, all other hooks and features aren't affected.");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean isHookDisabled(String pluginName) {
|
||||
|
||||
if (pluginName.equalsIgnoreCase("dynmap"))
|
||||
return !plugin.getSettings().getBoolean("HookOptions.EnableDynmapHook");
|
||||
if (pluginName.equalsIgnoreCase("Utilities-OG"))
|
||||
return !plugin.getSettings().getBoolean("HookOptions.EnableUtilitiesOGHook", true);
|
||||
if (pluginName.equalsIgnoreCase("TAB-OG"))
|
||||
return !plugin.getSettings().getBoolean("HookOptions.EnableTabOGHook", true);
|
||||
return !plugin.getSettings().getBoolean("HookOptions.Enable" + pluginName + "Hook", true);
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPluginDisable(PluginDisableEvent e) {
|
||||
|
||||
Plugin plugin = e.getPlugin();
|
||||
PluginHook hook = getActiveHook(plugin);
|
||||
if (hook == null) return;
|
||||
if (hook == null)
|
||||
return;
|
||||
try {
|
||||
|
||||
hook.onPluginDisable(plugin);
|
||||
|
||||
} catch (Exception e1) {
|
||||
|
||||
this.plugin.logException(new InvalidPluginHookException(e1));
|
||||
|
||||
}
|
||||
|
||||
hook.setPlugin(null);
|
||||
activeHooks.remove(hook);
|
||||
|
||||
}
|
||||
|
||||
private PluginHook getActiveHook(Plugin plugin) {
|
||||
for (PluginHook hook : activeHooks) if (hook.getPlugin() == plugin) return hook;
|
||||
|
||||
for (PluginHook hook : activeHooks)
|
||||
if (hook.getPlugin() == plugin)
|
||||
return hook;
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
public boolean isHookActive(Class<? extends PluginHook> hookClass) {
|
||||
|
||||
for (PluginHook hook : activeHooks) {
|
||||
|
||||
if (hook.getClass().equals(hookClass)) {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
// Must run before the rest of the plugin tears down so TAB-OG's static
|
||||
// HANDLERS list doesn't keep a reference to a disabled SuperVanish.
|
||||
public void onSuperVanishDisable() {
|
||||
|
||||
for (PluginHook hook : activeHooks) {
|
||||
|
||||
if (hook instanceof TabOGHook) {
|
||||
|
||||
((TabOGHook) hook).onSuperVanishDisable();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void onCleanup() {
|
||||
|
||||
for (PluginHook hook : activeHooks) {
|
||||
|
||||
try {
|
||||
|
||||
hook.onCleanup();
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
plugin.logException(e);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package de.myzelyam.supervanish.hooks;
|
||||
|
||||
import de.myzelyam.api.vanish.PlayerHideEvent;
|
||||
import de.myzelyam.api.vanish.PlayerShowEvent;
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import me.kvq.plugin.trails.API.SuperTrailsAPI;
|
||||
|
||||
public class SuperTrailsHook extends PluginHook {
|
||||
|
||||
public SuperTrailsHook(SuperVanish superVanish) {
|
||||
super(superVanish);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPluginEnable(Plugin plugin) {
|
||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||
if (superVanish.getVanishStateMgr().isVanished(p.getUniqueId())) {
|
||||
SuperTrailsAPI.HideTrailFor(p, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onVanish(PlayerHideEvent e) {
|
||||
SuperTrailsAPI.HideTrailFor(e.getPlayer(), true);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onReappear(PlayerShowEvent e) {
|
||||
SuperTrailsAPI.HideTrailFor(e.getPlayer(), false);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onJoin(PlayerJoinEvent e) {
|
||||
if (!superVanish.getVanishStateMgr().isVanished(e.getPlayer().getUniqueId())) return;
|
||||
SuperTrailsAPI.HideTrailFor(e.getPlayer(), true);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onQuit(PlayerQuitEvent e) {
|
||||
if (!superVanish.getVanishStateMgr().isVanished(e.getPlayer().getUniqueId())) return;
|
||||
SuperTrailsAPI.HideTrailFor(e.getPlayer(), false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package de.myzelyam.supervanish.hooks;
|
||||
|
||||
import de.myzelyam.api.vanish.PostPlayerHideEvent;
|
||||
import de.myzelyam.api.vanish.PostPlayerShowEvent;
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
import de.myzelyam.supervanish.visibility.VanishStateMgr;
|
||||
|
||||
import me.neznamy.tab.api.TabPlayer;
|
||||
import me.neznamy.tab.api.integration.VanishIntegration;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.UUID;
|
||||
|
||||
public class TabOGHook extends PluginHook {
|
||||
|
||||
private VanishOGIntegration integration;
|
||||
|
||||
public TabOGHook(SuperVanish superVanish) {
|
||||
|
||||
super(superVanish);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPluginEnable(Plugin plugin) {
|
||||
|
||||
// Do not double-register if an earlier lifecycle already registered one.
|
||||
unregisterIfPresent();
|
||||
integration = new VanishOGIntegration(superVanish);
|
||||
integration.register();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPluginDisable(Plugin plugin) {
|
||||
|
||||
unregisterIfPresent();
|
||||
|
||||
}
|
||||
|
||||
// Called from SuperVanish.onDisable() so the integration is removed from
|
||||
// TAB-OG's static HANDLERS list before the plugin's state is torn down.
|
||||
// Without this, TAB-OG keeps a stale handler whose plugin reference no
|
||||
// longer has valid state during subsequent logins.
|
||||
public void onSuperVanishDisable() {
|
||||
|
||||
unregisterIfPresent();
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onVanish(PostPlayerHideEvent event) {
|
||||
|
||||
notifyTabFeatures(event.getPlayer().getUniqueId());
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onReappear(PostPlayerShowEvent event) {
|
||||
|
||||
notifyTabFeatures(event.getPlayer().getUniqueId());
|
||||
|
||||
}
|
||||
|
||||
private void unregisterIfPresent() {
|
||||
|
||||
if (integration != null) {
|
||||
|
||||
try {
|
||||
|
||||
integration.unregister();
|
||||
|
||||
} catch (Throwable ignored) {
|
||||
|
||||
// TAB-OG may already be unloaded; removing a missing handler is harmless.
|
||||
}
|
||||
|
||||
integration = null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void notifyTabFeatures(UUID playerUuid) {
|
||||
|
||||
// Fire once immediately for metadata-based TAB-OG features and once after
|
||||
// BackendTabPlayer's vanish cache window so cache-backed features refresh too.
|
||||
Bukkit.getScheduler().runTask(superVanish, () -> notifyTabFeaturesNow(playerUuid));
|
||||
Bukkit.getScheduler().runTaskLater(superVanish, () -> notifyTabFeaturesNow(playerUuid), 20L);
|
||||
|
||||
}
|
||||
|
||||
private void notifyTabFeaturesNow(UUID playerUuid) {
|
||||
|
||||
if (integration == null) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
Class<?> tabClass = Class.forName("me.neznamy.tab.shared.TAB");
|
||||
Object tab = tabClass.getMethod("getInstance").invoke(null);
|
||||
if (tab == null) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
Object tabPlayer = tabClass.getMethod("getPlayer", UUID.class).invoke(tab, playerUuid);
|
||||
if (tabPlayer == null) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
Object featureManager = tabClass.getMethod("getFeatureManager").invoke(tab);
|
||||
Class<?> tabPlayerClass = Class.forName("me.neznamy.tab.shared.platform.TabPlayer");
|
||||
Method vanishChangeMethod = featureManager.getClass().getMethod("onVanishStatusChange", tabPlayerClass);
|
||||
vanishChangeMethod.invoke(featureManager, tabPlayer);
|
||||
|
||||
} catch (ReflectiveOperationException ignored) {
|
||||
|
||||
// TAB-OG implementation internals are optional and may differ across versions.
|
||||
|
||||
} catch (Throwable t) {
|
||||
|
||||
superVanish.logException(t);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class VanishOGIntegration extends VanishIntegration {
|
||||
|
||||
private final SuperVanish plugin;
|
||||
|
||||
private VanishOGIntegration(SuperVanish plugin) {
|
||||
|
||||
super("Vanish-OG");
|
||||
this.plugin = plugin;
|
||||
|
||||
}
|
||||
|
||||
// TAB-OG invokes this on its async CPU-manager thread during join
|
||||
// processing, so every field access must tolerate partial-enable and
|
||||
// partial-disable states. Any exception thrown here propagates through
|
||||
// TAB-OG's feature pipeline and breaks player login packet flow.
|
||||
@Override
|
||||
public boolean canSee(@NotNull TabPlayer viewer, @NotNull TabPlayer target) {
|
||||
|
||||
try {
|
||||
|
||||
final VanishStateMgr stateMgr = plugin.getVanishStateMgr();
|
||||
if (stateMgr == null)
|
||||
return true;
|
||||
if (!stateMgr.isVanished(target.getUniqueId()))
|
||||
return true;
|
||||
final Player bukkitViewer = Bukkit.getPlayer(viewer.getUniqueId());
|
||||
if (bukkitViewer == null)
|
||||
return true;
|
||||
// Direct permission check only: plugin.hasPermissionToSee() reaches
|
||||
// LayeredPermissionChecker, which iterates the non-thread-safe
|
||||
// vanishPlayers HashSet on SuperVanish. That's safe on the Bukkit
|
||||
// main thread but not here, so we stick to Player.hasPermission.
|
||||
return bukkitViewer.hasPermission("sv.see");
|
||||
|
||||
} catch (Throwable t) {
|
||||
|
||||
plugin.logException(t);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVanished(@NotNull TabPlayer player) {
|
||||
|
||||
try {
|
||||
|
||||
final VanishStateMgr stateMgr = plugin.getVanishStateMgr();
|
||||
if (stateMgr == null)
|
||||
return false;
|
||||
return stateMgr.isVanished(player.getUniqueId());
|
||||
|
||||
} catch (Throwable t) {
|
||||
|
||||
plugin.logException(t);
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -23,28 +23,37 @@ import ca.jamiesinn.trailgui.TrailGUI;
|
||||
public class TrailGUIHook extends PluginHook {
|
||||
|
||||
public TrailGUIHook(SuperVanish superVanish) {
|
||||
|
||||
super(superVanish);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPluginEnable(Plugin plugin) {
|
||||
if (plugin == null || !(plugin instanceof TrailGUI)) {
|
||||
superVanish.log(Level.WARNING,
|
||||
"Failed to hook into TrailGUI. (PluginNotFound)");
|
||||
|
||||
if (!(plugin instanceof TrailGUI)) {
|
||||
|
||||
superVanish.log(Level.WARNING, "Failed to hook into TrailGUI. (PluginNotFound)");
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
PlayerMoveEvent.getHandlerList().unregister(plugin);
|
||||
final Listeners trailGUIListeners = new Listeners((TrailGUI) plugin);
|
||||
plugin.getServer().getPluginManager().registerEvents(new Listener() {
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerMove(PlayerMoveEvent event) {
|
||||
if (superVanish.getVanishStateMgr()
|
||||
.getOnlineVanishedPlayers().contains(
|
||||
event.getPlayer().getUniqueId()))
|
||||
|
||||
if (superVanish.getVanishStateMgr().getOnlineVanishedPlayers()
|
||||
.contains(event.getPlayer().getUniqueId()))
|
||||
return;
|
||||
trailGUIListeners.onPlayerMove(event);
|
||||
|
||||
}
|
||||
|
||||
}, plugin);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+83
-26
@@ -6,121 +6,178 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package de.myzelyam.supervanish.events;
|
||||
package de.myzelyam.supervanish.listeners;
|
||||
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
import de.myzelyam.supervanish.VanishPlayer;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.entity.EntityTargetEvent;
|
||||
import org.bukkit.event.entity.FoodLevelChangeEvent;
|
||||
import org.bukkit.event.entity.*;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerPickupItemEvent;
|
||||
|
||||
public class GeneralEventHandler implements Listener {
|
||||
public class GeneralListener implements Listener {
|
||||
|
||||
private final SuperVanish plugin;
|
||||
|
||||
private final FileConfiguration config;
|
||||
|
||||
public GeneralEventHandler(SuperVanish plugin) {
|
||||
public GeneralListener(SuperVanish plugin) {
|
||||
|
||||
this.plugin = plugin;
|
||||
config = plugin.getSettings();
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onDamage(EntityDamageByEntityEvent e) {
|
||||
|
||||
try {
|
||||
if (!(e.getDamager() instanceof Player)) return;
|
||||
if (e.getEntity() == null) return;
|
||||
|
||||
if (!(e.getDamager() instanceof Player))
|
||||
return;
|
||||
if (e.getEntity() == null)
|
||||
return;
|
||||
Player p = (Player) e.getDamager();
|
||||
if (plugin.getVanishStateMgr().isVanished(p.getUniqueId())) {
|
||||
|
||||
if (config.getBoolean("RestrictiveOptions.PreventHittingEntities")
|
||||
&& !p.hasPermission("sv.damageentities") && !p.hasPermission("sv.damage")) {
|
||||
&& !p.hasPermission("sv.damageentities") && !p.hasPermission("sv.damage"))
|
||||
{
|
||||
|
||||
plugin.sendMessage(p, "EntityHitDenied", p);
|
||||
e.setCancelled(true);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception er) {
|
||||
|
||||
plugin.logException(er);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onFoodLevelChange(FoodLevelChangeEvent e) {
|
||||
|
||||
try {
|
||||
|
||||
if (e.getEntity() instanceof Player && config.getBoolean("InvisibilityFeatures.DisableHunger")) {
|
||||
|
||||
Player p = (Player) e.getEntity();
|
||||
if (plugin.getVanishStateMgr().isVanished(p.getUniqueId())
|
||||
&& e.getFoodLevel() <= p.getFoodLevel())
|
||||
if (plugin.getVanishStateMgr().isVanished(p.getUniqueId()) && e.getFoodLevel() <= p.getFoodLevel())
|
||||
e.setCancelled(true);
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception er) {
|
||||
|
||||
plugin.logException(er);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onDamage(EntityDamageEvent e) {
|
||||
|
||||
try {
|
||||
if (!(e.getEntity() instanceof Player)) return;
|
||||
|
||||
if (!(e.getEntity() instanceof Player))
|
||||
return;
|
||||
Player p = (Player) e.getEntity();
|
||||
if (!config.getBoolean("InvisibilityFeatures.DisableDamage")) return;
|
||||
if (!config.getBoolean("InvisibilityFeatures.DisableDamage"))
|
||||
return;
|
||||
if (plugin.getVanishStateMgr().isVanished(p.getUniqueId())) {
|
||||
|
||||
e.setCancelled(true);
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception er) {
|
||||
|
||||
plugin.logException(er);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onTarget(EntityTargetEvent e) {
|
||||
|
||||
try {
|
||||
if (!(e.getTarget() instanceof Player)) return;
|
||||
if (!config.getBoolean("InvisibilityFeatures.DisableMobTarget")) return;
|
||||
|
||||
if (!(e.getTarget() instanceof Player))
|
||||
return;
|
||||
if (!config.getBoolean("InvisibilityFeatures.DisableMobTarget"))
|
||||
return;
|
||||
Player p = (Player) e.getTarget();
|
||||
if (plugin.getVanishStateMgr().isVanished(p.getUniqueId())) {
|
||||
|
||||
e.setCancelled(true);
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception er) {
|
||||
|
||||
plugin.logException(er);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onItemPickUp(PlayerPickupItemEvent e) {
|
||||
public void onItemPickUp(EntityPickupItemEvent e) {
|
||||
|
||||
try {
|
||||
VanishPlayer vanishPlayer = plugin.getVanishPlayer(e.getPlayer());
|
||||
if (vanishPlayer == null || !vanishPlayer.isOnlineVanished()) return;
|
||||
|
||||
if (!(e.getEntity() instanceof Player player))
|
||||
return;
|
||||
VanishPlayer vanishPlayer = plugin.getVanishPlayer(player);
|
||||
if (vanishPlayer == null || !vanishPlayer.isOnlineVanished())
|
||||
return;
|
||||
if (!vanishPlayer.hasItemPickUpsEnabled())
|
||||
e.setCancelled(true);
|
||||
if (plugin.getSettings().getBoolean("RestrictiveOptions.PreventModifyingOwnInventory")
|
||||
&& !vanishPlayer.getPlayer().hasPermission("sv.modifyowninv")) {
|
||||
&& !player.hasPermission("sv.modifyowninv"))
|
||||
{
|
||||
|
||||
e.setCancelled(true);
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception er) {
|
||||
|
||||
plugin.logException(er);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerCropTrample(PlayerInteractEvent e) {
|
||||
|
||||
try {
|
||||
if (!plugin.getVanishStateMgr().isVanished(e.getPlayer().getUniqueId())) return;
|
||||
if (e.getAction() != Action.PHYSICAL) return;
|
||||
if (e.getClickedBlock() != null && e.getClickedBlock().getType() == Material.SOIL)
|
||||
|
||||
if (!plugin.getVanishStateMgr().isVanished(e.getPlayer().getUniqueId()))
|
||||
return;
|
||||
if (e.getAction() != Action.PHYSICAL)
|
||||
return;
|
||||
if (e.getClickedBlock() != null && e.getClickedBlock().getType().toString().matches("SOIL|FARMLAND"))
|
||||
e.setCancelled(true);
|
||||
|
||||
} catch (Exception er) {
|
||||
|
||||
plugin.logException(er);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+56
-24
@@ -6,10 +6,9 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package de.myzelyam.supervanish.events;
|
||||
package de.myzelyam.supervanish.listeners;
|
||||
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
import de.myzelyam.supervanish.features.Broadcast;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event;
|
||||
@@ -19,73 +18,106 @@ import org.bukkit.metadata.FixedMetadataValue;
|
||||
import org.bukkit.plugin.EventExecutor;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
public class JoinEvent implements EventExecutor, Listener {
|
||||
public class JoinListener implements EventExecutor, Listener {
|
||||
|
||||
private final SuperVanish plugin;
|
||||
|
||||
public JoinEvent(SuperVanish plugin) {
|
||||
public JoinListener(SuperVanish plugin) {
|
||||
|
||||
this.plugin = plugin;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Listener l, Event event) {
|
||||
|
||||
try {
|
||||
|
||||
if (event instanceof PlayerJoinEvent) {
|
||||
|
||||
PlayerJoinEvent e = (PlayerJoinEvent) event;
|
||||
final Player p = e.getPlayer();
|
||||
// vanished:
|
||||
if (plugin.getVanishStateMgr().isVanished(p.getUniqueId())) {
|
||||
// Join message
|
||||
if (plugin.getSettings().getBoolean("MessageOptions.HideRealJoinQuitMessages")) {
|
||||
e.setJoinMessage(null);
|
||||
Broadcast.announceSilentJoin(p, plugin);
|
||||
}
|
||||
// collision
|
||||
try {
|
||||
//noinspection deprecation
|
||||
p.getPlayer().spigot().setCollidesWithEntities(false);
|
||||
} catch (NoClassDefFoundError | NoSuchMethodError ignored) {
|
||||
}
|
||||
|
||||
// reminding message
|
||||
if (plugin.getSettings().getBoolean("MessageOptions.RemindVanishedOnJoin")) {
|
||||
|
||||
plugin.sendMessage(p, "RemindingMessage", p);
|
||||
|
||||
}
|
||||
|
||||
// re-add action bar
|
||||
if (plugin.getActionBarMgr() != null && plugin.getSettings().getBoolean(
|
||||
"MessageOptions.DisplayActionBar")) {
|
||||
if (plugin.getActionBarMgr() != null
|
||||
&& plugin.getSettings().getBoolean("MessageOptions.DisplayActionBar"))
|
||||
{
|
||||
|
||||
plugin.getActionBarMgr().addActionBar(p);
|
||||
|
||||
}
|
||||
|
||||
// sleep state
|
||||
p.setSleepingIgnored(true);
|
||||
// adjust fly
|
||||
if (plugin.getSettings().getBoolean("InvisibilityFeatures.Fly.Enable")) {
|
||||
|
||||
p.setAllowFlight(true);
|
||||
|
||||
}
|
||||
|
||||
// metadata
|
||||
p.setMetadata("vanished", new FixedMetadataValue(plugin, true));
|
||||
|
||||
} else {
|
||||
|
||||
// not vanished:
|
||||
// metadata
|
||||
p.removeMetadata("vanished", plugin);
|
||||
|
||||
}
|
||||
|
||||
new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
plugin.reconcileVisibility(p);
|
||||
|
||||
}
|
||||
|
||||
}.runTaskLater(plugin, 1L);
|
||||
|
||||
// not necessarily vanished:
|
||||
// recreate files msg
|
||||
if ((p.hasPermission("sv.recreatecfg") || p.hasPermission("sv.recreatefiles"))
|
||||
&& (plugin.getConfigMgr().isSettingsUpdateRequired()
|
||||
|| plugin.getConfigMgr().isMessagesUpdateRequired())) {
|
||||
String currentVersion = plugin.getDescription().getVersion();
|
||||
boolean isDismissed =
|
||||
plugin.getPlayerData().getBoolean("PlayerData." + p.getUniqueId() + ".dismissed."
|
||||
+ currentVersion.replace(".", "_"), false);
|
||||
&& plugin.getConfigMgr().isMessagesUpdateRequired())
|
||||
{
|
||||
|
||||
String currentVersion = plugin.getPluginMeta().getVersion();
|
||||
boolean isDismissed = plugin.getVanishStateMgr().isDismissed(p.getUniqueId().toString(),
|
||||
currentVersion);
|
||||
if (!isDismissed)
|
||||
new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
plugin.sendMessage(p, "RecreationRequiredMsg", p);
|
||||
|
||||
}
|
||||
|
||||
}.runTaskLater(plugin, 1);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception er) {
|
||||
|
||||
plugin.logException(er);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+38
-28
@@ -6,60 +6,70 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package de.myzelyam.supervanish.events;
|
||||
package de.myzelyam.supervanish.listeners;
|
||||
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
import de.myzelyam.supervanish.commands.CommandAction;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerLoginEvent;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
|
||||
|
||||
public class LoginEvent implements Listener {
|
||||
public class LoginListener implements Listener {
|
||||
|
||||
private final SuperVanish plugin;
|
||||
|
||||
public LoginEvent(SuperVanish plugin) {
|
||||
public LoginListener(SuperVanish plugin) {
|
||||
|
||||
this.plugin = plugin;
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onLogin(PlayerLoginEvent e) {
|
||||
|
||||
try {
|
||||
if (e.getResult() != PlayerLoginEvent.Result.ALLOWED) return;
|
||||
|
||||
if (e.getResult() != PlayerLoginEvent.Result.ALLOWED)
|
||||
return;
|
||||
final Player p = e.getPlayer();
|
||||
boolean vanished = plugin.getVanishStateMgr().isVanished(p.getUniqueId());
|
||||
boolean itemPickUps = plugin.getPlayerData().getBoolean(
|
||||
"PlayerData." + p.getUniqueId() + ".itemPickUps",
|
||||
boolean persistedVanished = plugin.getVanishStateMgr().isVanished(p.getUniqueId());
|
||||
boolean itemPickUps = plugin.getVanishStateMgr().getItemPickUps(p.getUniqueId(),
|
||||
plugin.getSettings().getBoolean("InvisibilityFeatures.DefaultPickUpItemsOption"));
|
||||
plugin.createVanishPlayer(p, itemPickUps);
|
||||
if (vanished && plugin.getSettings().getBoolean("VanishStateFeatures.CheckPermissionOnLogin", false)
|
||||
&& !CommandAction.VANISH_SELF.checkPermission(p, plugin)) {
|
||||
vanished = false;
|
||||
}
|
||||
if (!vanished && p.hasPermission("sv.joinvanished")
|
||||
&& plugin.getSettings().getBoolean("VanishStateFeatures.AutoVanishOnJoin", false)) {
|
||||
plugin.getVanishStateMgr().setVanishedState(p.getUniqueId(), p.getName(), true, null);
|
||||
vanished = true;
|
||||
}
|
||||
if (vanished) {
|
||||
// hide self
|
||||
for (Player onlinePlayer : Bukkit.getOnlinePlayers())
|
||||
if (!plugin.hasPermissionToSee(onlinePlayer, p))
|
||||
plugin.getVisibilityChanger().getHider().setHidden(p, onlinePlayer, true);
|
||||
if (persistedVanished
|
||||
&& plugin.getSettings().getBoolean("VanishStateFeatures.CheckPermissionOnLogin", false)
|
||||
&& !CommandAction.VANISH_SELF.checkPermission(p, plugin))
|
||||
{
|
||||
|
||||
// Persist the auto-unvanish so reconcileVisibility() and TAB-OG's
|
||||
// canSee() do not keep hiding the player based on stale saved state.
|
||||
plugin.getVanishStateMgr().setVanishedState(p.getUniqueId(), p.getName(), false, null);
|
||||
persistedVanished = false;
|
||||
|
||||
}
|
||||
|
||||
// hide others
|
||||
for (Player onlinePlayer : Bukkit.getOnlinePlayers())
|
||||
if (plugin.getVanishStateMgr().isVanished(onlinePlayer.getUniqueId())
|
||||
&& !plugin.hasPermissionToSee(p, onlinePlayer))
|
||||
plugin.getVisibilityChanger().getHider().setHidden(onlinePlayer, p, true);
|
||||
if (persistedVanished) {
|
||||
|
||||
p.setMetadata("vanished", new FixedMetadataValue(plugin, true));
|
||||
|
||||
} else {
|
||||
|
||||
p.removeMetadata("vanished", plugin);
|
||||
|
||||
}
|
||||
|
||||
plugin.reconcileVisibility(p);
|
||||
|
||||
} catch (Exception er) {
|
||||
|
||||
plugin.logException(er);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+46
-13
@@ -6,11 +6,10 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package de.myzelyam.supervanish.events;
|
||||
package de.myzelyam.supervanish.listeners;
|
||||
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
@@ -20,67 +19,101 @@ import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlayerBlockModifyEventHandler implements Listener {
|
||||
public class PlayerBlockModifyListener implements Listener {
|
||||
|
||||
private final SuperVanish plugin;
|
||||
|
||||
public PlayerBlockModifyEventHandler(SuperVanish plugin) {
|
||||
public PlayerBlockModifyListener(SuperVanish plugin) {
|
||||
|
||||
this.plugin = plugin;
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onInteract(PlayerInteractEvent e) {
|
||||
|
||||
try {
|
||||
|
||||
if (!plugin.getVanishStateMgr().isVanished(e.getPlayer().getUniqueId()))
|
||||
return;
|
||||
if (e.getAction().equals(Action.PHYSICAL)) {
|
||||
if (e.getAction().equals(Action.PHYSICAL) && e.getClickedBlock() != null) {
|
||||
|
||||
if (!plugin.getSettings().getBoolean("InvisibilityFeatures.DisablePressurePlates"))
|
||||
return;
|
||||
Material blockType = e.getClickedBlock().getType();
|
||||
if (blockType == Material.STONE_PLATE
|
||||
|| blockType == Material.GOLD_PLATE
|
||||
|| blockType == Material.IRON_PLATE
|
||||
|| blockType == Material.WOOD_PLATE
|
||||
|| blockType == Material.TRIPWIRE) {
|
||||
e.setCancelled(true);
|
||||
}
|
||||
String material = e.getClickedBlock().getType().toString();
|
||||
List<String> disallowedMaterials = Arrays.asList("STONE_PLATE", "GOLD_PLATE", "IRON_PLATE",
|
||||
"WOOD_PLATE"/* <- LEGACY */, "TRIPWIRE", "PRESSURE_PLATE");
|
||||
for (String disallowedMaterial : disallowedMaterials)
|
||||
if (material.equals(disallowedMaterial) || material.contains(disallowedMaterial)) {
|
||||
|
||||
e.setCancelled(true);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception er) {
|
||||
|
||||
plugin.logException(er);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onPlace(BlockPlaceEvent e) {
|
||||
|
||||
try {
|
||||
|
||||
if (plugin.getSettings().getBoolean("RestrictiveOptions.PreventBlockPlacing")) {
|
||||
|
||||
Player p = e.getPlayer();
|
||||
Collection<UUID> vanishedPlayers = plugin.getVanishStateMgr().getOnlineVanishedPlayers();
|
||||
if (vanishedPlayers.contains(p.getUniqueId()) && !p.hasPermission("sv.placeblocks")) {
|
||||
|
||||
e.setCancelled(true);
|
||||
plugin.sendMessage(e.getPlayer(), "BlockPlaceDenied", e.getPlayer());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception er) {
|
||||
|
||||
plugin.logException(er);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onBreak(BlockBreakEvent e) {
|
||||
|
||||
try {
|
||||
|
||||
if (plugin.getSettings().getBoolean("RestrictiveOptions.PreventBlockBreaking")) {
|
||||
|
||||
Player p = e.getPlayer();
|
||||
if (plugin.getVanishStateMgr().isVanished(p.getUniqueId()) && !p.hasPermission("sv.breakblocks")) {
|
||||
|
||||
e.setCancelled(true);
|
||||
plugin.sendMessage(e.getPlayer(), "BlockBreakDenied", e.getPlayer());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception er) {
|
||||
|
||||
plugin.logException(er);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+28
-25
@@ -6,68 +6,71 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package de.myzelyam.supervanish.events;
|
||||
package de.myzelyam.supervanish.listeners;
|
||||
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
import de.myzelyam.supervanish.commands.CommandAction;
|
||||
import de.myzelyam.supervanish.features.Broadcast;
|
||||
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.plugin.EventExecutor;
|
||||
|
||||
public class QuitEvent implements EventExecutor, Listener {
|
||||
public class QuitListener implements EventExecutor, Listener {
|
||||
|
||||
private final SuperVanish plugin;
|
||||
|
||||
public QuitEvent(SuperVanish plugin) {
|
||||
public QuitListener(SuperVanish plugin) {
|
||||
|
||||
this.plugin = plugin;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Listener l, Event event) {
|
||||
|
||||
try {
|
||||
|
||||
if (event instanceof PlayerQuitEvent) {
|
||||
|
||||
PlayerQuitEvent e = (PlayerQuitEvent) event;
|
||||
FileConfiguration config = plugin.getConfig();
|
||||
Player p = e.getPlayer();
|
||||
// if is invisible
|
||||
if (plugin.getVanishStateMgr().isVanished(p.getUniqueId())) {
|
||||
|
||||
// remove action bar
|
||||
if (plugin.getActionBarMgr() != null && plugin.getSettings().getBoolean(
|
||||
"MessageOptions.DisplayActionBar")) {
|
||||
if (plugin.getActionBarMgr() != null
|
||||
&& plugin.getSettings().getBoolean("MessageOptions.DisplayActionBar"))
|
||||
{
|
||||
|
||||
plugin.getActionBarMgr().removeActionBar(p);
|
||||
|
||||
}
|
||||
|
||||
// check auto-reappear-option
|
||||
boolean noMsg = false;
|
||||
if (plugin.getSettings().getBoolean("VanishStateFeatures.ReappearOnQuit")
|
||||
|| plugin.getSettings().getBoolean("VanishStateFeatures.CheckPermissionOnQuit")
|
||||
&& !CommandAction.VANISH_SELF.checkPermission(p, plugin)) {
|
||||
&& !CommandAction.VANISH_SELF.checkPermission(p, plugin))
|
||||
{
|
||||
|
||||
plugin.getVanishStateMgr().setVanishedState(p.getUniqueId(), p.getName(), false, null);
|
||||
// collision
|
||||
try {
|
||||
//noinspection deprecation
|
||||
p.getPlayer().spigot().setCollidesWithEntities(true);
|
||||
} catch (NoClassDefFoundError | NoSuchMethodError ignored) {
|
||||
}
|
||||
// check if it should handle the quit msg
|
||||
if (!config.getBoolean("MessageOptions.ReappearOnQuitHideLeaveMsg"))
|
||||
noMsg = true;
|
||||
}
|
||||
// check remove-quit-msg option
|
||||
if (!noMsg && config.getBoolean("MessageOptions.HideRealJoinQuitMessages")) {
|
||||
e.setQuitMessage(null);
|
||||
Broadcast.announceSilentQuit(p, plugin);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// remove VanishPlayer
|
||||
plugin.removeVanishPlayer(plugin.getVanishPlayer(p));
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception er) {
|
||||
|
||||
plugin.logException(er);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* license, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package de.myzelyam.supervanish.listeners;
|
||||
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.server.TabCompleteEvent;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class TabCompleteListener implements Listener {
|
||||
|
||||
private final SuperVanish plugin;
|
||||
|
||||
private boolean errorLogged = false;
|
||||
|
||||
public TabCompleteListener(SuperVanish plugin) {
|
||||
|
||||
this.plugin = plugin;
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onTabComplete(TabCompleteEvent e) {
|
||||
|
||||
try {
|
||||
|
||||
if (!(e.getSender() instanceof Player))
|
||||
return;
|
||||
Player p = (Player) e.getSender();
|
||||
Set<String> hiddenNames = plugin.getVanishStateMgr().getOnlineVanishedPlayers().stream()
|
||||
.map(Bukkit::getPlayer).filter(Objects::nonNull)
|
||||
.filter(vanishedPlayer -> !plugin.canSee(p, vanishedPlayer)).map(HumanEntity::getName)
|
||||
.map(name -> name.toLowerCase(Locale.ENGLISH)).collect(Collectors.toSet());
|
||||
Iterator<String> it = e.getCompletions().iterator();
|
||||
while (it.hasNext()) {
|
||||
|
||||
String completion = it.next();
|
||||
boolean allowedCompletion = !hiddenNames.contains(completion.toLowerCase(Locale.ENGLISH));
|
||||
if (!allowedCompletion) {
|
||||
|
||||
it.remove();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} catch (UnsupportedOperationException uoe) {
|
||||
|
||||
if (!errorLogged) {
|
||||
|
||||
plugin.getLogger().warning("UnsupportedOperationException while modifying TabCompleteEvent");
|
||||
errorLogged = true;
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception er) {
|
||||
|
||||
if (!errorLogged) {
|
||||
|
||||
plugin.logException(er);
|
||||
errorLogged = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+16
-4
@@ -6,7 +6,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package de.myzelyam.supervanish.events;
|
||||
package de.myzelyam.supervanish.listeners;
|
||||
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
import de.myzelyam.supervanish.commands.CommandAction;
|
||||
@@ -17,28 +17,40 @@ import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerChangedWorldEvent;
|
||||
|
||||
public class WorldChangeEvent implements Listener {
|
||||
public class WorldChangeListener implements Listener {
|
||||
|
||||
private final SuperVanish plugin;
|
||||
|
||||
public WorldChangeEvent(SuperVanish plugin) {
|
||||
public WorldChangeListener(SuperVanish plugin) {
|
||||
|
||||
this.plugin = plugin;
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onWorldChange(PlayerChangedWorldEvent e) {
|
||||
|
||||
try {
|
||||
|
||||
final Player p = e.getPlayer();
|
||||
if (!plugin.getVanishStateMgr().isVanished(p.getUniqueId()))
|
||||
return;
|
||||
// check auto-reappear option
|
||||
if (plugin.getSettings().getBoolean("VanishStateFeatures.ReappearOnWorldChange")
|
||||
|| plugin.getSettings().getBoolean("VanishStateFeatures.CheckPermissionOnWorldChange")
|
||||
&& !CommandAction.VANISH_SELF.checkPermission(p, plugin)) {
|
||||
&& !CommandAction.VANISH_SELF.checkPermission(p, plugin))
|
||||
{
|
||||
|
||||
plugin.getVisibilityChanger().showPlayer(p);
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception er) {
|
||||
|
||||
plugin.logException(er);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package de.myzelyam.supervanish.net;
|
||||
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
public class UpdateNotifier {
|
||||
|
||||
// 20 minutes
|
||||
private static final long CHECK_INTERVAL = 20 * 60 * 20;
|
||||
|
||||
private final SuperVanish plugin;
|
||||
private final BukkitTask checkTask;
|
||||
@Getter
|
||||
private final String currentVersion;
|
||||
private final Set<UUID> notifiedPlayers = new HashSet<>();
|
||||
@Getter
|
||||
private volatile String latestVersion;
|
||||
private boolean notifiedConsole = false;
|
||||
|
||||
public UpdateNotifier(final SuperVanish plugin) {
|
||||
this.plugin = plugin;
|
||||
currentVersion = plugin.getDescription().getVersion();
|
||||
checkTask = start();
|
||||
Bukkit.getPluginManager().registerEvents(new Listener() {
|
||||
@EventHandler
|
||||
public void onJoin(final PlayerJoinEvent e) {
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!isUpToDate())
|
||||
notifyPlayer(e.getPlayer());
|
||||
}
|
||||
}.runTaskLater(plugin, 2);
|
||||
}
|
||||
}, plugin);
|
||||
}
|
||||
|
||||
public boolean isUpToDate() {
|
||||
try {
|
||||
if (latestVersion == null) throw new NumberFormatException();
|
||||
int comparision = plugin.getVersionUtil().compareVersions(currentVersion, latestVersion);
|
||||
return comparision >= 0;
|
||||
} catch (NumberFormatException e) {
|
||||
return currentVersion.equals(latestVersion);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyPlayer(Player p) {
|
||||
if (p.hasPermission("sv.notify") && latestVersion != null) {
|
||||
if (notifiedPlayers.contains(p.getUniqueId())) return;
|
||||
notifiedPlayers.add(p.getUniqueId());
|
||||
plugin.sendMessage(p,
|
||||
plugin.getMessage("PluginOutdated").replace("%new%", latestVersion)
|
||||
.replace("%current%", currentVersion), p);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyAdmins() {
|
||||
for (Player p : plugin.getServer().getOnlinePlayers()) {
|
||||
notifyPlayer(p);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyConsole() {
|
||||
if (!notifiedConsole) {
|
||||
plugin.log(Level.INFO, "Your current version of SuperVanish is outdated" +
|
||||
" - New version: '" + latestVersion + "'; Currently: '" + currentVersion + "'");
|
||||
notifiedConsole = true;
|
||||
}
|
||||
}
|
||||
|
||||
private BukkitTask start() {
|
||||
if (checkTask != null) throw new IllegalStateException("Task is already running");
|
||||
return new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
String latestVersion = fetchLatestVersion();
|
||||
UpdateNotifier.this.latestVersion = latestVersion.equals("Error")
|
||||
? UpdateNotifier.this.latestVersion == null
|
||||
? currentVersion
|
||||
: UpdateNotifier.this.latestVersion
|
||||
: latestVersion;
|
||||
if (!isUpToDate())
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
notifyConsole();
|
||||
if (plugin.getSettings().getBoolean(
|
||||
"MiscellaneousOptions.UpdateChecker.NotifyAdmins")) notifyAdmins();
|
||||
}
|
||||
}.runTask(plugin);
|
||||
}
|
||||
}.runTaskTimerAsynchronously(plugin, 0, CHECK_INTERVAL);
|
||||
}
|
||||
|
||||
private String fetchLatestVersion() {
|
||||
try {
|
||||
HttpsURLConnection con = (HttpsURLConnection) new URL(
|
||||
"https://api.spigotmc.org/legacy/update.php?resource=1331").openConnection();
|
||||
con.setConnectTimeout(20 * 1000);
|
||||
con.setReadTimeout(20 * 1000);
|
||||
String version;
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream()))) {
|
||||
version = reader.readLine();
|
||||
}
|
||||
con.disconnect();
|
||||
if (version.length() <= 7)
|
||||
return version;
|
||||
else throw new RuntimeException("'" + version + "' is not a valid version");
|
||||
} catch (Exception e) {
|
||||
plugin.log(Level.WARNING, "Failed to check for an update: "
|
||||
+ e.getMessage());
|
||||
return "Error";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,33 +7,91 @@ import org.bukkit.entity.Player;
|
||||
public class BukkitPlayerHidingUtil {
|
||||
|
||||
private BukkitPlayerHidingUtil() {
|
||||
|
||||
}
|
||||
|
||||
public static void hidePlayer(Player player, Player viewer, SuperVanish plugin) {
|
||||
if (isNewPlayerHidingAPISupported(viewer))
|
||||
viewer.hidePlayer(plugin, player);
|
||||
else
|
||||
//noinspection deprecation
|
||||
viewer.hidePlayer(player);
|
||||
|
||||
try {
|
||||
|
||||
if (isNewPlayerHidingAPISupported(plugin)) {
|
||||
|
||||
Player.class.getMethod("hidePlayer", org.bukkit.plugin.Plugin.class, Player.class).invoke(viewer,
|
||||
plugin, player);
|
||||
|
||||
} else {
|
||||
|
||||
Player.class.getMethod("hidePlayer", Player.class).invoke(viewer, player);
|
||||
|
||||
}
|
||||
|
||||
} catch (ReflectiveOperationException e) {
|
||||
|
||||
throw new RuntimeException("Failed to hide player " + player.getName() + " from " + viewer.getName(), e);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void showPlayer(Player player, Player viewer, SuperVanish plugin) {
|
||||
if (isNewPlayerHidingAPISupported(viewer))
|
||||
viewer.showPlayer(plugin, player);
|
||||
else
|
||||
//noinspection deprecation
|
||||
viewer.showPlayer(player);
|
||||
|
||||
try {
|
||||
|
||||
if (isNewPlayerHidingAPISupported(plugin)) {
|
||||
|
||||
Player.class.getMethod("showPlayer", org.bukkit.plugin.Plugin.class, Player.class).invoke(viewer,
|
||||
plugin, player);
|
||||
|
||||
} else {
|
||||
|
||||
Player.class.getMethod("showPlayer", Player.class).invoke(viewer, player);
|
||||
|
||||
}
|
||||
|
||||
} catch (ReflectiveOperationException e) {
|
||||
|
||||
throw new RuntimeException("Failed to show player " + player.getName() + " to " + viewer.getName(), e);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static boolean isNewPlayerHidingAPISupported(Player testPlayer) {
|
||||
return false; // New API doesn't seem to work with SuperVanish
|
||||
/*
|
||||
Class<? extends Player> playerClass = testPlayer.getClass();
|
||||
try {
|
||||
playerClass.getMethod("hidePlayer", Plugin.class, Player.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
return false;
|
||||
/**
|
||||
* Nuclear show: clears every hide ref that Vanish-OG could plausibly be
|
||||
* responsible for on this (viewer, player) pair. CraftPlayer tracks hides
|
||||
* per-plugin in {@code invertedVisibilityEntities}, and an entity stays hidden
|
||||
* until *all* refs in its set are gone. Essentials'
|
||||
* {@code User#setVanished(true)} and
|
||||
* {@code EssentialsPlayerListener#onPlayerJoin} both call the deprecated
|
||||
* {@code hidePlayer(Player)} form, which registers a {@code null} plugin ref
|
||||
* that Vanish-OG's normal {@code showPlayer(Plugin, Player)} cannot remove — so
|
||||
* {@code /sv cleanup} must also call the deprecated {@code showPlayer(Player)}
|
||||
* to drop it. Without this step, players stay invisible to each other even
|
||||
* after cleanup wipes persisted vanish state and Vanish-OG's own hide map.
|
||||
*/
|
||||
public static void showPlayerAggressive(Player player, Player viewer, SuperVanish plugin) {
|
||||
|
||||
showPlayer(player, viewer, plugin);
|
||||
if (isNewPlayerHidingAPISupported(plugin)) {
|
||||
|
||||
try {
|
||||
|
||||
Player.class.getMethod("showPlayer", Player.class).invoke(viewer, player);
|
||||
|
||||
} catch (ReflectiveOperationException e) {
|
||||
|
||||
throw new RuntimeException("Failed to legacy-show " + player.getName() + " to " + viewer.getName(), e);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return true;*/
|
||||
|
||||
}
|
||||
|
||||
public static boolean isNewPlayerHidingAPISupported(SuperVanish plugin) {
|
||||
|
||||
return plugin.getVersionUtil().isOneDotXOrHigher(19);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,4 +3,5 @@ package de.myzelyam.supervanish.utils;
|
||||
public interface ExceptionHandler {
|
||||
|
||||
void handle(Exception e);
|
||||
|
||||
}
|
||||
@@ -10,70 +10,110 @@ import java.util.logging.Level;
|
||||
public class ExceptionLogger {
|
||||
|
||||
private ExceptionLogger() {
|
||||
|
||||
}
|
||||
|
||||
private static boolean isSensitiveKey(String key) {
|
||||
|
||||
String lower = key.toLowerCase(java.util.Locale.ROOT);
|
||||
return lower.contains("password") || lower.contains("secret") || lower.contains("token")
|
||||
|| lower.contains("apikey") || lower.contains("api-key") || lower.contains("api_key")
|
||||
|| lower.contains("credential");
|
||||
|
||||
}
|
||||
|
||||
public static void logException(Throwable e, SuperVanish plugin) {
|
||||
|
||||
try {
|
||||
|
||||
final boolean realEx = e != null;
|
||||
Level loggingLevel = realEx ? Level.WARNING : Level.INFO;
|
||||
if (realEx) plugin.log(loggingLevel, "Unknown exception occurred!");
|
||||
else plugin.log(loggingLevel, "Printing information...");
|
||||
if (plugin.getConfigMgr().isSettingsUpdateRequired()
|
||||
|| plugin.getConfigMgr().isMessagesUpdateRequired()) {
|
||||
if (realEx) plugin.log(loggingLevel, "You have an outdated configuration, " +
|
||||
"regenerating it by using '/sv recreatefiles' might fix this problem!");
|
||||
else plugin.log(loggingLevel, "Configuration is outdated.");
|
||||
} else if (realEx) plugin.log(loggingLevel, "Please report this issue!");
|
||||
if (!realEx) e = new RuntimeException("Information for reporting an issue");
|
||||
if (realEx)
|
||||
plugin.log(loggingLevel, "Unknown exception occurred!");
|
||||
else
|
||||
plugin.log(loggingLevel, "Printing information...");
|
||||
if (plugin.getConfigMgr().isMessagesUpdateRequired()) {
|
||||
|
||||
if (realEx)
|
||||
plugin.log(loggingLevel, "Your config files may need to be recreated. "
|
||||
+ "Running '/sv recreatefiles' might fix this problem.");
|
||||
else
|
||||
plugin.log(loggingLevel, "Config file recreation may be required.");
|
||||
|
||||
} else if (realEx)
|
||||
plugin.log(loggingLevel, "Please report this issue!");
|
||||
|
||||
if (!realEx)
|
||||
e = new RuntimeException("Information for reporting an issue");
|
||||
plugin.log(loggingLevel, "Message: ");
|
||||
plugin.log(loggingLevel, " " + e.getMessage());
|
||||
plugin.log(loggingLevel, "General information: ");
|
||||
StringBuilder plugins = new StringBuilder();
|
||||
for (Plugin pl : Bukkit.getServer().getPluginManager().getPlugins()) {
|
||||
if (pl.getName().equalsIgnoreCase("SuperVanish")) continue;
|
||||
plugins.append(pl.getName()).append(" v")
|
||||
.append(pl.getDescription().getVersion()).append(", ");
|
||||
|
||||
if (pl.getName().equalsIgnoreCase("Vanish-OG"))
|
||||
continue;
|
||||
plugins.append(pl.getName()).append(" v").append(pl.getPluginMeta().getVersion()).append(", ");
|
||||
|
||||
}
|
||||
|
||||
plugins = new StringBuilder(plugins.substring(0, plugins.length() - 1));
|
||||
plugin.log(loggingLevel, " ServerVersion: " + plugin.getServer().getVersion());
|
||||
plugin.log(loggingLevel, " PluginVersion: "
|
||||
+ plugin.getDescription().getVersion());
|
||||
plugin.log(loggingLevel, " PluginVersion: " + plugin.getPluginMeta().getVersion());
|
||||
plugin.log(loggingLevel, " ServerPlugins: " + plugins);
|
||||
try {
|
||||
|
||||
plugin.log(loggingLevel, "Settings:");
|
||||
plugin.log(loggingLevel, " MsgsVersion: "
|
||||
+ plugin.getMessages().getString("MessagesVersion"));
|
||||
plugin.log(loggingLevel, " MsgsVersion: " + plugin.getMessages().getString("MessagesVersion"));
|
||||
StringBuilder settings = new StringBuilder("||");
|
||||
for (String key : plugin.getSettings().getKeys(true)) {
|
||||
if (!plugin.getSettings().getString(key).contains("MemorySection"))
|
||||
settings.append(key).append(">")
|
||||
.append(plugin.getSettings().getString(key)).append("||");
|
||||
|
||||
if (!plugin.getSettings().getString(key).contains("MemorySection")) {
|
||||
|
||||
String value = isSensitiveKey(key) ? "<redacted>" : plugin.getSettings().getString(key);
|
||||
settings.append(key).append(">").append(value).append("||");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
plugin.log(loggingLevel, " Settings: " + settings);
|
||||
|
||||
} catch (Exception er) {
|
||||
|
||||
plugin.log(Level.SEVERE, ">> Error occurred while trying to print config info <<");
|
||||
|
||||
}
|
||||
|
||||
plugin.log(loggingLevel, "StackTrace: ");
|
||||
e.printStackTrace();
|
||||
if (realEx) {
|
||||
if (plugin.getConfigMgr().isSettingsUpdateRequired()
|
||||
|| plugin.getConfigMgr().isMessagesUpdateRequired())
|
||||
plugin.log(loggingLevel, "You have an outdated configuration, " +
|
||||
"regenerating it by using '/sv recreatefiles' might fix this problem!");
|
||||
|
||||
if (plugin.getConfigMgr().isMessagesUpdateRequired())
|
||||
plugin.log(loggingLevel, "Your config files may need to be recreated. "
|
||||
+ "Running '/sv recreatefiles' might fix this problem.");
|
||||
plugin.log(loggingLevel, "Please include this information");
|
||||
plugin.log(loggingLevel, "if you report the issue.");
|
||||
|
||||
} else
|
||||
plugin.log(loggingLevel, "End of information.");
|
||||
|
||||
} catch (Exception e2) {
|
||||
plugin.log(Level.WARNING,
|
||||
"An exception occurred while trying to print a detailed stacktrace, " +
|
||||
"printing an undetailed stacktrace of both exceptions:");
|
||||
|
||||
plugin.log(Level.WARNING, "An exception occurred while trying to print a detailed stacktrace, "
|
||||
+ "printing an undetailed stacktrace of both exceptions:");
|
||||
plugin.log(Level.SEVERE, "ORIGINAL EXCEPTION:");
|
||||
if (e != null) {
|
||||
|
||||
e.printStackTrace();
|
||||
|
||||
}
|
||||
|
||||
plugin.log(Level.SEVERE, "SECOND EXCEPTION:");
|
||||
e2.printStackTrace();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,5 +9,7 @@
|
||||
package de.myzelyam.supervanish.utils;
|
||||
|
||||
public interface Requirement<T> {
|
||||
|
||||
boolean fulfilledBy(T testSubject);
|
||||
|
||||
}
|
||||
@@ -7,40 +7,62 @@ import java.util.logging.Level;
|
||||
public abstract class Validation {
|
||||
|
||||
public static void checkNotNull(Object... objects) {
|
||||
|
||||
checkNotNull(null, objects);
|
||||
|
||||
}
|
||||
|
||||
public static void checkIsTrue(boolean... bool) {
|
||||
|
||||
checkIsTrue(null, bool);
|
||||
|
||||
}
|
||||
|
||||
public static void checkNotNull(String message, Object... objects) {
|
||||
|
||||
for (Object obj : objects) {
|
||||
|
||||
if (obj == null) {
|
||||
|
||||
if (message != null)
|
||||
log(Level.SEVERE, message);
|
||||
throw new IllegalArgumentException(message == null ? "" : message);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static void checkIsTrue(String message, boolean... booleans) {
|
||||
|
||||
for (boolean bool : booleans) {
|
||||
|
||||
if (!bool) {
|
||||
|
||||
if (message != null)
|
||||
log(Level.SEVERE, message);
|
||||
throw new IllegalArgumentException(message == null ? "" : message);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void log(Level level, String message) {
|
||||
|
||||
try {
|
||||
|
||||
Class.forName("org.bukkit.plugin.java.JavaPlugin");
|
||||
Bukkit.getLogger().log(level, message);
|
||||
|
||||
} catch (ClassNotFoundException e) {
|
||||
|
||||
e.printStackTrace();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,39 +1,65 @@
|
||||
package de.myzelyam.supervanish.utils;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
|
||||
public class VersionUtil {
|
||||
|
||||
private final SuperVanish plugin;
|
||||
private final String version;
|
||||
private final String minecraftVersion;
|
||||
|
||||
public VersionUtil(SuperVanish plugin) {
|
||||
this.plugin = plugin;
|
||||
version = plugin.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
|
||||
|
||||
// Saves versions in the format x.x.x (e.g. 1.20.1).
|
||||
minecraftVersion = plugin.getServer().getBukkitVersion().split(Pattern.quote("-"))[0];
|
||||
|
||||
}
|
||||
|
||||
public int compareVersions(String version1, String version2) {
|
||||
String[] levels1 = version1.split("\\.");
|
||||
String[] levels2 = version2.split("\\.");
|
||||
int length = Math.max(levels1.length, levels2.length);
|
||||
|
||||
final String[] levels1 = version1.split("\\.");
|
||||
final String[] levels2 = version2.split("\\.");
|
||||
final int length = Math.max(levels1.length, levels2.length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
Integer v1 = i < levels1.length ? Integer.parseInt(levels1[i]) : 0;
|
||||
Integer v2 = i < levels2.length ? Integer.parseInt(levels2[i]) : 0;
|
||||
int compare = v1.compareTo(v2);
|
||||
|
||||
final Integer v1 = i < levels1.length ? Integer.parseInt(levels1[i]) : 0;
|
||||
final Integer v2 = i < levels2.length ? Integer.parseInt(levels2[i]) : 0;
|
||||
final int compare = v1.compareTo(v2);
|
||||
if (compare != 0) {
|
||||
|
||||
return compare;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
public boolean isOneDotX(int majorRelease) {
|
||||
return version.contains("v1_" + majorRelease + "_R");
|
||||
|
||||
return minecraftVersion.equals("1." + majorRelease)
|
||||
|| StringUtils.startsWith(minecraftVersion, "1." + majorRelease + ".");
|
||||
|
||||
}
|
||||
|
||||
public boolean isOneDotXOrHigher(int majorRelease) {
|
||||
for (int i = majorRelease; i < 20; i++)
|
||||
if (version.contains("v1_" + i + "_R")) return true;
|
||||
return version.contains("v2_");
|
||||
|
||||
for (int i = majorRelease; i < 40; i++) {
|
||||
|
||||
if (minecraftVersion.equals("1." + i) || StringUtils.startsWith(minecraftVersion, "1." + i + ".")) {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return StringUtils.startsWith(minecraftVersion, "2.");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,17 +13,12 @@ import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
||||
import com.comphenix.protocol.wrappers.WrappedChatComponent;
|
||||
|
||||
import de.myzelyam.supervanish.SuperVanish;
|
||||
|
||||
import net.md_5.bungee.api.ChatMessageType;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -33,54 +28,95 @@ public class ActionBarMgr {
|
||||
private final List<Player> actionBars = new ArrayList<>();
|
||||
|
||||
public ActionBarMgr(SuperVanish plugin) {
|
||||
|
||||
this.plugin = plugin;
|
||||
startTask();
|
||||
|
||||
}
|
||||
|
||||
private void startTask() {
|
||||
|
||||
new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
for (Player p : actionBars) {
|
||||
|
||||
try {
|
||||
sendActionBar(p, plugin.replacePlaceholders(
|
||||
plugin.getMessage("ActionBarMessage"), p));
|
||||
} catch (Exception e) {
|
||||
|
||||
sendActionBar(p, plugin.expandPlaceholders(p, plugin.getMessage("ActionBarMessage"), p));
|
||||
|
||||
} catch (Exception | NoSuchMethodError | NoClassDefFoundError e) {
|
||||
|
||||
cancel();
|
||||
plugin.logException(e);
|
||||
plugin.getLogger().warning("IMPORTANT: Please make sure that you are using the latest "
|
||||
+ "dev-build of ProtocolLib and that your server is up-to-date! This error likely "
|
||||
+ "happened inside of ProtocolLib code which is out of Vanish-OG's control. It's part "
|
||||
+ "of an optional feature module and can be removed safely by disabling "
|
||||
+ "DisplayActionBar in the config file. Please report this "
|
||||
+ "error if you can reproduce it on an up-to-date server with only latest "
|
||||
+ "ProtocolLib and latest Vanish-OG installed.");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}.runTaskTimer(plugin, 0, 2 * 20);
|
||||
|
||||
}
|
||||
|
||||
private void sendActionBar(Player p, String bar) {
|
||||
String json = "{\"text\": \"" + ChatColor.translateAlternateColorCodes('&', bar) + "\"}";
|
||||
WrappedChatComponent msg = WrappedChatComponent.fromJson(json);
|
||||
PacketContainer chatMsg = new PacketContainer(PacketType.Play.Server.CHAT);
|
||||
chatMsg.getChatComponents().write(0, msg);
|
||||
if (plugin.getVersionUtil().isOneDotXOrHigher(12))
|
||||
try {
|
||||
chatMsg.getChatTypes().write(0, EnumWrappers.ChatType.GAME_INFO);
|
||||
} catch (NoSuchMethodError e) {
|
||||
p.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText
|
||||
("SuperVanish: Please update ProtocolLib"));
|
||||
}
|
||||
else
|
||||
chatMsg.getBytes().write(0, (byte) 2);
|
||||
private void sendActionBar(Player p, Component bar) {
|
||||
|
||||
try {
|
||||
ProtocolLibrary.getProtocolManager().sendServerPacket(p, chatMsg);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new RuntimeException("Cannot send packet " + chatMsg, e);
|
||||
|
||||
p.sendActionBar(bar);
|
||||
|
||||
} catch (NoSuchMethodError | NoClassDefFoundError er) {
|
||||
|
||||
String json = GsonComponentSerializer.gson().serialize(bar);
|
||||
WrappedChatComponent msg = WrappedChatComponent.fromJson(json);
|
||||
PacketContainer chatMsg = new PacketContainer(PacketType.Play.Server.CHAT);
|
||||
chatMsg.getChatComponents().write(0, msg);
|
||||
if (plugin.getVersionUtil().isOneDotXOrHigher(12))
|
||||
try {
|
||||
|
||||
chatMsg.getChatTypes().write(0, EnumWrappers.ChatType.GAME_INFO);
|
||||
|
||||
} catch (NoSuchMethodError e) {
|
||||
|
||||
p.sendActionBar(Component.text("Vanish-OG: Please update ProtocolLib"));
|
||||
|
||||
}
|
||||
else
|
||||
chatMsg.getBytes().write(0, (byte) 2);
|
||||
try {
|
||||
|
||||
ProtocolLibrary.getProtocolManager().sendServerPacket(p, chatMsg);
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
throw new RuntimeException("Cannot send packet " + chatMsg, e);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void addActionBar(Player p) {
|
||||
|
||||
actionBars.add(p);
|
||||
|
||||
}
|
||||
|
||||
public void removeActionBar(Player p) {
|
||||
|
||||
actionBars.remove(p);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Loaded 100 of 115 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user