mirror of
https://github.com/EssentialsX/Essentials.git
synced 2026-11-05 09:10:17 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a6edf04a60 | ||
|
|
3ba675a899 | ||
|
|
1fed7a9a3a | ||
|
|
80fb91b6d7 | ||
|
|
5b0c2a4131 | ||
|
|
bb43e8f7b6 | ||
|
|
4d9a10147a | ||
|
|
ea4f5cf919 | ||
|
|
295bc9f76d | ||
|
|
327806d9a1 | ||
|
|
80e7558fc0 | ||
|
|
9cda59511e | ||
|
|
c12a031918 | ||
|
|
a4f580e319 | ||
|
|
583bf88207 | ||
|
|
a5f8e83e03 | ||
|
|
e2f17f11d3 | ||
|
|
4f8c040d06 | ||
|
|
af1d068022 | ||
|
|
1bd8d1c85c | ||
|
|
d7fc859d14 | ||
|
|
ac953cd114 | ||
|
|
6e6dd041d5 | ||
|
|
9b3c8a9df2 | ||
|
|
234a481b0d | ||
|
|
89b3c9233e | ||
|
|
5d61a43fe1 | ||
|
|
29d5ccf751 | ||
|
|
fde0665593 | ||
|
|
29541b0995 | ||
|
|
05f31c5ddf | ||
|
|
f89840545d | ||
|
|
18534f8576 | ||
|
|
1382a05dc8 | ||
|
|
1671d4839c | ||
|
|
4d2fbd04c5 | ||
|
|
dc6b9b89cd | ||
|
|
76f36aa895 | ||
|
|
fa835e9c64 | ||
|
|
c8dc874a56 | ||
|
|
b3a6307052 | ||
|
|
3ca0181b79 | ||
|
|
98557dcecf | ||
|
|
3351092c79 | ||
|
|
68cd509d41 | ||
|
|
5fa65b42ae | ||
|
|
bdae259a1d | ||
|
|
fea86ea70e | ||
|
|
1133770aeb | ||
|
|
2c462106bc | ||
|
|
bd1e624c91 | ||
|
|
6875fa4c7e | ||
|
|
def5f2155d | ||
|
|
73d2457fea | ||
|
|
bc52ca856e | ||
|
|
18ccea320a | ||
|
|
f6cb9ff470 | ||
|
|
14c6c2a055 | ||
|
|
68d0aa9688 | ||
|
|
1ef4e15a4d | ||
|
|
d35b4b9128 | ||
|
|
6995be7dbd | ||
|
|
f9de6763d3 | ||
|
|
dfce971565 | ||
|
|
97e3f32d7f | ||
|
|
c86e1a5973 | ||
|
|
ab545dc44c | ||
|
|
11cd57e8fb | ||
|
|
b7c18d0785 | ||
|
|
9aec89f381 | ||
|
|
e34984513d | ||
|
|
cedd42f411 | ||
|
|
c9b75aabb2 | ||
|
|
41ae12ed3d | ||
|
|
dba35f043d | ||
|
|
8046b8594a | ||
|
|
6c64aaefec | ||
|
|
07fa87dc6a | ||
|
|
b58c98bea0 | ||
|
|
08e553bd1a | ||
|
|
e35fb82bc2 | ||
|
|
a92ca63ca9 | ||
|
|
cbfad7b320 | ||
|
|
c16987fb87 | ||
|
|
477f5a7841 | ||
|
|
6f149224d1 | ||
|
|
1a6ad2fdb0 | ||
|
|
76e511a774 | ||
|
|
9681933ec2 | ||
|
|
711bfed557 | ||
|
|
016a1b3421 | ||
|
|
01b9ec4a42 | ||
|
|
9b729dd091 | ||
|
|
0a73be2082 | ||
|
|
c668879070 | ||
|
|
c4d318b7d0 | ||
|
|
e7d9dbfbcf | ||
|
|
1be3daf0b5 | ||
|
|
8f86849aec | ||
|
|
0b4ee9e73e | ||
|
|
65f88834ba | ||
|
|
024c56efdd | ||
|
|
9c487b0aac | ||
|
|
d743f928ad | ||
|
|
07e2fe3af1 | ||
|
|
9f384c71f3 | ||
|
|
7a5aea0bcf | ||
|
|
b6c9bc1439 | ||
|
|
b7f38517ef | ||
|
|
60f54ee37d | ||
|
|
adf1273bf9 | ||
|
|
3c79e9e59d | ||
|
|
1ab1b5713e | ||
|
|
edf2f295d1 | ||
|
|
c043416b11 | ||
|
|
4a471f0a93 | ||
|
|
04a1d8197f | ||
|
|
d9bf099c3d | ||
|
|
d2f2140be9 | ||
|
|
04f88e460b | ||
|
|
d64f73e719 | ||
|
|
2ab4dcbc11 | ||
|
|
846043e9a0 | ||
|
|
ea57e4ae01 | ||
|
|
6aa5e5cc4a | ||
|
|
3e5bd4cf09 | ||
|
|
3d096c1f31 | ||
|
|
b5b6bce758 | ||
|
|
46ed8e954f | ||
|
|
cfca2f7550 | ||
|
|
a09df9bf3a | ||
|
|
dc2462c277 | ||
|
|
25c7ebcf39 | ||
|
|
baab65d776 | ||
|
|
9e2b906048 | ||
|
|
9f3c2683ae | ||
|
|
9e01a1a427 | ||
|
|
db729241c9 | ||
|
|
d5d8c80d74 | ||
|
|
4c48ccb422 | ||
|
|
53e7c83254 | ||
|
|
fdef1062f0 | ||
|
|
b9f8fc2e11 | ||
|
|
db410fb3e7 | ||
|
|
500dadc760 | ||
|
|
7d61953753 | ||
|
|
5b9b76d5e7 | ||
|
|
b9804d8980 | ||
|
|
b960ee365a | ||
|
|
302f0acbaa | ||
|
|
8f5b97b9d2 | ||
|
|
6371cf7517 | ||
|
|
e53520aef6 | ||
|
|
d59fd71ba5 | ||
|
|
4b967a749b | ||
|
|
8f88a8dcb3 | ||
|
|
a58ba406eb | ||
|
|
a93ca9b7bc | ||
|
|
02e6b5f1b3 | ||
|
|
63dd5f3f64 | ||
|
|
a3a50e9cd5 | ||
|
|
8e3c1aaa96 | ||
|
|
8b71437264 | ||
|
|
61d0ed3f01 | ||
|
|
fc2b7b63a2 | ||
|
|
96590a3389 | ||
|
|
a043de3e44 | ||
|
|
81d3900ef6 | ||
|
|
fd136384a1 | ||
|
|
dd5fe117b5 | ||
|
|
e9d29f789f | ||
|
|
1bc1f646fd | ||
|
|
8ad55cb634 | ||
|
|
b19dec120a | ||
|
|
283c088b21 | ||
|
|
d5ffed09b4 | ||
|
|
b7eec09307 | ||
|
|
23f0f98af3 | ||
|
|
6bbdbc89a6 | ||
|
|
12c8623666 | ||
|
|
2bd6ebd2b1 | ||
|
|
40fb496052 | ||
|
|
b72d822f94 | ||
|
|
6d92ac9af6 | ||
|
|
47f27a8016 | ||
|
|
849d095e9a | ||
|
|
923f240aa1 | ||
|
|
8655ff2de3 | ||
|
|
6f61010cf9 | ||
|
|
5082badca4 | ||
|
|
307bd2a35f | ||
|
|
a11552f497 | ||
|
|
8556caaeb4 | ||
|
|
7c09012b3d | ||
|
|
eb596caa00 | ||
|
|
ab4501aa4c | ||
|
|
4b766d373d | ||
|
|
e3574edc5d | ||
|
|
dcb69ddc73 | ||
|
|
1d6ad297a4 | ||
|
|
85a5e517c9 | ||
|
|
b08d380643 | ||
|
|
ad98fc4121 | ||
|
|
810689c037 | ||
|
|
c007700c59 | ||
|
|
8cc3f6626b | ||
|
|
a3b8a4adc9 | ||
|
|
8f817c089b | ||
|
|
ed4e7794c3 | ||
|
|
6f732d410e | ||
|
|
6c8da20883 | ||
|
|
c7d9ce7f7f | ||
|
|
4e7f639076 | ||
|
|
b2c3b3a99f | ||
|
|
77338d66dc | ||
|
|
e2130df596 | ||
|
|
2bbe6d6069 | ||
|
|
c8b8e505f3 | ||
|
|
89743f9900 | ||
|
|
dbc0562fb0 | ||
|
|
76f4dff14c | ||
|
|
baa2a2f24f | ||
|
|
2ca02911b3 | ||
|
|
cf48237049 | ||
|
|
adfe2c1975 | ||
|
|
a782043798 | ||
|
|
90c4a2f53c | ||
|
|
338b371e4c | ||
|
|
347179373d | ||
|
|
3bb45b80b1 | ||
|
|
e3ec0f3b9b | ||
|
|
f20572b30c | ||
|
|
2124cce603 | ||
|
|
ebf60c1e70 | ||
|
|
c31b6c3683 | ||
|
|
ffc83343fe | ||
|
|
2554acd304 | ||
|
|
98239114ad | ||
|
|
c10b39c1c7 | ||
|
|
20e11465e4 | ||
|
|
46e1b95b33 | ||
|
|
279d6f16e1 | ||
|
|
a747eccaa3 | ||
|
|
0bafbc3184 | ||
|
|
8069370b8c | ||
|
|
46f4b92ff7 | ||
|
|
d92f5ce71c | ||
|
|
2314bf8bd4 | ||
|
|
7808b21496 | ||
|
|
18ef412211 | ||
|
|
0678328253 | ||
|
|
5503e1e14c | ||
|
|
9e89cfa4ed | ||
|
|
13f454a022 | ||
|
|
129650dade | ||
|
|
6fa5b80c0a | ||
|
|
04dfcd0965 | ||
|
|
2e818ac709 | ||
|
|
32ef61197f | ||
|
|
fa06cd8253 | ||
|
|
5020983af5 | ||
|
|
f4496b6977 | ||
|
|
a1719d651e | ||
|
|
e7be2b68a3 | ||
|
|
552dcb56a1 | ||
|
|
e158a65603 | ||
|
|
b694e8aaa2 | ||
|
|
a2e09121ba | ||
|
|
4ce7dfa8f0 | ||
|
|
1c4ce7b4bd | ||
|
|
8a04c1e232 | ||
|
|
6e5d378324 | ||
|
|
8e1f3617fd | ||
|
|
2549ed830f | ||
|
|
0ebd64d314 | ||
|
|
843ecb4a42 | ||
|
|
a1a0d34940 | ||
|
|
15bb978dab | ||
|
|
6a7cf39548 | ||
|
|
8ccb70d07d | ||
|
|
45461a93b0 | ||
|
|
b3a54a78bc | ||
|
|
a4182b5ff9 | ||
|
|
215dcde4b9 | ||
|
|
67b2a9a4f4 | ||
|
|
3b51b23ac2 | ||
|
|
e0f19f8121 | ||
|
|
e720fb528a | ||
|
|
518a5454c6 | ||
|
|
2d9c846084 | ||
|
|
59e30f05fc | ||
|
|
0f1085a02d | ||
|
|
882699919e | ||
|
|
f6a70a542e | ||
|
|
785b1fe937 | ||
|
|
bae909ba10 | ||
|
|
dbb9757a9f | ||
|
|
deaeb46ce9 | ||
|
|
219012bc35 | ||
|
|
5f9eb22d23 | ||
|
|
2c33fb6834 | ||
|
|
8bcef6022b | ||
|
|
93d36779f0 | ||
|
|
2502f5e6f2 | ||
|
|
95f2852cf3 | ||
|
|
ff9f712d65 | ||
|
|
60c4e75a1c | ||
|
|
ccf7c48bf1 | ||
|
|
65d81eb31e | ||
|
|
b97eb12dfc | ||
|
|
d2724d77df | ||
|
|
119b21ac67 | ||
|
|
1ff73b3837 | ||
|
|
d98f8b3467 | ||
|
|
ac8b8861cb | ||
|
|
22dc5dcebd | ||
|
|
3c09e72ce4 | ||
|
|
fffc3fcac7 | ||
|
|
bcdbbe9546 | ||
|
|
19f03cd70e | ||
|
|
9b7858b830 | ||
|
|
8bc55387dd |
No files matched your search
@@ -0,0 +1,183 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE module PUBLIC "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
|
||||
"https://checkstyle.org/dtds/configuration_1_3.dtd">
|
||||
|
||||
<!-- based on https://github.com/KyoriPowered/adventure/blob/master/.checkstyle/checkstyle.xml -->
|
||||
|
||||
<module name="Checker">
|
||||
<property name="charset" value="UTF-8"/>
|
||||
<property name="fileExtensions" value="java, properties, xml"/>
|
||||
<property name="severity" value="error"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_filefilters.html#BeforeExecutionExclusionFileFilter -->
|
||||
<module name="BeforeExecutionExclusionFileFilter">
|
||||
<property name="fileNamePattern" value="module\-info\.java$"/>
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_whitespace.html#FileTabCharacter -->
|
||||
<module name="FileTabCharacter">
|
||||
<property name="eachLine" value="true"/>
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_misc.html#NewlineAtEndOfFile -->
|
||||
<module name="NewlineAtEndOfFile"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_filters.html#SuppressionFilter -->
|
||||
<module name="SuppressionFilter">
|
||||
<property name="file" value="${checkstyle.suppressions.file}"/>
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_filters.html#SuppressWithPlainTextCommentFilter -->
|
||||
<module name="SuppressWithPlainTextCommentFilter"/>
|
||||
|
||||
<module name="TreeWalker">
|
||||
<!-- https://checkstyle.org/config_misc.html#ArrayTypeStyle -->
|
||||
<module name="ArrayTypeStyle"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_imports.html#AvoidStarImport -->
|
||||
<module name="AvoidStarImport"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_misc.html#AvoidEscapedUnicodeCharacters -->
|
||||
<module name="AvoidEscapedUnicodeCharacters">
|
||||
<property name="allowByTailComment" value="true"/>
|
||||
<property name="allowEscapesForControlCharacters" value="true"/>
|
||||
<property name="allowNonPrintableEscapes" value="true"/>
|
||||
<property name="severity" value="info"/>
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_misc.html#CommentsIndentation -->
|
||||
<module name="CommentsIndentation"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_whitespace.html#EmptyForInitializerPad -->
|
||||
<module name="EmptyForInitializerPad"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_whitespace.html#EmptyForIteratorPad -->
|
||||
<module name="EmptyForIteratorPad"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_whitespace.html#EmptyLineSeparator -->
|
||||
<module name="EmptyLineSeparator">
|
||||
<property name="allowMultipleEmptyLines" value="false"/>
|
||||
<property name="allowMultipleEmptyLinesInsideClassMembers" value="false"/>
|
||||
<property name="allowNoEmptyLineBetweenFields" value="true"/>
|
||||
<property name="tokens"
|
||||
value="CLASS_DEF, CTOR_DEF, ENUM_DEF, IMPORT, INSTANCE_INIT, INTERFACE_DEF, METHOD_DEF, STATIC_IMPORT, STATIC_INIT, VARIABLE_DEF"/> <!-- remove PACKAGE_DEF, temporarily remove COMPACT_CTOR_DEF, RECORD_DEF -->
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_coding.html#FallThrough -->
|
||||
<module name="FallThrough">
|
||||
<property name="checkLastCaseGroup" value="true"/>
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_design.html#FinalClass -->
|
||||
<module name="FinalClass"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_coding.html#FinalLocalVariable -->
|
||||
<module name="FinalLocalVariable"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_whitespace.html#GenericWhitespace -->
|
||||
<module name="GenericWhitespace"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_design.html#HideUtilityClassConstructor -->
|
||||
<module name="HideUtilityClassConstructor"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_imports.html#IllegalImport -->
|
||||
<module name="IllegalImport">
|
||||
<property name="illegalPkgs" value="sun, jdk, com.sun"/>
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_coding.html#IllegalTokenText -->
|
||||
<module name="IllegalTokenText">
|
||||
<property name="format"
|
||||
value="\\u00(09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/>
|
||||
<property name="message"
|
||||
value="Consider using special escape sequence instead of octal value or Unicode escaped value."/>
|
||||
<property name="tokens" value="CHAR_LITERAL, STRING_LITERAL"/>
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_misc.html#Indentation -->
|
||||
<module name="Indentation"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_blocks.html#LeftCurly -->
|
||||
<module name="LeftCurly"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_naming.html#MethodName -->
|
||||
<module name="MethodName">
|
||||
<property name="format" value="^[_]?[a-z][a-zA-Z0-9]*$"/>
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_whitespace.html#MethodParamPad -->
|
||||
<module name="MethodParamPad"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_javadoc.html#MissingJavadocMethod -->
|
||||
<module name="MissingJavadocMethod">
|
||||
<property name="allowMissingPropertyJavadoc" value="true"/>
|
||||
<property name="tokens" value="METHOD_DEF, ANNOTATION_FIELD_DEF"/> <!-- remove CTOR_DEF, COMPACT_CTOR_DEF -->
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_javadoc.html#MissingJavadocType -->
|
||||
<module name="MissingJavadocType"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_coding.html#NoFinalizer -->
|
||||
<module name="NoFinalizer"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_whitespace.html#NoLineWrap -->
|
||||
<module name="NoLineWrap"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_whitespace.html#NoWhitespaceAfter -->
|
||||
<module name="NoWhitespaceAfter">
|
||||
<property name="allowLineBreaks" value="false"/>
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_whitespace.html#NoWhitespaceBefore -->
|
||||
<module name="NoWhitespaceBefore">
|
||||
<property name="allowLineBreaks" value="true"/>
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_coding.html#OneStatementPerLine -->
|
||||
<module name="OneStatementPerLine"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_misc.html#OuterTypeFilename -->
|
||||
<module name="OuterTypeFilename"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_imports.html#RedundantImport -->
|
||||
<module name="RedundantImport"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_modifier.html#RedundantModifier -->
|
||||
<module name="RedundantModifier">
|
||||
<property name="tokens"
|
||||
value="ANNOTATION_FIELD_DEF, CLASS_DEF, CTOR_DEF, ENUM_DEF, INTERFACE_DEF, VARIABLE_DEF"/> <!-- remove METHOD_DEF and RESOURCE -->
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_coding.html#RequireThis -->
|
||||
<module name="RequireThis"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_blocks.html#RightCurly -->
|
||||
<module name="RightCurly">
|
||||
<property name="id" value="RightCurlyAlone"/>
|
||||
<property name="option" value="alone"/>
|
||||
<property name="tokens"
|
||||
value="ANNOTATION_DEF, CLASS_DEF, CTOR_DEF, ENUM_DEF, INSTANCE_INIT, LITERAL_FOR, LITERAL_WHILE, METHOD_DEF, STATIC_INIT"/>
|
||||
</module>
|
||||
<module name="RightCurly">
|
||||
<property name="id" value="RightCurlySame"/>
|
||||
<property name="option" value="same"/>
|
||||
<property name="tokens"
|
||||
value="LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY, LITERAL_IF, LITERAL_TRY"/> <!-- add LITERAL_DO -->
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_whitespace.html#SingleSpaceSeparator -->
|
||||
<module name="SingleSpaceSeparator">
|
||||
<property name="validateComments" value="true"/>
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_whitespace.html#TypecastParenPad -->
|
||||
<module name="TypecastParenPad"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_coding.html#UnnecessaryParentheses -->
|
||||
<module name="UnnecessaryParentheses"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_imports.html#UnusedImports -->
|
||||
<module name="UnusedImports"/>
|
||||
|
||||
</module>
|
||||
</module>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE suppressions PUBLIC "-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN" "http://checkstyle.org/dtds/suppressions_1_2.dtd">
|
||||
<suppressions>
|
||||
<suppress files=".*[\\/]test[\\/]java[\\/].*" checks="RequireExplicitVisibilityModifier"/>
|
||||
<!-- TODO: don't suppress I-prefixed API interfaces under com.earth2me.essentials -->
|
||||
<suppress files="(com[\\/]earth2me[\\/]essentials[\\/]|net[\\/]ess3[\\/])(?:[^\\/]+$|(?!api)[^\\/]+[\\/])" checks="MissingJavadoc(Method|Type)"/>
|
||||
</suppressions>
|
||||
+1
-1
@@ -1,10 +1,10 @@
|
||||
# Currently used
|
||||
patreon: EssentialsX
|
||||
ko_fi: essentialsx
|
||||
|
||||
# Currently not used
|
||||
#github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
#open_collective: # Replace with a single Open Collective username
|
||||
#ko_fi: # Replace with a single Ko-fi username
|
||||
#tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
#community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
#liberapay: # Replace with a single Liberapay username
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: MOSS Discord Server
|
||||
url: https://discord.gg/casfFyh
|
||||
about: Need help with using EssentialsX? Join the MOSS Discord server for help.
|
||||
@@ -1,45 +1,86 @@
|
||||
---
|
||||
name: Help!
|
||||
about: Encountered a problem with EssentialsX? Not sure how to fix it?
|
||||
labels: 'type: question'
|
||||
|
||||
---
|
||||
|
||||
<!-- EssentialsX help guide
|
||||
<!-- EssentialsX help request guide
|
||||
|
||||
Don't write inside the arrows as they will be hidden when you post your issue.
|
||||
NOTE: Failure to fill out this template properly may result in your issue being
|
||||
delayed or ignored.
|
||||
|
||||
Want faster support? Come join our Discord server to get help sooner:
|
||||
https://discord.gg/F7gexAQ
|
||||
Don't type between any arrows in the template, as this text will be hidden.
|
||||
This includes this header block and any other explanatory text blocks.
|
||||
|
||||
Want faster support? Come join our Discord server to get help from both
|
||||
developers and community members: https://discord.gg/F7gexAQ
|
||||
|
||||
If you're happy to wait (or you were sent here from Discord), read on:
|
||||
|
||||
1. Fill out the template.
|
||||
This will help us understand what problem you've encountered and help us
|
||||
find a solution.
|
||||
|
||||
2. Check the Common Issues page.
|
||||
1. Check the Common Issues page.
|
||||
Read through the wiki page to see if you've encountered a regular issue:
|
||||
https://essentialsx.github.io/#/Common-Issues
|
||||
https://essentialsx.net/wiki/Common-Issues.html
|
||||
|
||||
3. Delete this line and all above lines before posting your issue! -->
|
||||
2. Fill out the template.
|
||||
Run the commands in the console. Don't just put "latest" as a version, or
|
||||
we will ignore it. This will help us understand what problem you've
|
||||
encountered and help us find a solution.
|
||||
|
||||
3. When linking logs or config files, do not attach them to the post!
|
||||
Copy and paste any logs into https://gist.github.com/, then paste a
|
||||
link to them in the relevant parts of the template. Do not use Hastebin
|
||||
or Pastebin, as this can cause issues when trying to solve issues in the
|
||||
future.
|
||||
**DO NOT drag logs into this text box!**
|
||||
|
||||
4. If you are encountering a performance issue, please include a link to a
|
||||
Timings and/or profiler report.
|
||||
|
||||
-->
|
||||
|
||||
### Information
|
||||
|
||||
Full output of `/ess version`:
|
||||
**Full output of `/ess version`:**
|
||||
<!--
|
||||
Run /ess version in the console, then paste the full output of the command
|
||||
between the ```s.
|
||||
-->
|
||||
```
|
||||
|
||||
<!-- Replace this with the command output -->
|
||||
```
|
||||
|
||||
**Server log:** <!-- Upload `logs/latest.log` to https://gist.github.com/ -->
|
||||
**Server startup log:**
|
||||
<!--
|
||||
Restart your server and upload `logs/latest.log` to
|
||||
https://gist.github.com/. You may redact sensitive data (such as IP
|
||||
addresses), but you should make it clear what data was removed. Once
|
||||
uploaded, paste the link below this block.
|
||||
-->
|
||||
|
||||
|
||||
**EssentialsX config:**
|
||||
<!--
|
||||
Upload `plugins/Essentials/config.yml` (and other config files if relevant)
|
||||
to https://gist.github.com/ then paste the link below this block.
|
||||
-->
|
||||
|
||||
**EssentialsX config** <!-- Upload `plugins/Essentials/config.yml` to https://gist.github.com/ -->
|
||||
|
||||
### Help request
|
||||
|
||||
**Problem**
|
||||
<!-- What problem did you encounter? -->
|
||||
**Problem:**
|
||||
<!-- What problem did you encounter? Type below this line. -->
|
||||
|
||||
**What I have tried**
|
||||
<!-- What have you tried so far? -->
|
||||
**What I have tried:**
|
||||
<!-- What have you tried so far? Type below this line. -->
|
||||
|
||||
**Screenshots**
|
||||
<!-- If relevant, include any screenshots here. -->
|
||||
**Console stack trace:**
|
||||
<!--
|
||||
If you are reporting an error in the console, paste it between the ```s.
|
||||
-->
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
**Screenshots:**
|
||||
<!-- If relevant, include any screenshots or a video below this line. -->
|
||||
@@ -1,12 +1,17 @@
|
||||
---
|
||||
name: Report a bug
|
||||
about: Report an EssentialsX bug. Only use this if you're 100% sure there's something wrong with EssentialsX - otherwise, try "Help!".
|
||||
labels: 'bug: unconfirmed'
|
||||
|
||||
---
|
||||
|
||||
<!-- EssentialsX bug reporting guide
|
||||
|
||||
Don't put anything inside this block, as it won't be included in the issue.
|
||||
NOTE: Failure to fill out this template properly may result in your issue being
|
||||
delayed or ignored.
|
||||
|
||||
Don't type between any arrows in the template, as this text will be hidden.
|
||||
This includes this header block and any other explanatory text blocks.
|
||||
|
||||
If you are reporting a bug, please follow the following steps:
|
||||
|
||||
@@ -18,7 +23,7 @@ If you are reporting a bug, please follow the following steps:
|
||||
Copy and paste any logs into https://gist.github.com/, then paste a
|
||||
link to them in the relevant parts of the template. Avoid using
|
||||
Hastebin or Pastebin, as this makes providing support more difficult.
|
||||
**DO NOT drag files into this box!**
|
||||
**DO NOT drag files into this text box!**
|
||||
|
||||
3. If you are reporting a performance issue, please include a link to a
|
||||
Timings and/or profiler report.
|
||||
@@ -26,33 +31,53 @@ If you are reporting a bug, please follow the following steps:
|
||||
4. If you are reporting a bug with commands or something else in-game,
|
||||
please include screenshots to help us diagnose the problem.
|
||||
|
||||
5. Make sure not to write between the arrows, as anything there will be
|
||||
hidden.
|
||||
|
||||
6. Delete this line and all above lines before posting your issue! -->
|
||||
-->
|
||||
|
||||
### Information
|
||||
|
||||
**Full output of `/ess version`**:
|
||||
|
||||
```
|
||||
<!-- Run the command in your console, and copy and paste the whole output here -->
|
||||
**Full output of `/ess version`:**
|
||||
<!--
|
||||
Run /ess version in the console, then paste the full output of the command
|
||||
between the ```s.
|
||||
-->
|
||||
```
|
||||
|
||||
**Server log**: <!-- Upload `logs/latest.log` to https://gist.github.com/, replace this with link -->
|
||||
```
|
||||
|
||||
**Server startup log:**
|
||||
<!--
|
||||
Restart your server and upload `logs/latest.log` to
|
||||
https://gist.github.com/. You may redact sensitive data (such as IP
|
||||
addresses), but you should make it clear what data was removed. Once
|
||||
uploaded, paste the link below this block.
|
||||
-->
|
||||
|
||||
|
||||
**EssentialsX config:**
|
||||
<!--
|
||||
Upload `plugins/Essentials/config.yml` (and other config files if relevant)
|
||||
to https://gist.github.com/ then paste the link below this block.
|
||||
-->
|
||||
|
||||
**EssentialsX config**: <!-- Upload `plugins/Essentials/config.yml` to https://gist.github.com/, replace this with link -->
|
||||
|
||||
### Details
|
||||
|
||||
**Description**
|
||||
<!-- Replace this with a brief summary of the bug. -->
|
||||
**Description:**
|
||||
<!-- What is the bug? Type a brief summary below this line. -->
|
||||
|
||||
**Steps to reproduce**
|
||||
<!-- Replace this with exactly what you did to cause the bug. -->
|
||||
**Steps to reproduce:**
|
||||
<!-- How did you cause it? Describe what you did to cause the bug below. -->
|
||||
|
||||
**Expected behavior**
|
||||
<!-- Replace this with what you expected to happen. -->
|
||||
**Expected behavior:**
|
||||
<!-- What did you expect to happen? Type below this line. -->
|
||||
|
||||
**Screenshots**
|
||||
<!-- Replace this with screenshots, if necessary. -->
|
||||
**Console stack trace:**
|
||||
<!--
|
||||
If you are encountering an error in the console, paste it between the ```s.
|
||||
-->
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
**Screenshots:**
|
||||
<!-- If necessary, include screenshots or a video below this line. -->
|
||||
@@ -1,13 +1,17 @@
|
||||
---
|
||||
name: Request a feature
|
||||
about: Suggest a feature you want to see in EssentialsX!
|
||||
labels: 'type: enhancement'
|
||||
|
||||
---
|
||||
|
||||
<!-- EssentialsX feature request guide
|
||||
|
||||
Fill out the template. Don't write inside the arrows as they will be hidden
|
||||
when you post your issue.
|
||||
NOTE: Failure to fill out this template properly may result in your issue being
|
||||
delayed or ignored.
|
||||
|
||||
Don't type between any arrows in the template, as this text will be hidden.
|
||||
This includes this header block and any other explanatory text blocks.
|
||||
|
||||
Not sure if your feature fits in EssentialsX? Feel free to ask on our Discord
|
||||
server: https://discord.gg/F7gexAQ
|
||||
@@ -26,20 +30,23 @@ If you have a feature suggestion for EssentialsX, read the following tips:
|
||||
3. Check whether it has already been asked or added.
|
||||
You can search the issue tracker to see if your feature has already been
|
||||
requested at https://github.com/EssentialsX/Essentials/issues. You can
|
||||
also check the wiki at https://essentialsx.github.io/ to see if the
|
||||
feature was recently added.
|
||||
also check the changelogs to see if the feature was recently added:
|
||||
https://github.com/EssentialsX/Essentials/releases
|
||||
|
||||
4. Ask yourself: "Does this belong in EssentialsX?"
|
||||
There are lots of features that we reject because most servers won't
|
||||
need or use them. If your feature is very specific or already exists in
|
||||
another plugin, it might not be a good fit for EssentialsX.
|
||||
|
||||
5. Delete this line and all above lines before posting your issue! -->
|
||||
-->
|
||||
|
||||
### Feature request
|
||||
|
||||
**Feature description**
|
||||
<!-- What feature are you suggesting? -->
|
||||
**Feature description:**
|
||||
<!-- What feature are you suggesting? Type below this line. -->
|
||||
|
||||
**How the feature is useful**
|
||||
<!-- How is the feature useful to players, server owners and/or developers? -->
|
||||
**How the feature is useful:**
|
||||
<!--
|
||||
How is the feature useful to players, server owners and/or developers?
|
||||
Type below this block.
|
||||
-->
|
||||
@@ -0,0 +1,82 @@
|
||||
---
|
||||
name: Bug fix
|
||||
about: Use this if your PR fixes a bug in EssentialsX.
|
||||
labels: 'type: bugfix'
|
||||
---
|
||||
|
||||
<!-- EssentialsX bug fix submission guide
|
||||
|
||||
NOTE: Failure to fill out this template properly may result in your PR being
|
||||
delayed or ignored without warning.
|
||||
|
||||
Don't type between any arrows in the template, as this text will be hidden.
|
||||
This includes this header block and any other explanatory text blocks.
|
||||
|
||||
Want to discuss your PR before submitting it? Join the EssentialsX Development
|
||||
server: https://discord.gg/CUN7qVb
|
||||
|
||||
By contributing to EssentialsX, you agree to license your code under the
|
||||
GNU General Public License version 3, which can be found at the link below:
|
||||
https://github.com/EssentialsX/Essentials/blob/2.x/LICENSE
|
||||
|
||||
If you are submitting a bug fix, please follow the following steps:
|
||||
|
||||
1. Fill out the template in full.
|
||||
This includes providing screenshots and a link to the original bug
|
||||
report. If there isn't an existing bug report, we recommend opening a new
|
||||
detailed bug report BEFORE opening your PR to fix it, else your PR may be
|
||||
delayed or rejected without warning.
|
||||
|
||||
You can open a new bug report by following this link:
|
||||
https://github.com/EssentialsX/Essentials/issues/new/choose
|
||||
|
||||
2. When linking logs or config files, do not attach them to the post!
|
||||
Copy and paste any logs into https://gist.github.com/, then paste a
|
||||
link to them in the relevant parts of the template. Do not use Hastebin
|
||||
or Pastebin, as this can cause issues with future reviews.
|
||||
**DO NOT drag logs into this text box!**
|
||||
|
||||
3. If you are fixing a performance issue, please include a link to a
|
||||
Timings and/or profiler report, both before and after your PR.
|
||||
|
||||
4. If you are fixing a visual bug, such as in commands, please include
|
||||
screenshots so that we can more easily review the proposed fix.
|
||||
(You may drag screenshots directly into this box.)
|
||||
|
||||
-->
|
||||
|
||||
### Information
|
||||
|
||||
<!--
|
||||
Replace #nnnn with the number of the original issue. If this PR fixes
|
||||
multiple issues, you should repeat the phrase "fixes #nnnn" for each issue.
|
||||
-->
|
||||
|
||||
This PR fixes #nnnn.
|
||||
|
||||
### Details
|
||||
|
||||
**Proposed fix:**
|
||||
<!-- Type a description of your proposed fix below this line. -->
|
||||
|
||||
|
||||
**Environments tested:**
|
||||
<!--
|
||||
Below this line, put an "x" inside the box for the environments you have
|
||||
tested this bug fix on, and if relevant alter the OS and Java version
|
||||
accordingly. If this feature does not apply to an environment, strike
|
||||
through the environment using ~~strikethrough~~. If you have tested on
|
||||
other environments, add a new line with relevant details.
|
||||
-->
|
||||
|
||||
- [ ] [Latest](https://papermc.io/downloads) Paper Version (any OS, any Java 8+ version)
|
||||
- [ ] CraftBukkit/Spigot/Paper 1.12.2 (any OS, any Java 8+ version)
|
||||
- [ ] CraftBukkit 1.8.8 (any OS, any Java 8+ version)
|
||||
|
||||
|
||||
**Demonstration:**
|
||||
<!--
|
||||
Below this block, include screenshots/log snippets from before and after as
|
||||
necessary. If you have created or used a test case plugin, please link to a
|
||||
download of the plugin, source code and exact version used where possible.
|
||||
-->
|
||||
@@ -0,0 +1,8 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: MOSS Discord Server
|
||||
url: https://discord.gg/casfFyh
|
||||
about: Need help with using EssentialsX? Join the MOSS Discord server for help.
|
||||
- name: EssentialsX Development Discord Server
|
||||
url: https://discord.gg/CUN7qVb
|
||||
about: Got questions or want to discuss changes before opening your PR? Join the EssentialsX Development Discord server. (Need help? Join MOSS instead.)
|
||||
@@ -0,0 +1,82 @@
|
||||
---
|
||||
name: Feature addition
|
||||
about: Use this if your PR adds a new feature to EssentialsX.
|
||||
labels: 'type: enhancement'
|
||||
---
|
||||
|
||||
<!-- EssentialsX feature submission guide
|
||||
|
||||
NOTE: Failure to fill out this template properly may result in your PR being
|
||||
delayed or ignored without warning.
|
||||
|
||||
Don't type between any arrows in the template, as this text will be hidden.
|
||||
This includes this header block and any other explanatory text blocks.
|
||||
|
||||
Want to discuss your PR before submitting it? Join the EssentialsX Development
|
||||
server: https://discord.gg/CUN7qVb
|
||||
|
||||
By contributing to EssentialsX, you agree to license your code under the
|
||||
GNU General Public License version 3, which can be found at the link below:
|
||||
https://github.com/EssentialsX/Essentials/blob/2.x/LICENSE
|
||||
|
||||
If you are submitting a new feature, please follow the following steps:
|
||||
|
||||
1. Fill out the template in full.
|
||||
This includes providing screenshots and a link to the original feature
|
||||
request. If there isn't an existing feature request, we strongly
|
||||
recommend opening a new feature request BEFORE opening your PR to
|
||||
implement it, as this allows us to review whether we're likely to accept
|
||||
your feature in advance, and also allows us to discuss possible
|
||||
implementations for the feature. If there is no associated feature
|
||||
request, your PR may be delayed or rejected without warning.
|
||||
|
||||
You can open a new feature request by following this link:
|
||||
https://github.com/EssentialsX/Essentials/issues/new/choose
|
||||
|
||||
2. If you are fixing a performance issue, please use the "Bug fix" PR template
|
||||
instead. The "bug fix" template is better suited to performance issues.
|
||||
|
||||
3. Include a demonstration.
|
||||
If you are adding commands, please provide screenshots and/or a video
|
||||
demonstration of the feature. Similarly, if you are adding a new API,
|
||||
please include a link to example code that takes advantage of your
|
||||
proposed API. This will aid us in reviewing PRs and speed up the process
|
||||
significantly.
|
||||
|
||||
-->
|
||||
|
||||
### Information
|
||||
|
||||
<!--
|
||||
Replace #nnnn with the number of the original issue. If this PR implements
|
||||
features from multiple issues, you should repeat the phrase "closes #nnnn"
|
||||
for each issue.
|
||||
-->
|
||||
|
||||
This PR closes #nnnn.
|
||||
|
||||
### Details
|
||||
|
||||
**Proposed feature**
|
||||
<!-- Type a description of your proposed feature below this line. -->
|
||||
|
||||
**Environments tested:**
|
||||
<!--
|
||||
Below this block, put an "x" inside the box for the environments you have
|
||||
tested this bug fix on, and if relevant alter the OS and Java version
|
||||
accordingly. If this feature does not apply to an environment, strike
|
||||
through the environment using ~~strikethrough~~. If you have tested on
|
||||
other environments, add a new line with relevant details.
|
||||
-->
|
||||
|
||||
- [ ] [Latest](https://papermc.io/downloads) Paper Version (any OS, any Java 8+ version)
|
||||
- [ ] CraftBukkit/Spigot/Paper 1.12.2 (any OS, any Java 8+ version)
|
||||
- [ ] CraftBukkit 1.8.8 (any OS, any Java 8+ version)
|
||||
|
||||
**Demonstration:**
|
||||
<!--
|
||||
Below this block, include screenshots/code snippets from before and after
|
||||
as necessary. If you have created or used a test case plugin, please link
|
||||
to a download of the plugin, source code and exact version used where
|
||||
possible.
|
||||
-->
|
||||
@@ -0,0 +1,38 @@
|
||||
name: Build EssentialsX
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 2.x
|
||||
- mc/*
|
||||
pull_request:
|
||||
branches:
|
||||
- 2.x
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout Git repo
|
||||
uses: actions/checkout@v1
|
||||
- name: Restore Maven cache
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-
|
||||
- name: Set up JDK 1.8
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.8
|
||||
- name: Build with Maven
|
||||
run: mvn package verify --file pom.xml
|
||||
- name: Copy artifacts
|
||||
run: mkdir -p ./out/ && cp -t ./out/ **/target/Essentials*.jar
|
||||
- uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: Plugin jars
|
||||
path: out/
|
||||
+7
-3
@@ -1,11 +1,14 @@
|
||||
# IDE files
|
||||
# Other IDE files
|
||||
*.classpath
|
||||
*.project
|
||||
*.settings/
|
||||
.idea/
|
||||
.idea/*
|
||||
*.iml
|
||||
.DS_Store
|
||||
|
||||
# Checkstyle-IDEA config
|
||||
!.idea/checkstyle-idea.xml
|
||||
|
||||
# Essentials files
|
||||
/Essentials/userdata
|
||||
/Essentials/config.yml
|
||||
@@ -15,4 +18,5 @@
|
||||
|
||||
# Build files
|
||||
target/
|
||||
jars/
|
||||
jars/
|
||||
out/
|
||||
Generated
+19
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CheckStyle-IDEA">
|
||||
<option name="configuration">
|
||||
<map>
|
||||
<entry key="active-configuration" value="PROJECT_RELATIVE:$PROJECT_DIR$/.checkstyle/checkstyle.xml:EssentialsX" />
|
||||
<entry key="checkstyle-version" value="8.36.2" />
|
||||
<entry key="copy-libs" value="true" />
|
||||
<entry key="location-0" value="BUNDLED:(bundled):Sun Checks" />
|
||||
<entry key="location-1" value="BUNDLED:(bundled):Google Checks" />
|
||||
<entry key="location-2" value="PROJECT_RELATIVE:$PROJECT_DIR$/.checkstyle/checkstyle.xml:EssentialsX" />
|
||||
<entry key="property-2.checkstyle.suppressions.file" value=".checkstyle/suppressions.xml" />
|
||||
<entry key="scan-before-checkin" value="false" />
|
||||
<entry key="scanscope" value="JavaOnly" />
|
||||
<entry key="suppress-errors" value="false" />
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
language: java
|
||||
|
||||
jdk:
|
||||
- openjdk8
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- .buildtools
|
||||
- $HOME/.m2
|
||||
|
||||
before_install:
|
||||
- chmod +x scripts/buildtools.sh
|
||||
- scripts/buildtools.sh
|
||||
@@ -0,0 +1,31 @@
|
||||
Contributing to EssentialsX
|
||||
===========================
|
||||
|
||||
Want to help improve EssentialsX? There are several ways you can support and contribute to the project.
|
||||
|
||||
If you'd like to make a financial contribution to the project, you can join our [Patreon](https://www.patreon.com/essentialsx/),
|
||||
or to make a one-off donation you can visit our [Ko-fi page](https://ko-fi.com/essentialsx). If you can't make a
|
||||
donation, don't worry! There are lots of other ways to contribute:
|
||||
|
||||
* Do you run a server? Take a look at our ["help wanted"](https://github.com/EssentialsX/Essentials/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22help+wanted%22)
|
||||
and ["bug: unconfirmed"](https://github.com/EssentialsX/Essentials/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22bug%3A+unconfirmed%22)
|
||||
issues, where you can find issues that need extra testing and investigation.
|
||||
* Do you speak multiple languages? If so, we always welcome contributions to our [Crowdin project](https://crowdin.com/project/essentialsx-official).
|
||||
* Do you enjoy helping others? If so, why not contribute to the [EssentialsX documentation](https://github.com/EssentialsX/wiki)?
|
||||
You can also join the [MOSS Discord community](https://discord.gg/casfFyh) and provide direct community support to
|
||||
other EssentialsX users.
|
||||
* If you're a developer, you could look through our ["open to PR"](https://github.com/EssentialsX/Essentials/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22status%3A+open+to+PR%22)
|
||||
issues. We're always happy to receive bug fixes and feature additions as pull requests.
|
||||
|
||||
Submitting a PR
|
||||
---------------
|
||||
|
||||
EssentialsX has extensive templates for PRs that detail how to submit your PR. To find out more, see the PR templates for:
|
||||
* [Bug fixes](https://github.com/EssentialsX/Essentials/blob/2.x/.github/PULL_REQUEST_TEMPLATE/bug-fix.md)
|
||||
* [New features](https://github.com/EssentialsX/Essentials/blob/2.x/.github/PULL_REQUEST_TEMPLATE/new-feature.md)
|
||||
|
||||
Want to discuss a feature before opening a PR? Join the [EssentialsX Development Discord server](https://discord.gg/CUN7qVb). Note that this server is **not for end-users** - if you need support with EssentialsX, you should join [MOSS](https://discord.gg/casfFyh) instead.
|
||||
|
||||
By contributing to EssentialsX, you agree to license your code under the [GNU General Public License version 3](https://github.com/EssentialsX/Essentials/blob/2.x/LICENSE).
|
||||
|
||||
|
||||
+35
-35
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>EssentialsXParent</artifactId>
|
||||
<version>2.17-pre1</version>
|
||||
<version>2.18.2</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>EssentialsX</artifactId>
|
||||
@@ -49,69 +49,69 @@
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>net.milkbowl.vault</groupId>
|
||||
<groupId>com.github.milkbowl</groupId>
|
||||
<artifactId>VaultAPI</artifactId>
|
||||
<version>1.7</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.luckperms</groupId>
|
||||
<artifactId>api</artifactId>
|
||||
<version>5.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.papermc</groupId>
|
||||
<artifactId>paperlib</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.6-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>NMSProvider</artifactId>
|
||||
<version>2.17-pre1</version>
|
||||
<artifactId>BaseProviders</artifactId>
|
||||
<version>2.18.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>UpdatedMetaProvider</artifactId>
|
||||
<version>2.17-pre1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>1_8_R1Provider</artifactId>
|
||||
<version>2.17-pre1</version>
|
||||
<scope>compile</scope>
|
||||
<artifactId>NMSReflectionProvider</artifactId>
|
||||
<version>2.18.2</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>craftbukkit</artifactId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>1_8_R2Provider</artifactId>
|
||||
<version>2.17-pre1</version>
|
||||
<artifactId>PaperProvider</artifactId>
|
||||
<version>2.18.2</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.destroystokyo.paper</groupId>
|
||||
<artifactId>paper-api</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>1_8Provider</artifactId>
|
||||
<version>2.18.2</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>craftbukkit</artifactId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>LegacyProvider</artifactId>
|
||||
<version>2.17-pre1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>ReflectionProvider</artifactId>
|
||||
<version>2.17-pre1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>FlattenedProvider</artifactId>
|
||||
<version>2.17-pre1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -13,6 +13,6 @@ Minecraft colors:
|
||||
&8 &&8 &9 &&9 &a &&a &b &&b
|
||||
&c &&c &d &&d &e &&e &f &&f
|
||||
&0
|
||||
&&k &kMagic&r &&l &lBold
|
||||
&&m &mStrike&r &&n &nUline
|
||||
&&o &oItalic&r &&r &rReset
|
||||
&&k &kMagic&r &&l &lBold&r
|
||||
&&m &mStrike&r &&n &nUline&r
|
||||
&&o &oItalic&r &&r &rReset
|
||||
@@ -6,11 +6,15 @@ import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.command.PluginCommandYamlParser;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
||||
public class AlternativeCommandsHandler {
|
||||
private static final Logger LOGGER = Logger.getLogger("Essentials");
|
||||
private final transient Map<String, List<PluginCommand>> altcommands = new HashMap<>();
|
||||
@@ -19,7 +23,7 @@ public class AlternativeCommandsHandler {
|
||||
|
||||
public AlternativeCommandsHandler(final IEssentials ess) {
|
||||
this.ess = ess;
|
||||
for (Plugin plugin : ess.getServer().getPluginManager().getPlugins()) {
|
||||
for (final Plugin plugin : ess.getServer().getPluginManager().getPlugins()) {
|
||||
if (plugin.isEnabled()) {
|
||||
addPlugin(plugin);
|
||||
}
|
||||
@@ -33,7 +37,7 @@ public class AlternativeCommandsHandler {
|
||||
final List<Command> commands = PluginCommandYamlParser.parse(plugin);
|
||||
final String pluginName = plugin.getDescription().getName().toLowerCase(Locale.ENGLISH);
|
||||
|
||||
for (Command command : commands) {
|
||||
for (final Command command : commands) {
|
||||
final PluginCommand pc = (PluginCommand) command;
|
||||
final List<String> labels = new ArrayList<>(pc.getAliases());
|
||||
labels.add(pc.getName());
|
||||
@@ -45,16 +49,13 @@ public class AlternativeCommandsHandler {
|
||||
if (reg == null || !reg.getPlugin().equals(plugin)) {
|
||||
continue;
|
||||
}
|
||||
for (String label : labels) {
|
||||
List<PluginCommand> plugincommands = altcommands.get(label.toLowerCase(Locale.ENGLISH));
|
||||
if (plugincommands == null) {
|
||||
plugincommands = new ArrayList<>();
|
||||
altcommands.put(label.toLowerCase(Locale.ENGLISH), plugincommands);
|
||||
}
|
||||
for (final String label : labels) {
|
||||
final List<PluginCommand> plugincommands = altcommands.computeIfAbsent(label.toLowerCase(Locale.ENGLISH), k -> new ArrayList<>());
|
||||
boolean found = false;
|
||||
for (PluginCommand pc2 : plugincommands) {
|
||||
for (final PluginCommand pc2 : plugincommands) {
|
||||
if (pc2.getPlugin().equals(plugin)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
@@ -68,13 +69,7 @@ public class AlternativeCommandsHandler {
|
||||
final Iterator<Map.Entry<String, List<PluginCommand>>> iterator = altcommands.entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final Map.Entry<String, List<PluginCommand>> entry = iterator.next();
|
||||
final Iterator<PluginCommand> pcIterator = entry.getValue().iterator();
|
||||
while (pcIterator.hasNext()) {
|
||||
final PluginCommand pc = pcIterator.next();
|
||||
if (pc.getPlugin() == null || pc.getPlugin().equals(plugin)) {
|
||||
pcIterator.remove();
|
||||
}
|
||||
}
|
||||
entry.getValue().removeIf(pc -> pc.getPlugin() == null || pc.getPlugin().equals(plugin));
|
||||
if (entry.getValue().isEmpty()) {
|
||||
iterator.remove();
|
||||
}
|
||||
@@ -90,7 +85,7 @@ public class AlternativeCommandsHandler {
|
||||
return commands.get(0);
|
||||
}
|
||||
// return the first command that is not an alias
|
||||
for (PluginCommand command : commands) {
|
||||
for (final PluginCommand command : commands) {
|
||||
if (command.getName().equalsIgnoreCase(label)) {
|
||||
return command;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,455 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.api.IAsyncTeleport;
|
||||
import com.earth2me.essentials.commands.WarpNotFoundException;
|
||||
import com.earth2me.essentials.utils.DateUtil;
|
||||
import com.earth2me.essentials.utils.LocationUtil;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.IUser;
|
||||
import net.ess3.api.InvalidWorldException;
|
||||
import net.ess3.api.events.UserWarpEvent;
|
||||
import net.ess3.api.events.teleport.PreTeleportEvent;
|
||||
import net.ess3.api.events.teleport.TeleportWarmupEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerRespawnEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class AsyncTeleport implements IAsyncTeleport {
|
||||
private final IUser teleportOwner;
|
||||
private final IEssentials ess;
|
||||
private AsyncTimedTeleport timedTeleport;
|
||||
|
||||
private TeleportType tpType;
|
||||
|
||||
public AsyncTeleport(final IUser user, final IEssentials ess) {
|
||||
this.teleportOwner = user;
|
||||
this.ess = ess;
|
||||
tpType = TeleportType.NORMAL;
|
||||
}
|
||||
|
||||
public void cooldown(final boolean check) throws Throwable {
|
||||
final CompletableFuture<Boolean> exceptionFuture = new CompletableFuture<>();
|
||||
if (cooldown(check, exceptionFuture)) {
|
||||
try {
|
||||
exceptionFuture.get();
|
||||
} catch (final ExecutionException e) {
|
||||
throw e.getCause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean cooldown(final boolean check, final CompletableFuture<Boolean> future) {
|
||||
final Calendar time = new GregorianCalendar();
|
||||
if (teleportOwner.getLastTeleportTimestamp() > 0) {
|
||||
// Take the current time, and remove the delay from it.
|
||||
final double cooldown = ess.getSettings().getTeleportCooldown();
|
||||
final Calendar earliestTime = new GregorianCalendar();
|
||||
earliestTime.add(Calendar.SECOND, -(int) cooldown);
|
||||
earliestTime.add(Calendar.MILLISECOND, -(int) ((cooldown * 1000.0) % 1000.0));
|
||||
// This value contains the most recent time a teleportPlayer could have been used that would allow another use.
|
||||
final long earliestLong = earliestTime.getTimeInMillis();
|
||||
|
||||
// When was the last teleportPlayer used?
|
||||
final long lastTime = teleportOwner.getLastTeleportTimestamp();
|
||||
|
||||
if (lastTime > time.getTimeInMillis()) {
|
||||
// This is to make sure time didn't get messed up on last teleportPlayer use.
|
||||
// If this happens, let's give the user the benifit of the doubt.
|
||||
teleportOwner.setLastTeleportTimestamp(time.getTimeInMillis());
|
||||
return false;
|
||||
} else if (lastTime > earliestLong
|
||||
&& cooldownApplies()) {
|
||||
time.setTimeInMillis(lastTime);
|
||||
time.add(Calendar.SECOND, (int) cooldown);
|
||||
time.add(Calendar.MILLISECOND, (int) ((cooldown * 1000.0) % 1000.0));
|
||||
future.completeExceptionally(new Exception(tl("timeBeforeTeleport", DateUtil.formatDateDiff(time.getTimeInMillis()))));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// if justCheck is set, don't update lastTeleport; we're just checking
|
||||
if (!check) {
|
||||
teleportOwner.setLastTeleportTimestamp(time.getTimeInMillis());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean cooldownApplies() {
|
||||
boolean applies = true;
|
||||
final String globalBypassPerm = "essentials.teleport.cooldown.bypass";
|
||||
switch (tpType) {
|
||||
case NORMAL:
|
||||
applies = !teleportOwner.isAuthorized(globalBypassPerm);
|
||||
break;
|
||||
case BACK:
|
||||
applies = !(teleportOwner.isAuthorized(globalBypassPerm) &&
|
||||
teleportOwner.isAuthorized("essentials.teleport.cooldown.bypass.back"));
|
||||
break;
|
||||
case TPA:
|
||||
applies = !(teleportOwner.isAuthorized(globalBypassPerm) &&
|
||||
teleportOwner.isAuthorized("essentials.teleport.cooldown.bypass.tpa"));
|
||||
break;
|
||||
}
|
||||
return applies;
|
||||
}
|
||||
|
||||
private void warnUser(final IUser user, final double delay) {
|
||||
final Calendar c = new GregorianCalendar();
|
||||
c.add(Calendar.SECOND, (int) delay);
|
||||
c.add(Calendar.MILLISECOND, (int) ((delay * 1000.0) % 1000.0));
|
||||
user.sendMessage(tl("dontMoveMessage", DateUtil.formatDateDiff(c.getTimeInMillis())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void now(final Location loc, final boolean cooldown, final TeleportCause cause, final CompletableFuture<Boolean> future) {
|
||||
if (cooldown && cooldown(false, future)) {
|
||||
return;
|
||||
}
|
||||
final ITarget target = new LocationTarget(loc);
|
||||
nowAsync(teleportOwner, target, cause, future);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void now(final Player entity, final boolean cooldown, final TeleportCause cause, final CompletableFuture<Boolean> future) {
|
||||
if (cooldown && cooldown(false, future)) {
|
||||
future.complete(false);
|
||||
return;
|
||||
}
|
||||
final ITarget target = new PlayerTarget(entity);
|
||||
nowAsync(teleportOwner, target, cause, future);
|
||||
future.thenAccept(success -> {
|
||||
if (success) {
|
||||
teleportOwner.sendMessage(tl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void runOnMain(final Runnable runnable) throws ExecutionException, InterruptedException {
|
||||
if (Bukkit.isPrimaryThread()) {
|
||||
runnable.run();
|
||||
return;
|
||||
}
|
||||
final CompletableFuture<Object> taskLock = new CompletableFuture<>();
|
||||
Bukkit.getScheduler().runTask(ess, () -> {
|
||||
runnable.run();
|
||||
taskLock.complete(new Object());
|
||||
});
|
||||
taskLock.get();
|
||||
}
|
||||
|
||||
protected void nowAsync(final IUser teleportee, final ITarget target, final TeleportCause cause, final CompletableFuture<Boolean> future) {
|
||||
cancel(false);
|
||||
|
||||
final PreTeleportEvent event = new PreTeleportEvent(teleportee, cause, target);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
teleportee.setLastLocation();
|
||||
|
||||
if (!ess.getSettings().isForcePassengerTeleport() && !teleportee.getBase().isEmpty()) {
|
||||
if (!ess.getSettings().isTeleportPassengerDismount()) {
|
||||
future.completeExceptionally(new Exception(tl("passengerTeleportFail")));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
runOnMain(() -> teleportee.getBase().eject()); //EntityDismountEvent requires a sync context.
|
||||
} catch (final ExecutionException | InterruptedException e) {
|
||||
future.completeExceptionally(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
teleportee.setLastLocation();
|
||||
final Location targetLoc = target.getLocation();
|
||||
if (ess.getSettings().isTeleportSafetyEnabled() && LocationUtil.isBlockOutsideWorldBorder(targetLoc.getWorld(), targetLoc.getBlockX(), targetLoc.getBlockZ())) {
|
||||
targetLoc.setX(LocationUtil.getXInsideWorldBorder(targetLoc.getWorld(), targetLoc.getBlockX()));
|
||||
targetLoc.setZ(LocationUtil.getZInsideWorldBorder(targetLoc.getWorld(), targetLoc.getBlockZ()));
|
||||
}
|
||||
PaperLib.getChunkAtAsync(targetLoc).thenAccept(chunk -> {
|
||||
Location loc = targetLoc;
|
||||
if (LocationUtil.isBlockUnsafeForUser(teleportee, chunk.getWorld(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())) {
|
||||
if (ess.getSettings().isTeleportSafetyEnabled()) {
|
||||
if (ess.getSettings().isForceDisableTeleportSafety()) {
|
||||
//The chunk we're teleporting to is 100% going to be loaded here, no need to teleport async.
|
||||
teleportee.getBase().teleport(loc, cause);
|
||||
} else {
|
||||
try {
|
||||
//There's a chance the safer location is outside the loaded chunk so still teleport async here.
|
||||
PaperLib.teleportAsync(teleportee.getBase(), LocationUtil.getSafeDestination(ess, teleportee, loc), cause);
|
||||
} catch (final Exception e) {
|
||||
future.completeExceptionally(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
future.completeExceptionally(new Exception(tl("unsafeTeleportDestination", loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (ess.getSettings().isForceDisableTeleportSafety()) {
|
||||
//The chunk we're teleporting to is 100% going to be loaded here, no need to teleport async.
|
||||
teleportee.getBase().teleport(loc, cause);
|
||||
} else {
|
||||
if (ess.getSettings().isTeleportToCenterLocation()) {
|
||||
loc = LocationUtil.getRoundedDestination(loc);
|
||||
}
|
||||
//There's a *small* chance the rounded destination produces a location outside the loaded chunk so still teleport async here.
|
||||
PaperLib.teleportAsync(teleportee.getBase(), loc, cause);
|
||||
}
|
||||
}
|
||||
future.complete(true);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teleport(final Location loc, final Trade chargeFor, final TeleportCause cause, final CompletableFuture<Boolean> future) {
|
||||
teleport(teleportOwner, new LocationTarget(loc), chargeFor, cause, future);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teleport(final Player entity, final Trade chargeFor, final TeleportCause cause, final CompletableFuture<Boolean> future) {
|
||||
teleportOwner.sendMessage(tl("teleportToPlayer", entity.getDisplayName()));
|
||||
teleport(teleportOwner, new PlayerTarget(entity), chargeFor, cause, future);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teleportPlayer(final IUser otherUser, final Location loc, final Trade chargeFor, final TeleportCause cause, final CompletableFuture<Boolean> future) {
|
||||
teleport(otherUser, new LocationTarget(loc), chargeFor, cause, future);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teleportPlayer(final IUser otherUser, final Player entity, final Trade chargeFor, final TeleportCause cause, final CompletableFuture<Boolean> future) {
|
||||
final ITarget target = new PlayerTarget(entity);
|
||||
teleport(otherUser, target, chargeFor, cause, future);
|
||||
future.thenAccept(success -> {
|
||||
if (success) {
|
||||
otherUser.sendMessage(tl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ()));
|
||||
teleportOwner.sendMessage(tl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void teleport(final IUser teleportee, final ITarget target, final Trade chargeFor, final TeleportCause cause, final CompletableFuture<Boolean> future) {
|
||||
double delay = ess.getSettings().getTeleportDelay();
|
||||
|
||||
final TeleportWarmupEvent event = new TeleportWarmupEvent(teleportee, cause, target, delay);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
delay = event.getDelay();
|
||||
|
||||
Trade cashCharge = chargeFor;
|
||||
|
||||
if (chargeFor != null) {
|
||||
chargeFor.isAffordableFor(teleportOwner, future);
|
||||
if (future.isCompletedExceptionally()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//This code is to make sure that commandcosts are checked in the initial world, and not in the resulting world.
|
||||
if (!chargeFor.getCommandCost(teleportOwner).equals(BigDecimal.ZERO)) {
|
||||
//By converting a command cost to a regular cost, the command cost permission isn't checked when executing the charge after teleport.
|
||||
cashCharge = new Trade(chargeFor.getCommandCost(teleportOwner), ess);
|
||||
}
|
||||
}
|
||||
|
||||
if (cooldown(true, future)) {
|
||||
return;
|
||||
}
|
||||
if (delay <= 0 || teleportOwner.isAuthorized("essentials.teleport.timer.bypass") || teleportee.isAuthorized("essentials.teleport.timer.bypass")) {
|
||||
if (cooldown(false, future)) {
|
||||
return;
|
||||
}
|
||||
nowAsync(teleportee, target, cause, future);
|
||||
if (cashCharge != null) {
|
||||
cashCharge.charge(teleportOwner, future);
|
||||
if (future.isCompletedExceptionally()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
cancel(false);
|
||||
warnUser(teleportee, delay);
|
||||
initTimer((long) (delay * 1000.0), teleportee, target, cashCharge, cause, false);
|
||||
}
|
||||
|
||||
private void teleportOther(final IUser teleporter, final IUser teleportee, final ITarget target, final Trade chargeFor, final TeleportCause cause, final CompletableFuture<Boolean> future) {
|
||||
double delay = ess.getSettings().getTeleportDelay();
|
||||
|
||||
final TeleportWarmupEvent event = new TeleportWarmupEvent(teleportee, cause, target, delay);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
delay = event.getDelay();
|
||||
|
||||
Trade cashCharge = chargeFor;
|
||||
|
||||
if (teleporter != null && chargeFor != null) {
|
||||
chargeFor.isAffordableFor(teleporter, future);
|
||||
if (future.isCompletedExceptionally()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//This code is to make sure that commandcosts are checked in the initial world, and not in the resulting world.
|
||||
if (!chargeFor.getCommandCost(teleporter).equals(BigDecimal.ZERO)) {
|
||||
//By converting a command cost to a regular cost, the command cost permission isn't checked when executing the charge after teleport.
|
||||
cashCharge = new Trade(chargeFor.getCommandCost(teleporter), ess);
|
||||
}
|
||||
}
|
||||
|
||||
if (cooldown(true, future)) {
|
||||
return;
|
||||
}
|
||||
if (delay <= 0 || teleporter == null
|
||||
|| teleporter.isAuthorized("essentials.teleport.timer.bypass")
|
||||
|| teleportOwner.isAuthorized("essentials.teleport.timer.bypass")
|
||||
|| teleportee.isAuthorized("essentials.teleport.timer.bypass")) {
|
||||
if (cooldown(false, future)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nowAsync(teleportee, target, cause, future);
|
||||
if (teleporter != null && cashCharge != null) {
|
||||
cashCharge.charge(teleporter, future);
|
||||
if (future.isCompletedExceptionally()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
cancel(false);
|
||||
warnUser(teleportee, delay);
|
||||
initTimer((long) (delay * 1000.0), teleportee, target, cashCharge, cause, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void respawn(final Trade chargeFor, final TeleportCause cause, final CompletableFuture<Boolean> future) {
|
||||
double delay = ess.getSettings().getTeleportDelay();
|
||||
|
||||
final TeleportWarmupEvent event = new TeleportWarmupEvent(teleportOwner, cause, null, delay);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
delay = event.getDelay();
|
||||
|
||||
if (chargeFor != null) {
|
||||
chargeFor.isAffordableFor(teleportOwner, future);
|
||||
if (future.isCompletedExceptionally()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (cooldown(true, future)) {
|
||||
return;
|
||||
}
|
||||
if (delay <= 0 || teleportOwner.isAuthorized("essentials.teleport.timer.bypass")) {
|
||||
if (cooldown(false, future)) {
|
||||
return;
|
||||
}
|
||||
respawnNow(teleportOwner, cause, future);
|
||||
if (chargeFor != null) {
|
||||
chargeFor.charge(teleportOwner, future);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
cancel(false);
|
||||
warnUser(teleportOwner, delay);
|
||||
initTimer((long) (delay * 1000.0), teleportOwner, null, chargeFor, cause, true);
|
||||
}
|
||||
|
||||
void respawnNow(final IUser teleportee, final TeleportCause cause, final CompletableFuture<Boolean> future) {
|
||||
final Player player = teleportee.getBase();
|
||||
PaperLib.getBedSpawnLocationAsync(player, true).thenAccept(location -> {
|
||||
if (location != null) {
|
||||
nowAsync(teleportee, new LocationTarget(location), cause, future);
|
||||
} else {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().info("Could not find bed spawn, forcing respawn event.");
|
||||
}
|
||||
final PlayerRespawnEvent pre = new PlayerRespawnEvent(player, player.getWorld().getSpawnLocation(), false);
|
||||
ess.getServer().getPluginManager().callEvent(pre);
|
||||
nowAsync(teleportee, new LocationTarget(pre.getRespawnLocation()), cause, future);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warp(final IUser otherUser, String warp, final Trade chargeFor, final TeleportCause cause, final CompletableFuture<Boolean> future) {
|
||||
final UserWarpEvent event = new UserWarpEvent(otherUser, warp, chargeFor);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
warp = event.getWarp();
|
||||
final Location loc;
|
||||
try {
|
||||
loc = ess.getWarps().getWarp(warp);
|
||||
} catch (final WarpNotFoundException | InvalidWorldException e) {
|
||||
future.completeExceptionally(e);
|
||||
return;
|
||||
}
|
||||
otherUser.sendMessage(tl("warpingTo", warp, loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
|
||||
if (!otherUser.equals(teleportOwner)) {
|
||||
teleportOwner.sendMessage(tl("warpingTo", warp, loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
|
||||
}
|
||||
teleport(otherUser, new LocationTarget(loc), chargeFor, cause, future);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void back(final Trade chargeFor, final CompletableFuture<Boolean> future) {
|
||||
back(teleportOwner, chargeFor, future);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void back(final IUser teleporter, final Trade chargeFor, final CompletableFuture<Boolean> future) {
|
||||
tpType = TeleportType.BACK;
|
||||
final Location loc = teleportOwner.getLastLocation();
|
||||
teleportOwner.sendMessage(tl("backUsageMsg", loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
|
||||
teleportOther(teleporter, teleportOwner, new LocationTarget(loc), chargeFor, TeleportCause.COMMAND, future);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void back(final CompletableFuture<Boolean> future) {
|
||||
nowAsync(teleportOwner, new LocationTarget(teleportOwner.getLastLocation()), TeleportCause.COMMAND, future);
|
||||
}
|
||||
|
||||
public void setTpType(final TeleportType tpType) {
|
||||
this.tpType = tpType;
|
||||
}
|
||||
|
||||
//If we need to cancelTimer a pending teleportPlayer call this method
|
||||
private void cancel(final boolean notifyUser) {
|
||||
if (timedTeleport != null) {
|
||||
timedTeleport.cancelTimer(notifyUser);
|
||||
timedTeleport = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void initTimer(final long delay, final IUser teleportUser, final ITarget target, final Trade chargeFor, final TeleportCause cause, final boolean respawn) {
|
||||
timedTeleport = new AsyncTimedTeleport(teleportOwner, ess, this, delay, teleportUser, target, chargeFor, cause, respawn);
|
||||
}
|
||||
|
||||
public enum TeleportType {
|
||||
TPA,
|
||||
BACK,
|
||||
NORMAL
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.IUser;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class AsyncTimedTeleport implements Runnable {
|
||||
private static final double MOVE_CONSTANT = 0.3;
|
||||
private final IUser teleportOwner;
|
||||
private final IEssentials ess;
|
||||
private final AsyncTeleport teleport;
|
||||
private final UUID timer_teleportee;
|
||||
private final long timer_started; // time this task was initiated
|
||||
private final long timer_delay; // how long to delay the teleportPlayer
|
||||
// note that I initially stored a clone of the location for reference, but...
|
||||
// when comparing locations, I got incorrect mismatches (rounding errors, looked like)
|
||||
// so, the X/Y/Z values are stored instead and rounded off
|
||||
private final long timer_initX;
|
||||
private final long timer_initY;
|
||||
private final long timer_initZ;
|
||||
private final ITarget timer_teleportTarget;
|
||||
private final boolean timer_respawn;
|
||||
private final boolean timer_canMove;
|
||||
private final Trade timer_chargeFor;
|
||||
private final TeleportCause timer_cause;
|
||||
private int timer_task;
|
||||
private double timer_health;
|
||||
|
||||
AsyncTimedTeleport(final IUser user, final IEssentials ess, final AsyncTeleport teleport, final long delay, final IUser teleportUser, final ITarget target, final Trade chargeFor, final TeleportCause cause, final boolean respawn) {
|
||||
this.teleportOwner = user;
|
||||
this.ess = ess;
|
||||
this.teleport = teleport;
|
||||
this.timer_started = System.currentTimeMillis();
|
||||
this.timer_delay = delay;
|
||||
this.timer_health = teleportUser.getBase().getHealth();
|
||||
this.timer_initX = Math.round(teleportUser.getBase().getLocation().getX() * MOVE_CONSTANT);
|
||||
this.timer_initY = Math.round(teleportUser.getBase().getLocation().getY() * MOVE_CONSTANT);
|
||||
this.timer_initZ = Math.round(teleportUser.getBase().getLocation().getZ() * MOVE_CONSTANT);
|
||||
this.timer_teleportee = teleportUser.getBase().getUniqueId();
|
||||
this.timer_teleportTarget = target;
|
||||
this.timer_chargeFor = chargeFor;
|
||||
this.timer_cause = cause;
|
||||
this.timer_respawn = respawn;
|
||||
this.timer_canMove = user.isAuthorized("essentials.teleport.timer.move");
|
||||
|
||||
timer_task = ess.runTaskTimerAsynchronously(this, 20, 20).getTaskId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
if (teleportOwner == null || !teleportOwner.getBase().isOnline() || teleportOwner.getBase().getLocation() == null) {
|
||||
cancelTimer(false);
|
||||
return;
|
||||
}
|
||||
|
||||
final IUser teleportUser = ess.getUser(this.timer_teleportee);
|
||||
|
||||
if (teleportUser == null || !teleportUser.getBase().isOnline()) {
|
||||
cancelTimer(false);
|
||||
return;
|
||||
}
|
||||
|
||||
final Location currLocation = teleportUser.getBase().getLocation();
|
||||
if (currLocation == null) {
|
||||
cancelTimer(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!timer_canMove && (Math.round(currLocation.getX() * MOVE_CONSTANT) != timer_initX || Math.round(currLocation.getY() * MOVE_CONSTANT) != timer_initY || Math.round(currLocation.getZ() * MOVE_CONSTANT) != timer_initZ || teleportUser.getBase().getHealth() < timer_health)) {
|
||||
// user moved, cancelTimer teleportPlayer
|
||||
cancelTimer(true);
|
||||
return;
|
||||
}
|
||||
|
||||
class DelayedTeleportTask implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
timer_health = teleportUser.getBase().getHealth(); // in case user healed, then later gets injured
|
||||
final long now = System.currentTimeMillis();
|
||||
if (now > timer_started + timer_delay) {
|
||||
try {
|
||||
teleport.cooldown(false);
|
||||
} catch (final Throwable ex) {
|
||||
teleportOwner.sendMessage(tl("cooldownWithMessage", ex.getMessage()));
|
||||
if (teleportOwner != teleportUser) {
|
||||
teleportUser.sendMessage(tl("cooldownWithMessage", ex.getMessage()));
|
||||
}
|
||||
}
|
||||
try {
|
||||
cancelTimer(false);
|
||||
teleportUser.sendMessage(tl("teleportationCommencing"));
|
||||
|
||||
final CompletableFuture<Boolean> future = new CompletableFuture<>();
|
||||
future.exceptionally(e -> {
|
||||
ess.showError(teleportOwner.getSource(), e, "\\ teleport");
|
||||
return false;
|
||||
});
|
||||
if (timer_chargeFor != null) {
|
||||
timer_chargeFor.isAffordableFor(teleportOwner);
|
||||
}
|
||||
if (timer_respawn) {
|
||||
teleport.respawnNow(teleportUser, timer_cause, future);
|
||||
} else {
|
||||
teleport.nowAsync(teleportUser, timer_teleportTarget, timer_cause, future);
|
||||
}
|
||||
future.thenAccept(success -> {
|
||||
if (timer_chargeFor != null) {
|
||||
try {
|
||||
timer_chargeFor.charge(teleportOwner);
|
||||
} catch (final ChargeException ex) {
|
||||
ess.showError(teleportOwner.getSource(), ex, "\\ teleport");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
} catch (final Exception ex) {
|
||||
ess.showError(teleportOwner.getSource(), ex, "\\ teleport");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ess.scheduleSyncDelayedTask(new DelayedTeleportTask());
|
||||
}
|
||||
|
||||
//If we need to cancelTimer a pending teleportPlayer call this method
|
||||
void cancelTimer(final boolean notifyUser) {
|
||||
if (timer_task == -1) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
ess.getServer().getScheduler().cancelTask(timer_task);
|
||||
if (notifyUser) {
|
||||
teleportOwner.sendMessage(tl("pendingTeleportCancelled"));
|
||||
if (timer_teleportee != null && !timer_teleportee.equals(teleportOwner.getBase().getUniqueId())) {
|
||||
ess.getUser(timer_teleportee).sendMessage(tl("pendingTeleportCancelled"));
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
timer_task = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,30 +7,28 @@ import org.bukkit.command.CommandSender;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Backup implements Runnable {
|
||||
private static final Logger LOGGER = Logger.getLogger("Essentials");
|
||||
private transient final Server server;
|
||||
private transient final IEssentials ess;
|
||||
private final AtomicBoolean pendingShutdown = new AtomicBoolean(false);
|
||||
private transient boolean running = false;
|
||||
private transient int taskId = -1;
|
||||
private transient boolean active = false;
|
||||
private transient CompletableFuture<Object> taskLock = null;
|
||||
|
||||
public Backup(final IEssentials ess) {
|
||||
this.ess = ess;
|
||||
server = ess.getServer();
|
||||
if (!ess.getOnlinePlayers().isEmpty()) {
|
||||
ess.runTaskAsynchronously(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
startTask();
|
||||
}
|
||||
});
|
||||
if (!ess.getOnlinePlayers().isEmpty() || ess.getSettings().isAlwaysRunBackup()) {
|
||||
ess.runTaskAsynchronously(this::startTask);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,20 +55,30 @@ public class Backup implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
public CompletableFuture<Object> getTaskLock() {
|
||||
return taskLock;
|
||||
}
|
||||
|
||||
public void setPendingShutdown(final boolean shutdown) {
|
||||
pendingShutdown.set(shutdown);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (active) {
|
||||
return;
|
||||
}
|
||||
active = true;
|
||||
final String command = ess.getSettings().getBackupCommand();
|
||||
if (command == null || "".equals(command)) {
|
||||
return;
|
||||
}
|
||||
active = true;
|
||||
taskLock = new CompletableFuture<>();
|
||||
if ("save-all".equalsIgnoreCase(command)) {
|
||||
final CommandSender cs = server.getConsoleSender();
|
||||
server.dispatchCommand(cs, "save-all");
|
||||
active = false;
|
||||
taskLock.complete(new Object());
|
||||
return;
|
||||
}
|
||||
LOGGER.log(Level.INFO, tl("backupStarted"));
|
||||
@@ -78,52 +86,45 @@ public class Backup implements Runnable {
|
||||
server.dispatchCommand(cs, "save-all");
|
||||
server.dispatchCommand(cs, "save-off");
|
||||
|
||||
ess.runTaskAsynchronously(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
final ProcessBuilder childBuilder = new ProcessBuilder(command);
|
||||
childBuilder.redirectErrorStream(true);
|
||||
childBuilder.directory(ess.getDataFolder().getParentFile().getParentFile());
|
||||
final Process child = childBuilder.start();
|
||||
ess.runTaskAsynchronously(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
final BufferedReader reader = new BufferedReader(new InputStreamReader(child.getInputStream()));
|
||||
try {
|
||||
String line;
|
||||
do {
|
||||
line = reader.readLine();
|
||||
if (line != null) {
|
||||
LOGGER.log(Level.INFO, line);
|
||||
}
|
||||
} while (line != null);
|
||||
} finally {
|
||||
reader.close();
|
||||
ess.runTaskAsynchronously(() -> {
|
||||
try {
|
||||
final ProcessBuilder childBuilder = new ProcessBuilder(command.split(" "));
|
||||
childBuilder.redirectErrorStream(true);
|
||||
childBuilder.directory(ess.getDataFolder().getParentFile().getParentFile());
|
||||
final Process child = childBuilder.start();
|
||||
ess.runTaskAsynchronously(() -> {
|
||||
try {
|
||||
try (final BufferedReader reader = new BufferedReader(new InputStreamReader(child.getInputStream()))) {
|
||||
String line;
|
||||
do {
|
||||
line = reader.readLine();
|
||||
if (line != null) {
|
||||
LOGGER.log(Level.INFO, line);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
});
|
||||
child.waitFor();
|
||||
} catch (InterruptedException ex) {
|
||||
LOGGER.log(Level.SEVERE, null, ex);
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, null, ex);
|
||||
} finally {
|
||||
class BackupEnableSaveTask implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
server.dispatchCommand(cs, "save-on");
|
||||
if (ess.getOnlinePlayers().isEmpty()) {
|
||||
stopTask();
|
||||
}
|
||||
active = false;
|
||||
LOGGER.log(Level.INFO, tl("backupFinished"));
|
||||
} while (line != null);
|
||||
}
|
||||
} catch (final IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, null, ex);
|
||||
}
|
||||
});
|
||||
child.waitFor();
|
||||
} catch (final InterruptedException | IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, null, ex);
|
||||
} finally {
|
||||
class BackupEnableSaveTask implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
server.dispatchCommand(cs, "save-on");
|
||||
if (!ess.getSettings().isAlwaysRunBackup() && ess.getOnlinePlayers().isEmpty()) {
|
||||
stopTask();
|
||||
}
|
||||
active = false;
|
||||
taskLock.complete(new Object());
|
||||
LOGGER.log(Level.INFO, tl("backupFinished"));
|
||||
}
|
||||
}
|
||||
|
||||
if (!pendingShutdown.get()) {
|
||||
ess.scheduleSyncDelayedTask(new BackupEnableSaveTask());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
|
||||
public class ChargeException extends Exception {
|
||||
public ChargeException(final String message) {
|
||||
super(message);
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.earth2me.essentials;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
|
||||
public class CommandSource {
|
||||
protected CommandSender sender;
|
||||
|
||||
@@ -22,18 +21,36 @@ public class CommandSource {
|
||||
return null;
|
||||
}
|
||||
|
||||
public final net.ess3.api.IUser getUser(final IEssentials ess) {
|
||||
if (sender instanceof Player) {
|
||||
return ess.getUser((Player) sender);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public final boolean isPlayer() {
|
||||
return (sender instanceof Player);
|
||||
return sender instanceof Player;
|
||||
}
|
||||
|
||||
public final CommandSender setSender(final CommandSender base) {
|
||||
return this.sender = base;
|
||||
}
|
||||
|
||||
|
||||
public void sendMessage(String message) {
|
||||
public void sendMessage(final String message) {
|
||||
if (!message.isEmpty()) {
|
||||
sender.sendMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isAuthorized(final String permission, final IEssentials ess) {
|
||||
return !(sender instanceof Player) || getUser(ess).isAuthorized(permission);
|
||||
}
|
||||
|
||||
public String getSelfSelector() {
|
||||
return sender instanceof Player ? getPlayer().getName() : "*";
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return sender instanceof Player ? getPlayer().getDisplayName() : getSender().getName();
|
||||
}
|
||||
}
|
||||
@@ -2,76 +2,88 @@ package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.messaging.IMessageRecipient;
|
||||
import com.earth2me.essentials.messaging.SimpleMessageRecipient;
|
||||
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public final class Console implements IMessageRecipient {
|
||||
public static final String NAME = "Console";
|
||||
private static Console instance; // Set in essentials
|
||||
|
||||
|
||||
private final IEssentials ess;
|
||||
private final IMessageRecipient messageRecipient;
|
||||
|
||||
private Console(final IEssentials ess) {
|
||||
this.ess = ess;
|
||||
this.messageRecipient = new SimpleMessageRecipient(ess, this);
|
||||
}
|
||||
|
||||
public static Console getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
static void setInstance(IEssentials ess) { // Called in Essentials#onEnable()
|
||||
static void setInstance(final IEssentials ess) { // Called in Essentials#onEnable()
|
||||
instance = new Console(ess);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link Console#getCommandSender()}
|
||||
*/
|
||||
@Deprecated
|
||||
public static CommandSender getCommandSender(Server server) throws Exception {
|
||||
public static CommandSender getCommandSender(final Server server) throws Exception {
|
||||
return server.getConsoleSender();
|
||||
}
|
||||
|
||||
private Console(IEssentials ess) {
|
||||
this.ess = ess;
|
||||
this.messageRecipient = new SimpleMessageRecipient(ess, this);
|
||||
}
|
||||
|
||||
public CommandSender getCommandSender() {
|
||||
return ess.getServer().getConsoleSender();
|
||||
}
|
||||
|
||||
@Override public String getName() {
|
||||
@Override
|
||||
public String getName() {
|
||||
return Console.NAME;
|
||||
}
|
||||
|
||||
@Override public String getDisplayName() {
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return Console.NAME;
|
||||
}
|
||||
|
||||
@Override public void sendMessage(String message) {
|
||||
@Override
|
||||
public void sendMessage(final String message) {
|
||||
getCommandSender().sendMessage(message);
|
||||
}
|
||||
|
||||
@Override public boolean isReachable() {
|
||||
@Override
|
||||
public boolean isReachable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* ================================
|
||||
* >> DELEGATE METHODS
|
||||
* ================================ */
|
||||
|
||||
@Override public MessageResponse sendMessage(IMessageRecipient recipient, String message) {
|
||||
@Override
|
||||
public MessageResponse sendMessage(final IMessageRecipient recipient, final String message) {
|
||||
return this.messageRecipient.sendMessage(recipient, message);
|
||||
}
|
||||
|
||||
@Override public MessageResponse onReceiveMessage(IMessageRecipient sender, String message) {
|
||||
@Override
|
||||
public MessageResponse onReceiveMessage(final IMessageRecipient sender, final String message) {
|
||||
return this.messageRecipient.onReceiveMessage(sender, message);
|
||||
}
|
||||
|
||||
@Override public IMessageRecipient getReplyRecipient() {
|
||||
@Override
|
||||
public IMessageRecipient getReplyRecipient() {
|
||||
return this.messageRecipient.getReplyRecipient();
|
||||
}
|
||||
|
||||
@Override public void setReplyRecipient(IMessageRecipient recipient) {
|
||||
@Override
|
||||
public void setReplyRecipient(final IMessageRecipient recipient) {
|
||||
this.messageRecipient.setReplyRecipient(recipient);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHiddenFrom(Player player) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -9,10 +9,9 @@ import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
public class Enchantments {
|
||||
private static final Map<String, Enchantment> ENCHANTMENTS = new HashMap<String, Enchantment>();
|
||||
private static final Map<String, Enchantment> ALIASENCHANTMENTS = new HashMap<String, Enchantment>();
|
||||
public final class Enchantments {
|
||||
private static final Map<String, Enchantment> ENCHANTMENTS = new HashMap<>();
|
||||
private static final Map<String, Enchantment> ALIASENCHANTMENTS = new HashMap<>();
|
||||
private static boolean isFlat;
|
||||
|
||||
static {
|
||||
@@ -152,76 +151,78 @@ public class Enchantments {
|
||||
|
||||
// 1.8
|
||||
try {
|
||||
Enchantment depthStrider = Enchantment.getByName("DEPTH_STRIDER");
|
||||
final Enchantment depthStrider = Enchantment.getByName("DEPTH_STRIDER");
|
||||
if (depthStrider != null) {
|
||||
ENCHANTMENTS.put("depthstrider", depthStrider);
|
||||
ALIASENCHANTMENTS.put("depth", depthStrider);
|
||||
ALIASENCHANTMENTS.put("strider", depthStrider);
|
||||
}
|
||||
} catch (IllegalArgumentException ignored) {}
|
||||
} catch (final IllegalArgumentException ignored) {
|
||||
}
|
||||
|
||||
// 1.9
|
||||
try {
|
||||
Enchantment frostWalker = Enchantment.getByName("FROST_WALKER");
|
||||
final Enchantment frostWalker = Enchantment.getByName("FROST_WALKER");
|
||||
if (frostWalker != null) {
|
||||
ENCHANTMENTS.put("frostwalker", frostWalker);
|
||||
ALIASENCHANTMENTS.put("frost", frostWalker);
|
||||
ALIASENCHANTMENTS.put("walker", frostWalker);
|
||||
}
|
||||
|
||||
Enchantment mending = Enchantment.getByName("MENDING");
|
||||
final Enchantment mending = Enchantment.getByName("MENDING");
|
||||
if (mending != null) {
|
||||
ENCHANTMENTS.put("mending", mending);
|
||||
}
|
||||
} catch (IllegalArgumentException ignored) {}
|
||||
} catch (final IllegalArgumentException ignored) {
|
||||
}
|
||||
|
||||
// 1.11
|
||||
try {
|
||||
Enchantment bindingCurse = Enchantment.getByName("BINDING_CURSE");
|
||||
final Enchantment bindingCurse = Enchantment.getByName("BINDING_CURSE");
|
||||
if (bindingCurse != null) {
|
||||
ENCHANTMENTS.put("bindingcurse", bindingCurse);
|
||||
ALIASENCHANTMENTS.put("bindcurse", bindingCurse);
|
||||
ALIASENCHANTMENTS.put("binding", bindingCurse);
|
||||
ALIASENCHANTMENTS.put("bind", bindingCurse);
|
||||
}
|
||||
Enchantment vanishingCurse = Enchantment.getByName("VANISHING_CURSE");
|
||||
final Enchantment vanishingCurse = Enchantment.getByName("VANISHING_CURSE");
|
||||
if (vanishingCurse != null) {
|
||||
ENCHANTMENTS.put("vanishingcurse", vanishingCurse);
|
||||
ALIASENCHANTMENTS.put("vanishcurse", vanishingCurse);
|
||||
ALIASENCHANTMENTS.put("vanishing", vanishingCurse);
|
||||
ALIASENCHANTMENTS.put("vanish", vanishingCurse);
|
||||
}
|
||||
Enchantment sweeping = Enchantment.getByName("SWEEPING_EDGE");
|
||||
final Enchantment sweeping = Enchantment.getByName("SWEEPING_EDGE");
|
||||
if (sweeping != null) {
|
||||
ENCHANTMENTS.put("sweepingedge", sweeping);
|
||||
ALIASENCHANTMENTS.put("sweepedge", sweeping);
|
||||
ALIASENCHANTMENTS.put("sweeping", sweeping);
|
||||
}
|
||||
} catch (IllegalArgumentException ignored) {}
|
||||
|
||||
} catch (final IllegalArgumentException ignored) {
|
||||
}
|
||||
|
||||
try { // 1.13
|
||||
Enchantment loyalty = Enchantment.getByName("LOYALTY");
|
||||
final Enchantment loyalty = Enchantment.getByName("LOYALTY");
|
||||
if (loyalty != null) {
|
||||
ENCHANTMENTS.put("loyalty", loyalty);
|
||||
ALIASENCHANTMENTS.put("loyal", loyalty);
|
||||
ALIASENCHANTMENTS.put("return", loyalty);
|
||||
}
|
||||
Enchantment impaling = Enchantment.getByName("IMPALING");
|
||||
final Enchantment impaling = Enchantment.getByName("IMPALING");
|
||||
if (impaling != null) {
|
||||
ENCHANTMENTS.put("impaling", impaling);
|
||||
ALIASENCHANTMENTS.put("impale", impaling);
|
||||
ALIASENCHANTMENTS.put("oceandamage", impaling);
|
||||
ALIASENCHANTMENTS.put("oceandmg", impaling);
|
||||
}
|
||||
Enchantment riptide = Enchantment.getByName("RIPTIDE");
|
||||
final Enchantment riptide = Enchantment.getByName("RIPTIDE");
|
||||
if (riptide != null) {
|
||||
ENCHANTMENTS.put("riptide", riptide);
|
||||
ALIASENCHANTMENTS.put("rip", riptide);
|
||||
ALIASENCHANTMENTS.put("tide", riptide);
|
||||
ALIASENCHANTMENTS.put("launch", riptide);
|
||||
}
|
||||
Enchantment channelling = Enchantment.getByName("CHANNELING");
|
||||
final Enchantment channelling = Enchantment.getByName("CHANNELING");
|
||||
if (channelling != null) {
|
||||
ENCHANTMENTS.put("channelling", channelling);
|
||||
ALIASENCHANTMENTS.put("chanelling", channelling);
|
||||
@@ -229,39 +230,53 @@ public class Enchantments {
|
||||
ALIASENCHANTMENTS.put("chaneling", channelling);
|
||||
ALIASENCHANTMENTS.put("channel", channelling);
|
||||
}
|
||||
} catch (IllegalArgumentException ignored) {}
|
||||
|
||||
} catch (final IllegalArgumentException ignored) {
|
||||
}
|
||||
|
||||
try { // 1.14
|
||||
Enchantment multishot = Enchantment.getByName("MULTISHOT");
|
||||
final Enchantment multishot = Enchantment.getByName("MULTISHOT");
|
||||
if (multishot != null) {
|
||||
ENCHANTMENTS.put("multishot", multishot);
|
||||
ALIASENCHANTMENTS.put("tripleshot", multishot);
|
||||
}
|
||||
Enchantment quickCharge = Enchantment.getByName("QUICK_CHARGE");
|
||||
final Enchantment quickCharge = Enchantment.getByName("QUICK_CHARGE");
|
||||
if (quickCharge != null) {
|
||||
ENCHANTMENTS.put("quickcharge", quickCharge);
|
||||
ALIASENCHANTMENTS.put("quickdraw", quickCharge);
|
||||
ALIASENCHANTMENTS.put("fastcharge", quickCharge);
|
||||
ALIASENCHANTMENTS.put("fastdraw", quickCharge);
|
||||
}
|
||||
Enchantment piercing = Enchantment.getByName("PIERCING");
|
||||
final Enchantment piercing = Enchantment.getByName("PIERCING");
|
||||
if (piercing != null) {
|
||||
ENCHANTMENTS.put("piercing", piercing);
|
||||
}
|
||||
} catch (IllegalArgumentException ignored) {}
|
||||
} catch (final IllegalArgumentException ignored) {
|
||||
}
|
||||
|
||||
try { // 1.16
|
||||
final Enchantment soulspeed = Enchantment.getByName("SOUL_SPEED");
|
||||
if (soulspeed != null) {
|
||||
ENCHANTMENTS.put("soulspeed", soulspeed);
|
||||
ALIASENCHANTMENTS.put("soilspeed", soulspeed);
|
||||
ALIASENCHANTMENTS.put("sandspeed", soulspeed);
|
||||
}
|
||||
} catch (final IllegalArgumentException ignored) {
|
||||
}
|
||||
|
||||
try {
|
||||
Class<?> namespacedKeyClass = Class.forName("org.bukkit.NamespacedKey");
|
||||
Class<?> enchantmentClass = Class.forName("org.bukkit.enchantments.Enchantment");
|
||||
final Class<?> namespacedKeyClass = Class.forName("org.bukkit.NamespacedKey");
|
||||
final Class<?> enchantmentClass = Class.forName("org.bukkit.enchantments.Enchantment");
|
||||
enchantmentClass.getDeclaredMethod("getByKey", namespacedKeyClass);
|
||||
isFlat = true;
|
||||
} catch (ClassNotFoundException | NoSuchMethodException e) {
|
||||
} catch (final ClassNotFoundException | NoSuchMethodException e) {
|
||||
isFlat = false;
|
||||
}
|
||||
}
|
||||
|
||||
public static Enchantment getByName(String name) {
|
||||
private Enchantments() {
|
||||
}
|
||||
|
||||
public static Enchantment getByName(final String name) {
|
||||
Enchantment enchantment = null;
|
||||
if (isFlat) { // 1.13+ only
|
||||
enchantment = Enchantment.getByKey(NamespacedKey.minecraft(name.toLowerCase()));
|
||||
|
||||
@@ -17,11 +17,17 @@
|
||||
*/
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.commands.*;
|
||||
import com.earth2me.essentials.commands.EssentialsCommand;
|
||||
import com.earth2me.essentials.commands.IEssentialsCommand;
|
||||
import com.earth2me.essentials.commands.NoChargeException;
|
||||
import com.earth2me.essentials.commands.NotEnoughArgumentsException;
|
||||
import com.earth2me.essentials.commands.QuietAbortException;
|
||||
import com.earth2me.essentials.items.AbstractItemDb;
|
||||
import com.earth2me.essentials.items.CustomItemResolver;
|
||||
import com.earth2me.essentials.items.FlatItemDb;
|
||||
import com.earth2me.essentials.items.LegacyItemDb;
|
||||
import com.earth2me.essentials.metrics.Metrics;
|
||||
import com.earth2me.essentials.metrics.MetricsWrapper;
|
||||
import com.earth2me.essentials.perm.PermissionsDefaults;
|
||||
import com.earth2me.essentials.perm.PermissionsHandler;
|
||||
import com.earth2me.essentials.register.payment.Methods;
|
||||
import com.earth2me.essentials.signs.SignBlockListener;
|
||||
@@ -32,40 +38,53 @@ import com.earth2me.essentials.textreader.KeywordReplacer;
|
||||
import com.earth2me.essentials.textreader.SimpleTextInput;
|
||||
import com.earth2me.essentials.utils.DateUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.Iterables;
|
||||
import net.ess3.api.*;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import net.ess3.api.Economy;
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.IItemDb;
|
||||
import net.ess3.api.IJails;
|
||||
import net.ess3.api.ISettings;
|
||||
import net.ess3.nms.PotionMetaProvider;
|
||||
import net.ess3.nms.SpawnEggProvider;
|
||||
import net.ess3.nms.SpawnerProvider;
|
||||
import net.ess3.nms.flattened.FlatSpawnEggProvider;
|
||||
import net.ess3.nms.legacy.LegacyPotionMetaProvider;
|
||||
import net.ess3.nms.legacy.LegacySpawnEggProvider;
|
||||
import net.ess3.nms.legacy.LegacySpawnerProvider;
|
||||
import net.ess3.nms.refl.ReflSpawnEggProvider;
|
||||
import net.ess3.nms.updatedmeta.BasePotionDataProvider;
|
||||
import net.ess3.nms.updatedmeta.BlockMetaSpawnerProvider;
|
||||
import net.ess3.nms.v1_8_R1.v1_8_R1SpawnerProvider;
|
||||
import net.ess3.nms.v1_8_R2.v1_8_R2SpawnerProvider;
|
||||
import net.ess3.providers.ProviderFactory;
|
||||
import net.ess3.nms.refl.providers.ReflServerStateProvider;
|
||||
import net.ess3.nms.refl.providers.ReflSpawnEggProvider;
|
||||
import net.ess3.nms.refl.providers.ReflSpawnerBlockProvider;
|
||||
import net.ess3.nms.refl.providers.ReflKnownCommandsProvider;
|
||||
import net.ess3.provider.ContainerProvider;
|
||||
import net.ess3.provider.KnownCommandsProvider;
|
||||
import net.ess3.provider.PotionMetaProvider;
|
||||
import net.ess3.provider.ProviderListener;
|
||||
import net.ess3.provider.ServerStateProvider;
|
||||
import net.ess3.provider.SpawnEggProvider;
|
||||
import net.ess3.provider.SpawnerBlockProvider;
|
||||
import net.ess3.provider.SpawnerItemProvider;
|
||||
import net.ess3.provider.providers.BasePotionDataProvider;
|
||||
import net.ess3.provider.providers.BlockMetaSpawnerItemProvider;
|
||||
import net.ess3.provider.providers.BukkitSpawnerBlockProvider;
|
||||
import net.ess3.provider.providers.FlatSpawnEggProvider;
|
||||
import net.ess3.provider.providers.LegacyPotionMetaProvider;
|
||||
import net.ess3.provider.providers.LegacySpawnEggProvider;
|
||||
import net.ess3.provider.providers.PaperContainerProvider;
|
||||
import net.ess3.provider.providers.PaperKnownCommandsProvider;
|
||||
import net.ess3.provider.providers.PaperRecipeBookListener;
|
||||
import net.ess3.provider.providers.PaperServerStateProvider;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.command.*;
|
||||
import org.bukkit.command.BlockCommandSender;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.world.WorldLoadEvent;
|
||||
import org.bukkit.event.world.WorldUnloadEvent;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import org.bukkit.plugin.InvalidDescriptionException;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
@@ -78,54 +97,63 @@ import org.yaml.snakeyaml.error.YAMLException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
private static final Logger LOGGER = Logger.getLogger("Essentials");
|
||||
private transient ISettings settings;
|
||||
private final transient TNTExplodeListener tntListener = new TNTExplodeListener(this);
|
||||
private final transient Set<String> vanishedPlayers = new LinkedHashSet<>();
|
||||
private transient ISettings settings;
|
||||
private transient Jails jails;
|
||||
private transient Warps warps;
|
||||
private transient Worth worth;
|
||||
private transient List<IConf> confList;
|
||||
private transient Backup backup;
|
||||
private transient AbstractItemDb itemDb;
|
||||
private transient final Methods paymentMethod = new Methods();
|
||||
private transient CustomItemResolver customItemResolver;
|
||||
private transient PermissionsHandler permissionsHandler;
|
||||
private transient AlternativeCommandsHandler alternativeCommandsHandler;
|
||||
private transient UserMap userMap;
|
||||
private transient ExecuteTimer execTimer;
|
||||
private transient I18n i18n;
|
||||
private transient Metrics metrics;
|
||||
private transient MetricsWrapper metrics;
|
||||
private transient EssentialsTimer timer;
|
||||
private final transient Set<String> vanishedPlayers = new LinkedHashSet<>();
|
||||
private transient Method oldGetOnlinePlayers;
|
||||
private transient SpawnerProvider spawnerProvider;
|
||||
private transient SpawnerItemProvider spawnerItemProvider;
|
||||
private transient SpawnerBlockProvider spawnerBlockProvider;
|
||||
private transient SpawnEggProvider spawnEggProvider;
|
||||
private transient PotionMetaProvider potionMetaProvider;
|
||||
private transient ServerStateProvider serverStateProvider;
|
||||
private transient ContainerProvider containerProvider;
|
||||
private transient KnownCommandsProvider knownCommandsProvider;
|
||||
private transient ProviderListener recipeBookEventProvider;
|
||||
private transient Kits kits;
|
||||
private transient RandomTeleport randomTeleport;
|
||||
|
||||
static {
|
||||
// TODO: improve legacy code
|
||||
Methods.init();
|
||||
}
|
||||
|
||||
public Essentials() {
|
||||
}
|
||||
|
||||
public Essentials(final Server server) {
|
||||
super(new JavaPluginLoader(server), new PluginDescriptionFile("Essentials", "", "com.earth2me.essentials.Essentials"), null, null);
|
||||
protected Essentials(final JavaPluginLoader loader, final PluginDescriptionFile description, final File dataFolder, final File file) {
|
||||
super(loader, description, dataFolder, file);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void forceLoadClasses() {
|
||||
try {
|
||||
Class.forName(OfflinePlayer.class.getName());
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
public Essentials(final Server server) {
|
||||
super(new JavaPluginLoader(server), new PluginDescriptionFile("Essentials", "", "com.earth2me.essentials.Essentials"), null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -145,7 +173,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
i18n.onEnable();
|
||||
i18n.updateLocale("en");
|
||||
Console.setInstance(this);
|
||||
|
||||
|
||||
LOGGER.log(Level.INFO, tl("usingTempFolderForTesting"));
|
||||
LOGGER.log(Level.INFO, dataFolder.toString());
|
||||
settings = new Settings(this);
|
||||
@@ -169,29 +197,28 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
i18n = new I18n(this);
|
||||
i18n.onEnable();
|
||||
execTimer.mark("I18n1");
|
||||
|
||||
|
||||
Console.setInstance(this);
|
||||
|
||||
if (!VersionUtil.isServerSupported()) {
|
||||
getLogger().severe(tl("serverUnsupported"));
|
||||
switch (VersionUtil.getServerSupportStatus()) {
|
||||
case UNSTABLE:
|
||||
getLogger().severe(tl("serverUnsupportedMods"));
|
||||
break;
|
||||
case OUTDATED:
|
||||
getLogger().severe(tl("serverUnsupported"));
|
||||
break;
|
||||
case LIMITED:
|
||||
getLogger().info(tl("serverUnsupportedLimitedApi"));
|
||||
break;
|
||||
}
|
||||
|
||||
final PluginManager pm = getServer().getPluginManager();
|
||||
for (Plugin plugin : pm.getPlugins()) {
|
||||
for (final Plugin plugin : pm.getPlugins()) {
|
||||
if (plugin.getDescription().getName().startsWith("Essentials") && !plugin.getDescription().getVersion().equals(this.getDescription().getVersion()) && !plugin.getDescription().getName().equals("EssentialsAntiCheat")) {
|
||||
getLogger().warning(tl("versionMismatch", plugin.getDescription().getName()));
|
||||
}
|
||||
}
|
||||
|
||||
for (Method method : Server.class.getDeclaredMethods()) {
|
||||
if (method.getName().endsWith("getOnlinePlayers") && method.getReturnType() == Player[].class) {
|
||||
oldGetOnlinePlayers = method;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
forceLoadClasses();
|
||||
|
||||
try {
|
||||
final EssentialsUpgrade upgrade = new EssentialsUpgrade(this);
|
||||
upgrade.beforeSettings();
|
||||
@@ -216,43 +243,99 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
|
||||
warps = new Warps(getServer(), this.getDataFolder());
|
||||
confList.add(warps);
|
||||
execTimer.mark("Init(Spawn/Warp)");
|
||||
execTimer.mark("Init(Warp)");
|
||||
|
||||
worth = new Worth(this.getDataFolder());
|
||||
confList.add(worth);
|
||||
execTimer.mark("Init(Worth)");
|
||||
|
||||
itemDb = getItemDbFromConfig();
|
||||
confList.add(itemDb);
|
||||
execTimer.mark("Init(Worth/ItemDB)");
|
||||
execTimer.mark("Init(ItemDB)");
|
||||
|
||||
randomTeleport = new RandomTeleport(this);
|
||||
if (randomTeleport.getPreCache()) {
|
||||
randomTeleport.cacheRandomLocations(randomTeleport.getCenter(), randomTeleport.getMinRange(), randomTeleport.getMaxRange());
|
||||
}
|
||||
confList.add(randomTeleport);
|
||||
execTimer.mark("Init(RandomTeleport)");
|
||||
|
||||
customItemResolver = new CustomItemResolver(this);
|
||||
try {
|
||||
itemDb.registerResolver(this, "custom_items", customItemResolver);
|
||||
confList.add(customItemResolver);
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
customItemResolver = null;
|
||||
}
|
||||
execTimer.mark("Init(CustomItemResolver)");
|
||||
|
||||
jails = new Jails(this);
|
||||
confList.add(jails);
|
||||
execTimer.mark("Init(Jails)");
|
||||
|
||||
spawnerProvider = new ProviderFactory<>(getLogger(),
|
||||
Arrays.asList(
|
||||
BlockMetaSpawnerProvider.class,
|
||||
v1_8_R2SpawnerProvider.class,
|
||||
v1_8_R1SpawnerProvider.class,
|
||||
LegacySpawnerProvider.class
|
||||
), "mob spawner").getProvider();
|
||||
spawnEggProvider = new ProviderFactory<>(getLogger(),
|
||||
Arrays.asList(
|
||||
FlatSpawnEggProvider.class,
|
||||
ReflSpawnEggProvider.class,
|
||||
LegacySpawnEggProvider.class
|
||||
), "spawn egg").getProvider();
|
||||
potionMetaProvider = new ProviderFactory<>(getLogger(),
|
||||
Arrays.asList(
|
||||
BasePotionDataProvider.class,
|
||||
LegacyPotionMetaProvider.class
|
||||
), "potion meta").getProvider();
|
||||
//Spawner item provider only uses one but it's here for legacy...
|
||||
spawnerItemProvider = new BlockMetaSpawnerItemProvider();
|
||||
|
||||
//Spawner block providers
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_12_0_R01)) {
|
||||
spawnerBlockProvider = new ReflSpawnerBlockProvider();
|
||||
} else {
|
||||
spawnerBlockProvider = new BukkitSpawnerBlockProvider();
|
||||
}
|
||||
|
||||
//Spawn Egg Providers
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThanOrEqualTo(VersionUtil.v1_8_8_R01)) {
|
||||
spawnEggProvider = new LegacySpawnEggProvider();
|
||||
} else if (VersionUtil.getServerBukkitVersion().isLowerThanOrEqualTo(VersionUtil.v1_12_2_R01)) {
|
||||
spawnEggProvider = new ReflSpawnEggProvider();
|
||||
} else {
|
||||
spawnEggProvider = new FlatSpawnEggProvider();
|
||||
}
|
||||
|
||||
//Potion Meta Provider
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThanOrEqualTo(VersionUtil.v1_8_8_R01)) {
|
||||
potionMetaProvider = new LegacyPotionMetaProvider();
|
||||
} else {
|
||||
potionMetaProvider = new BasePotionDataProvider();
|
||||
}
|
||||
|
||||
//Server State Provider
|
||||
//Container Provider
|
||||
if (PaperLib.isPaper() && VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_15_2_R01)) {
|
||||
serverStateProvider = new PaperServerStateProvider();
|
||||
containerProvider = new PaperContainerProvider();
|
||||
} else {
|
||||
serverStateProvider = new ReflServerStateProvider(getLogger());
|
||||
}
|
||||
|
||||
//Event Providers
|
||||
if (PaperLib.isPaper()) {
|
||||
try {
|
||||
Class.forName("com.destroystokyo.paper.event.player.PlayerRecipeBookClickEvent");
|
||||
recipeBookEventProvider = new PaperRecipeBookListener(event -> {
|
||||
if (this.getUser(((PlayerEvent) event).getPlayer()).isRecipeSee()) {
|
||||
((Cancellable) event).setCancelled(true);
|
||||
}
|
||||
});
|
||||
} catch (final ClassNotFoundException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
//Known Commands Provider
|
||||
if (PaperLib.isPaper() && VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_11_2_R01)) {
|
||||
knownCommandsProvider = new PaperKnownCommandsProvider();
|
||||
} else {
|
||||
knownCommandsProvider = new ReflKnownCommandsProvider();
|
||||
}
|
||||
|
||||
execTimer.mark("Init(Providers)");
|
||||
reload();
|
||||
|
||||
// The item spawn blacklist is loaded with all other settings, before the item
|
||||
// DB, but it depends on the item DB, so we need to reload it again here:
|
||||
((Settings) settings)._lateLoadItemSpawnBlacklist();
|
||||
} catch (YAMLException exception) {
|
||||
} catch (final YAMLException exception) {
|
||||
if (pm.getPlugin("EssentialsUpdate") != null) {
|
||||
LOGGER.log(Level.SEVERE, tl("essentialsHelp2"));
|
||||
} else {
|
||||
@@ -271,26 +354,23 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
Economy.setEss(this);
|
||||
execTimer.mark("RegHandler");
|
||||
|
||||
for (World w : Bukkit.getWorlds())
|
||||
addDefaultBackPermissionsToWorld(w);
|
||||
// Register /hat and /back default permissions
|
||||
PermissionsDefaults.registerAllBackDefaults();
|
||||
PermissionsDefaults.registerAllHatDefaults();
|
||||
|
||||
metrics = new Metrics(this);
|
||||
if (metrics.isEnabled()) {
|
||||
getLogger().info("Starting Metrics. Opt-out using the global bStats config.");
|
||||
} else {
|
||||
getLogger().info("Metrics disabled per bStats config.");
|
||||
}
|
||||
metrics = new MetricsWrapper(this, 858, true);
|
||||
|
||||
final String timeroutput = execTimer.end();
|
||||
if (getSettings().isDebug()) {
|
||||
LOGGER.log(Level.INFO, "Essentials load {0}", timeroutput);
|
||||
}
|
||||
} catch (NumberFormatException ex) {
|
||||
} catch (final NumberFormatException ex) {
|
||||
handleCrash(ex);
|
||||
} catch (Error ex) {
|
||||
} catch (final Error ex) {
|
||||
handleCrash(ex);
|
||||
throw ex;
|
||||
}
|
||||
getBackup().setPendingShutdown(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -298,7 +378,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
// We don't use any of the bukkit config writing, as this breaks our config file formatting.
|
||||
}
|
||||
|
||||
private void registerListeners(PluginManager pm) {
|
||||
private void registerListeners(final PluginManager pm) {
|
||||
HandlerList.unregisterAll(this);
|
||||
|
||||
if (getSettings().isDebug()) {
|
||||
@@ -335,25 +415,49 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
|
||||
pm.registerEvents(tntListener, this);
|
||||
|
||||
if (recipeBookEventProvider != null) {
|
||||
pm.registerEvents(recipeBookEventProvider, this);
|
||||
}
|
||||
|
||||
jails.resetListener();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
for (User user : getOnlineUsers()) {
|
||||
final boolean stopping = getServerStateProvider().isStopping();
|
||||
if (!stopping) {
|
||||
LOGGER.log(Level.SEVERE, tl("serverReloading"));
|
||||
}
|
||||
getBackup().setPendingShutdown(true);
|
||||
for (final User user : getOnlineUsers()) {
|
||||
if (user.isVanished()) {
|
||||
user.setVanished(false);
|
||||
user.sendMessage(tl("unvanishedReload"));
|
||||
}
|
||||
user.stopTransaction();
|
||||
if (stopping) {
|
||||
user.setLastLocation();
|
||||
if (!user.isHidden()) {
|
||||
user.setLastLogout(System.currentTimeMillis());
|
||||
}
|
||||
user.cleanup();
|
||||
} else {
|
||||
user.stopTransaction();
|
||||
}
|
||||
}
|
||||
cleanupOpenInventories();
|
||||
if (getBackup().getTaskLock() != null && !getBackup().getTaskLock().isDone()) {
|
||||
LOGGER.log(Level.SEVERE, tl("backupInProgress"));
|
||||
getBackup().getTaskLock().join();
|
||||
}
|
||||
if (i18n != null) {
|
||||
i18n.onDisable();
|
||||
}
|
||||
if (backup != null) {
|
||||
backup.stopTask();
|
||||
}
|
||||
|
||||
this.getPermissionsHandler().unregisterContexts();
|
||||
|
||||
Economy.setEss(null);
|
||||
Trade.closeLog();
|
||||
getUserMap().getUUIDMap().shutdown();
|
||||
@@ -365,19 +469,26 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
public void reload() {
|
||||
Trade.closeLog();
|
||||
|
||||
for (IConf iConf : confList) {
|
||||
for (final IConf iConf : confList) {
|
||||
iConf.reloadConfig();
|
||||
execTimer.mark("Reload(" + iConf.getClass().getSimpleName() + ")");
|
||||
}
|
||||
|
||||
i18n.updateLocale(settings.getLocale());
|
||||
for (final String commandName : this.getDescription().getCommands().keySet()) {
|
||||
final Command command = this.getCommand(commandName);
|
||||
if (command != null) {
|
||||
command.setDescription(tl(commandName + "CommandDescription"));
|
||||
command.setUsage(tl(commandName + "CommandUsage"));
|
||||
}
|
||||
}
|
||||
|
||||
final PluginManager pm = getServer().getPluginManager();
|
||||
registerListeners(pm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender sender, Command command, String commandLabel, String[] args) {
|
||||
public List<String> onTabComplete(final CommandSender sender, final Command command, final String commandLabel, final String[] args) {
|
||||
return onTabCompleteEssentials(sender, command, commandLabel, args, Essentials.class.getClassLoader(),
|
||||
"com.earth2me.essentials.commands.Command", "essentials.", null);
|
||||
}
|
||||
@@ -390,7 +501,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
final PluginCommand pc = alternativeCommandsHandler.getAlternative(commandLabel);
|
||||
if (pc != null) {
|
||||
try {
|
||||
TabCompleter completer = pc.getTabCompleter();
|
||||
final TabCompleter completer = pc.getTabCompleter();
|
||||
if (completer != null) {
|
||||
return completer.onTabComplete(cSender, command, commandLabel, args);
|
||||
}
|
||||
@@ -407,19 +518,19 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
user = getUser((Player) cSender);
|
||||
}
|
||||
|
||||
CommandSource sender = new CommandSource(cSender);
|
||||
final CommandSource sender = new CommandSource(cSender);
|
||||
|
||||
// Check for disabled commands
|
||||
if (getSettings().isCommandDisabled(commandLabel)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
IEssentialsCommand cmd;
|
||||
final IEssentialsCommand cmd;
|
||||
try {
|
||||
cmd = (IEssentialsCommand) classLoader.loadClass(commandPath + command.getName()).newInstance();
|
||||
cmd.setEssentials(this);
|
||||
cmd.setEssentialsModule(module);
|
||||
} catch (Exception ex) {
|
||||
} catch (final Exception ex) {
|
||||
sender.sendMessage(tl("commandNotLoaded", commandLabel));
|
||||
LOGGER.log(Level.SEVERE, tl("commandNotLoaded", commandLabel), ex);
|
||||
return Collections.emptyList();
|
||||
@@ -441,13 +552,13 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
} else {
|
||||
return cmd.tabComplete(getServer(), user, commandLabel, command, args);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
} catch (final Exception ex) {
|
||||
showError(sender, ex, commandLabel);
|
||||
// Tab completion shouldn't fail
|
||||
LOGGER.log(Level.SEVERE, tl("commandFailed", commandLabel), ex);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
} catch (final Throwable ex) {
|
||||
LOGGER.log(Level.SEVERE, tl("commandFailed", commandLabel), ex);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@@ -455,6 +566,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
|
||||
@Override
|
||||
public boolean onCommand(final CommandSender sender, final Command command, final String commandLabel, final String[] args) {
|
||||
metrics.markCommand(command.getName(), true);
|
||||
return onCommandEssentials(sender, command, commandLabel, args, Essentials.class.getClassLoader(), "com.earth2me.essentials.commands.Command", "essentials.", null);
|
||||
}
|
||||
|
||||
@@ -482,17 +594,19 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
if (cSender instanceof Player) {
|
||||
user = getUser((Player) cSender);
|
||||
} else if (cSender instanceof BlockCommandSender) {
|
||||
BlockCommandSender bsender = (BlockCommandSender) cSender;
|
||||
final BlockCommandSender bsender = (BlockCommandSender) cSender;
|
||||
bSenderBlock = bsender.getBlock();
|
||||
}
|
||||
|
||||
if (bSenderBlock != null) {
|
||||
Bukkit.getLogger().log(Level.INFO, "CommandBlock at {0},{1},{2} issued server command: /{3} {4}", new Object[]{bSenderBlock.getX(), bSenderBlock.getY(), bSenderBlock.getZ(), commandLabel, EssentialsCommand.getFinalArg(args, 0)});
|
||||
if (getSettings().logCommandBlockCommands()) {
|
||||
Bukkit.getLogger().log(Level.INFO, "CommandBlock at {0},{1},{2} issued server command: /{3} {4}", new Object[] {bSenderBlock.getX(), bSenderBlock.getY(), bSenderBlock.getZ(), commandLabel, EssentialsCommand.getFinalArg(args, 0)});
|
||||
}
|
||||
} else if (user == null) {
|
||||
Bukkit.getLogger().log(Level.INFO, "{0} issued server command: /{1} {2}", new Object[]{cSender.getName(), commandLabel, EssentialsCommand.getFinalArg(args, 0)});
|
||||
Bukkit.getLogger().log(Level.INFO, "{0} issued server command: /{1} {2}", new Object[] {cSender.getName(), commandLabel, EssentialsCommand.getFinalArg(args, 0)});
|
||||
}
|
||||
|
||||
CommandSource sender = new CommandSource(cSender);
|
||||
final CommandSource sender = new CommandSource(cSender);
|
||||
|
||||
// New mail notification
|
||||
if (user != null && !getSettings().isCommandDisabled("mail") && !command.getName().equals("mail") && user.isAuthorized("essentials.mail")) {
|
||||
@@ -507,15 +621,16 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
|
||||
// Check for disabled commands
|
||||
if (getSettings().isCommandDisabled(commandLabel)) {
|
||||
sender.sendMessage(tl("commandDisabled", commandLabel));
|
||||
return true;
|
||||
}
|
||||
|
||||
IEssentialsCommand cmd;
|
||||
final IEssentialsCommand cmd;
|
||||
try {
|
||||
cmd = (IEssentialsCommand) classLoader.loadClass(commandPath + command.getName()).newInstance();
|
||||
cmd.setEssentials(this);
|
||||
cmd.setEssentialsModule(module);
|
||||
} catch (Exception ex) {
|
||||
} catch (final Exception ex) {
|
||||
sender.sendMessage(tl("commandNotLoaded", commandLabel));
|
||||
LOGGER.log(Level.SEVERE, tl("commandNotLoaded", commandLabel), ex);
|
||||
return true;
|
||||
@@ -545,32 +660,33 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
cmd.run(getServer(), user, commandLabel, command, args);
|
||||
}
|
||||
return true;
|
||||
} catch (NoChargeException ex) {
|
||||
} catch (final NoChargeException | QuietAbortException ex) {
|
||||
return true;
|
||||
} catch (QuietAbortException ex) {
|
||||
return true;
|
||||
} catch (NotEnoughArgumentsException ex) {
|
||||
} catch (final NotEnoughArgumentsException ex) {
|
||||
sender.sendMessage(command.getDescription());
|
||||
sender.sendMessage(command.getUsage().replaceAll("<command>", commandLabel));
|
||||
if (!ex.getMessage().isEmpty()) {
|
||||
sender.sendMessage(ex.getMessage());
|
||||
}
|
||||
if (ex.getCause() != null && settings.isDebug()) {
|
||||
ex.getCause().printStackTrace();
|
||||
}
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
} catch (final Exception ex) {
|
||||
showError(sender, ex, commandLabel);
|
||||
if (settings.isDebug()) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
} catch (final Throwable ex) {
|
||||
LOGGER.log(Level.SEVERE, tl("commandFailed", commandLabel), ex);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void cleanupOpenInventories() {
|
||||
for (User user : getOnlineUsers()) {
|
||||
for (final User user : getOnlineUsers()) {
|
||||
if (user.isRecipeSee()) {
|
||||
user.getBase().getOpenInventory().getTopInventory().clear();
|
||||
user.getBase().getOpenInventory().close();
|
||||
@@ -623,13 +739,8 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Metrics getMetrics() {
|
||||
return metrics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMetrics(Metrics metrics) {
|
||||
this.metrics = metrics;
|
||||
public RandomTeleport getRandomTeleport() {
|
||||
return randomTeleport;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@@ -703,7 +814,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
return user;
|
||||
}
|
||||
|
||||
private void handleCrash(Throwable exception) {
|
||||
private void handleCrash(final Throwable exception) {
|
||||
final PluginManager pm = getServer().getPluginManager();
|
||||
LOGGER.log(Level.SEVERE, exception.toString());
|
||||
exception.printStackTrace();
|
||||
@@ -713,7 +824,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
event.getPlayer().sendMessage("Essentials failed to load, read the log file.");
|
||||
}
|
||||
}, this);
|
||||
for (Player player : getOnlinePlayers()) {
|
||||
for (final Player player : getOnlinePlayers()) {
|
||||
player.sendMessage("Essentials failed to load, read the log file.");
|
||||
}
|
||||
this.setEnabled(false);
|
||||
@@ -735,27 +846,27 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
confList.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Methods getPaymentMethod() {
|
||||
return paymentMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int broadcastMessage(final String message) {
|
||||
return broadcastMessage(null, null, message, true);
|
||||
return broadcastMessage(null, null, message, true, u -> false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int broadcastMessage(final IUser sender, final String message) {
|
||||
return broadcastMessage(sender, null, message, false);
|
||||
return broadcastMessage(sender, null, message, false, u -> false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int broadcastMessage(final IUser sender, final String message, final Predicate<IUser> shouldExclude) {
|
||||
return broadcastMessage(sender, null, message, false, shouldExclude);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int broadcastMessage(final String permission, final String message) {
|
||||
return broadcastMessage(null, permission, message, false);
|
||||
return broadcastMessage(null, permission, message, false, u -> false);
|
||||
}
|
||||
|
||||
private int broadcastMessage(final IUser sender, final String permission, final String message, final boolean keywords) {
|
||||
private int broadcastMessage(final IUser sender, final String permission, final String message, final boolean keywords, final Predicate<IUser> shouldExclude) {
|
||||
if (sender != null && sender.isHidden()) {
|
||||
return 0;
|
||||
}
|
||||
@@ -763,14 +874,16 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
IText broadcast = new SimpleTextInput(message);
|
||||
|
||||
final Collection<Player> players = getOnlinePlayers();
|
||||
|
||||
for (Player player : players) {
|
||||
for (final Player player : players) {
|
||||
final User user = getUser(player);
|
||||
if ((permission == null && (sender == null || !user.isIgnoredPlayer(sender))) || (permission != null && user.isAuthorized(permission))) {
|
||||
if (shouldExclude.test(user)) {
|
||||
continue;
|
||||
}
|
||||
if (keywords) {
|
||||
broadcast = new KeywordReplacer(broadcast, new CommandSource(player), this, false);
|
||||
}
|
||||
for (String messageText : broadcast.getLines()) {
|
||||
for (final String messageText : broadcast.getLines()) {
|
||||
user.sendMessage(messageText);
|
||||
}
|
||||
}
|
||||
@@ -856,33 +969,26 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
|
||||
@Override
|
||||
public Collection<Player> getOnlinePlayers() {
|
||||
try {
|
||||
return (Collection<Player>) getServer().getOnlinePlayers(); // Needed for sanity here, the Bukkit API is a bit broken in the sense it only allows subclasses of Player to this list
|
||||
} catch (NoSuchMethodError ex) {
|
||||
try {
|
||||
return Arrays.asList((Player[]) oldGetOnlinePlayers.invoke(getServer()));
|
||||
} catch (InvocationTargetException ex1) {
|
||||
throw Throwables.propagate(ex.getCause());
|
||||
} catch (IllegalAccessException ex1) {
|
||||
throw new RuntimeException("Error invoking oldGetOnlinePlayers", ex1);
|
||||
}
|
||||
}
|
||||
return (Collection<Player>) getServer().getOnlinePlayers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<User> getOnlineUsers() {
|
||||
return Iterables.transform(getOnlinePlayers(), new Function<Player, User>() {
|
||||
|
||||
@Override
|
||||
public User apply(Player player) {
|
||||
return getUser(player);
|
||||
}
|
||||
});
|
||||
final List<User> onlineUsers = new ArrayList<>();
|
||||
for (final Player player : getOnlinePlayers()) {
|
||||
onlineUsers.add(getUser(player));
|
||||
}
|
||||
return onlineUsers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpawnerProvider getSpawnerProvider() {
|
||||
return spawnerProvider;
|
||||
public SpawnerItemProvider getSpawnerItemProvider() {
|
||||
return spawnerItemProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpawnerBlockProvider getSpawnerBlockProvider() {
|
||||
return spawnerBlockProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -895,32 +1001,58 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
return potionMetaProvider;
|
||||
}
|
||||
|
||||
private static void addDefaultBackPermissionsToWorld(World w) {
|
||||
String permName = "essentials.back.into." + w.getName();
|
||||
@Override
|
||||
public CustomItemResolver getCustomItemResolver() {
|
||||
return customItemResolver;
|
||||
}
|
||||
|
||||
Permission p = Bukkit.getPluginManager().getPermission(permName);
|
||||
if (p == null) {
|
||||
p = new Permission(permName,
|
||||
"Allows access to /back when the destination location is within world " + w.getName(),
|
||||
PermissionDefault.TRUE);
|
||||
Bukkit.getPluginManager().addPermission(p);
|
||||
@Override
|
||||
public ServerStateProvider getServerStateProvider() {
|
||||
return serverStateProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContainerProvider getContainerProvider() {
|
||||
return containerProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KnownCommandsProvider getKnownCommandsProvider() {
|
||||
return knownCommandsProvider;
|
||||
}
|
||||
|
||||
private AbstractItemDb getItemDbFromConfig() {
|
||||
final String setting = settings.getItemDbType();
|
||||
|
||||
if (setting.equalsIgnoreCase("json")) {
|
||||
return new FlatItemDb(this);
|
||||
} else if (setting.equalsIgnoreCase("csv")) {
|
||||
return new LegacyItemDb(this);
|
||||
} else {
|
||||
final VersionUtil.BukkitVersion version = VersionUtil.getServerBukkitVersion();
|
||||
|
||||
if (version.isHigherThanOrEqualTo(VersionUtil.v1_13_0_R01)) {
|
||||
return new FlatItemDb(this);
|
||||
} else {
|
||||
return new LegacyItemDb(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class EssentialsWorldListener implements Listener, Runnable {
|
||||
private transient final IEssentials ess;
|
||||
|
||||
public EssentialsWorldListener(final IEssentials ess) {
|
||||
EssentialsWorldListener(final IEssentials ess) {
|
||||
this.ess = ess;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onWorldLoad(final WorldLoadEvent event) {
|
||||
addDefaultBackPermissionsToWorld(event.getWorld());
|
||||
PermissionsDefaults.registerBackDefaultFor(event.getWorld());
|
||||
|
||||
ess.getJails().onReload();
|
||||
ess.getWarps().reloadConfig();
|
||||
for (IConf iConf : ((Essentials) ess).confList) {
|
||||
for (final IConf iConf : ((Essentials) ess).confList) {
|
||||
if (iConf instanceof IEssentialsModule) {
|
||||
iConf.reloadConfig();
|
||||
}
|
||||
@@ -931,7 +1063,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
public void onWorldUnload(final WorldUnloadEvent event) {
|
||||
ess.getJails().onReload();
|
||||
ess.getWarps().reloadConfig();
|
||||
for (IConf iConf : ((Essentials) ess).confList) {
|
||||
for (final IConf iConf : ((Essentials) ess).confList) {
|
||||
if (iConf instanceof IEssentialsModule) {
|
||||
iConf.reloadConfig();
|
||||
}
|
||||
@@ -943,22 +1075,4 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
ess.reload();
|
||||
}
|
||||
}
|
||||
|
||||
private AbstractItemDb getItemDbFromConfig() {
|
||||
final String setting = settings.getItemDbType();
|
||||
|
||||
if (setting.equalsIgnoreCase("json")) {
|
||||
return new FlatItemDb(this);
|
||||
} else if (setting.equalsIgnoreCase("csv")) {
|
||||
return new LegacyItemDb(this);
|
||||
} else {
|
||||
VersionUtil.BukkitVersion version = VersionUtil.getServerBukkitVersion();
|
||||
|
||||
if (version.isHigherThanOrEqualTo(VersionUtil.v1_13_0_R01)) {
|
||||
return new FlatItemDb(this);
|
||||
} else {
|
||||
return new LegacyItemDb(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,9 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.utils.EnumUtil;
|
||||
import com.earth2me.essentials.utils.LocationUtil;
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import net.ess3.api.IEssentials;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.CreatureSpawner;
|
||||
import org.bukkit.entity.EntityType;
|
||||
@@ -17,7 +15,6 @@ import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
|
||||
public class EssentialsBlockListener implements Listener {
|
||||
private final transient IEssentials ess;
|
||||
|
||||
@@ -39,7 +36,7 @@ public class EssentialsBlockListener implements Listener {
|
||||
final BlockState blockState = event.getBlockPlaced().getState();
|
||||
if (blockState instanceof CreatureSpawner) {
|
||||
final CreatureSpawner spawner = (CreatureSpawner) blockState;
|
||||
final EntityType type = ess.getSpawnerProvider().getEntityType(event.getItemInHand());
|
||||
final EntityType type = ess.getSpawnerItemProvider().getEntityType(event.getItemInHand());
|
||||
if (type != null && Mob.fromBukkitType(type) != null) {
|
||||
if (ess.getUser(event.getPlayer()).isAuthorized("essentials.spawnerconvert." + Mob.fromBukkitType(type).name().toLowerCase(Locale.ENGLISH))) {
|
||||
spawner.setSpawnedType(type);
|
||||
@@ -58,6 +55,7 @@ public class EssentialsBlockListener implements Listener {
|
||||
user.getBase().updateInventory();
|
||||
}
|
||||
}
|
||||
|
||||
ess.scheduleSyncDelayedTask(new UnlimitedItemSpawnTask());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,11 @@ package com.earth2me.essentials;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import net.ess3.api.InvalidWorldException;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
@@ -11,15 +14,30 @@ import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.CoderResult;
|
||||
import java.util.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
@@ -31,23 +49,33 @@ import java.util.logging.Logger;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class EssentialsConf extends YamlConfiguration {
|
||||
protected static final Logger LOGGER = Logger.getLogger("Essentials");
|
||||
protected final File configFile;
|
||||
protected String templateName = null;
|
||||
protected static final Charset UTF8 = Charset.forName("UTF-8");
|
||||
private Class<?> resourceClass = EssentialsConf.class;
|
||||
protected static final Charset UTF8 = StandardCharsets.UTF_8;
|
||||
private static final ExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadExecutor();
|
||||
protected final File configFile;
|
||||
private final AtomicInteger pendingDiskWrites = new AtomicInteger(0);
|
||||
private final AtomicBoolean transaction = new AtomicBoolean(false);
|
||||
private final byte[] bytebuffer = new byte[1024];
|
||||
protected String templateName = null;
|
||||
private Class<?> resourceClass = EssentialsConf.class;
|
||||
|
||||
public EssentialsConf(final File configFile) {
|
||||
super();
|
||||
this.configFile = configFile.getAbsoluteFile();
|
||||
}
|
||||
|
||||
private final byte[] bytebuffer = new byte[1024];
|
||||
public static BigDecimal toBigDecimal(final String input, final BigDecimal def) {
|
||||
if (input == null || input.isEmpty()) {
|
||||
return def;
|
||||
} else {
|
||||
try {
|
||||
return new BigDecimal(input, MathContext.DECIMAL128);
|
||||
} catch (final NumberFormatException | ArithmeticException e) {
|
||||
return def;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void load() {
|
||||
if (pendingDiskWrites.get() != 0) {
|
||||
@@ -68,16 +96,16 @@ public class EssentialsConf extends YamlConfiguration {
|
||||
input.close();
|
||||
configFile.delete();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
} catch (final IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, null, ex);
|
||||
} finally {
|
||||
try {
|
||||
input.close();
|
||||
} catch (IOException ex) {
|
||||
} catch (final IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
} catch (final FileNotFoundException ex) {
|
||||
LOGGER.log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
@@ -95,10 +123,9 @@ public class EssentialsConf extends YamlConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
try (FileInputStream inputStream = new FileInputStream(configFile)) {
|
||||
long startSize = configFile.length();
|
||||
try (final FileInputStream inputStream = new FileInputStream(configFile)) {
|
||||
final long startSize = configFile.length();
|
||||
if (startSize > Integer.MAX_VALUE) {
|
||||
throw new InvalidConfigurationException("File too big");
|
||||
}
|
||||
@@ -106,22 +133,23 @@ public class EssentialsConf extends YamlConfiguration {
|
||||
int length;
|
||||
while ((length = inputStream.read(bytebuffer)) != -1) {
|
||||
if (length > buffer.remaining()) {
|
||||
ByteBuffer resize = ByteBuffer.allocate(buffer.capacity() + length - buffer.remaining());
|
||||
int resizePosition = buffer.position();
|
||||
buffer.rewind();
|
||||
final ByteBuffer resize = ByteBuffer.allocate(buffer.capacity() + length - buffer.remaining());
|
||||
final int resizePosition = buffer.position();
|
||||
// Fix builds compiled against Java 9+ breaking on Java 8
|
||||
((Buffer) buffer).rewind();
|
||||
resize.put(buffer);
|
||||
resize.position(resizePosition);
|
||||
buffer = resize;
|
||||
}
|
||||
buffer.put(bytebuffer, 0, length);
|
||||
}
|
||||
buffer.rewind();
|
||||
((Buffer) buffer).rewind();
|
||||
final CharBuffer data = CharBuffer.allocate(buffer.capacity());
|
||||
CharsetDecoder decoder = UTF8.newDecoder();
|
||||
CoderResult result = decoder.decode(buffer, data, true);
|
||||
if (result.isError()) {
|
||||
buffer.rewind();
|
||||
data.clear();
|
||||
((Buffer) buffer).rewind();
|
||||
((Buffer) data).clear();
|
||||
LOGGER.log(Level.INFO, "File " + configFile.getAbsolutePath() + " is not utf-8 encoded, trying " + Charset.defaultCharset().displayName());
|
||||
decoder = Charset.defaultCharset().newDecoder();
|
||||
result = decoder.decode(buffer, data, true);
|
||||
@@ -134,13 +162,13 @@ public class EssentialsConf extends YamlConfiguration {
|
||||
decoder.flush(data);
|
||||
}
|
||||
final int end = data.position();
|
||||
data.rewind();
|
||||
((Buffer) data).rewind();
|
||||
super.loadFromString(data.subSequence(0, end).toString());
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
} catch (final IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, ex.getMessage(), ex);
|
||||
} catch (InvalidConfigurationException ex) {
|
||||
File broken = new File(configFile.getAbsolutePath() + ".broken." + System.currentTimeMillis());
|
||||
} catch (final InvalidConfigurationException ex) {
|
||||
final File broken = new File(configFile.getAbsolutePath() + ".broken." + System.currentTimeMillis());
|
||||
configFile.renameTo(broken);
|
||||
LOGGER.log(Level.SEVERE, "The file " + configFile.toString() + " is broken, it has been renamed to " + broken.toString(), ex.getCause());
|
||||
}
|
||||
@@ -172,28 +200,28 @@ public class EssentialsConf extends YamlConfiguration {
|
||||
return;
|
||||
}
|
||||
ostr = new FileOutputStream(configFile);
|
||||
byte[] buffer = new byte[1024];
|
||||
final byte[] buffer = new byte[1024];
|
||||
int length = 0;
|
||||
length = istr.read(buffer);
|
||||
while (length > 0) {
|
||||
ostr.write(buffer, 0, length);
|
||||
length = istr.read(buffer);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
} catch (final IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, tl("failedToWriteConfig", configFile.toString()), ex);
|
||||
} finally {
|
||||
try {
|
||||
if (istr != null) {
|
||||
istr.close();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
} catch (final IOException ex) {
|
||||
Logger.getLogger(EssentialsConf.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
try {
|
||||
if (ostr != null) {
|
||||
ostr.close();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
} catch (final IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, tl("failedToCloseConfig", configFile.toString()), ex);
|
||||
}
|
||||
}
|
||||
@@ -224,7 +252,7 @@ public class EssentialsConf extends YamlConfiguration {
|
||||
public void save() {
|
||||
try {
|
||||
save(configFile);
|
||||
} catch (IOException ex) {
|
||||
} catch (final IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
@@ -244,11 +272,11 @@ public class EssentialsConf extends YamlConfiguration {
|
||||
//This needs fixed to discard outstanding save requests.
|
||||
public synchronized void forceSave() {
|
||||
try {
|
||||
Future<?> future = delayedSave(configFile);
|
||||
final Future<?> future = delayedSave(configFile);
|
||||
if (future != null) {
|
||||
future.get();
|
||||
}
|
||||
} catch (InterruptedException | ExecutionException ex) {
|
||||
} catch (final InterruptedException | ExecutionException ex) {
|
||||
LOGGER.log(Level.SEVERE, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
@@ -273,60 +301,6 @@ public class EssentialsConf extends YamlConfiguration {
|
||||
return EXECUTOR_SERVICE.submit(new WriteRunner(configFile, data, pendingDiskWrites));
|
||||
}
|
||||
|
||||
|
||||
private static class WriteRunner implements Runnable {
|
||||
private final File configFile;
|
||||
private final String data;
|
||||
private final AtomicInteger pendingDiskWrites;
|
||||
|
||||
private WriteRunner(final File configFile, final String data, final AtomicInteger pendingDiskWrites) {
|
||||
this.configFile = configFile;
|
||||
this.data = data;
|
||||
this.pendingDiskWrites = pendingDiskWrites;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
//long startTime = System.nanoTime();
|
||||
synchronized (configFile) {
|
||||
if (pendingDiskWrites.get() > 1) {
|
||||
// Writes can be skipped, because they are stored in a queue (in the executor).
|
||||
// Only the last is actually written.
|
||||
pendingDiskWrites.decrementAndGet();
|
||||
//LOGGER.log(Level.INFO, configFile + " skipped writing in " + (System.nanoTime() - startTime) + " nsec.");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Files.createParentDirs(configFile);
|
||||
|
||||
if (!configFile.exists()) {
|
||||
try {
|
||||
LOGGER.log(Level.INFO, tl("creatingEmptyConfig", configFile.toString()));
|
||||
if (!configFile.createNewFile()) {
|
||||
LOGGER.log(Level.SEVERE, tl("failedToCreateConfig", configFile.toString()));
|
||||
return;
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, tl("failedToCreateConfig", configFile.toString()), ex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try (FileOutputStream fos = new FileOutputStream(configFile)) {
|
||||
try (OutputStreamWriter writer = new OutputStreamWriter(fos, UTF8)) {
|
||||
writer.write(data);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOGGER.log(Level.SEVERE, e.getMessage(), e);
|
||||
} finally {
|
||||
//LOGGER.log(Level.INFO, configFile + " written to disk in " + (System.nanoTime() - startTime) + " nsec.");
|
||||
pendingDiskWrites.decrementAndGet();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasProperty(final String path) {
|
||||
return isSet(path);
|
||||
}
|
||||
@@ -358,7 +332,7 @@ public class EssentialsConf extends YamlConfiguration {
|
||||
final ItemStack stack = new ItemStack(Material.valueOf(getString(path + ".type", "AIR")), getInt(path + ".amount", 1), (short) getInt(path + ".damage", 0));
|
||||
final ConfigurationSection enchants = getConfigurationSection(path + ".enchant");
|
||||
if (enchants != null) {
|
||||
for (String enchant : enchants.getKeys(false)) {
|
||||
for (final String enchant : enchants.getKeys(false)) {
|
||||
final Enchantment enchantment = Enchantment.getByName(enchant.toUpperCase(Locale.ENGLISH));
|
||||
if (enchantment == null) {
|
||||
continue;
|
||||
@@ -370,8 +344,8 @@ public class EssentialsConf extends YamlConfiguration {
|
||||
return stack;
|
||||
/*
|
||||
* ,
|
||||
* (byte)getInt(path + ".data", 0)
|
||||
*/
|
||||
* (byte)getInt(path + ".data", 0)
|
||||
*/
|
||||
}
|
||||
|
||||
public void setProperty(final String path, final ItemStack stack) {
|
||||
@@ -379,10 +353,10 @@ public class EssentialsConf extends YamlConfiguration {
|
||||
map.put("type", stack.getType().toString());
|
||||
map.put("amount", stack.getAmount());
|
||||
map.put("damage", stack.getDurability());
|
||||
Map<Enchantment, Integer> enchantments = stack.getEnchantments();
|
||||
final Map<Enchantment, Integer> enchantments = stack.getEnchantments();
|
||||
if (!enchantments.isEmpty()) {
|
||||
Map<String, Integer> enchant = new HashMap<>();
|
||||
for (Map.Entry<Enchantment, Integer> entry : enchantments.entrySet()) {
|
||||
final Map<String, Integer> enchant = new HashMap<>();
|
||||
for (final Map.Entry<Enchantment, Integer> entry : enchantments.entrySet()) {
|
||||
enchant.put(entry.getKey().getName().toLowerCase(Locale.ENGLISH), entry.getValue());
|
||||
}
|
||||
map.put("enchant", enchant);
|
||||
@@ -392,15 +366,15 @@ public class EssentialsConf extends YamlConfiguration {
|
||||
set(path, map);
|
||||
}
|
||||
|
||||
public void setProperty(String path, List object) {
|
||||
public void setProperty(final String path, final List object) {
|
||||
set(path, new ArrayList(object));
|
||||
}
|
||||
|
||||
public void setProperty(String path, Map object) {
|
||||
public void setProperty(final String path, final Map object) {
|
||||
set(path, new LinkedHashMap(object));
|
||||
}
|
||||
|
||||
public Object getProperty(String path) {
|
||||
public Object getProperty(final String path) {
|
||||
return get(path);
|
||||
}
|
||||
|
||||
@@ -408,21 +382,21 @@ public class EssentialsConf extends YamlConfiguration {
|
||||
set(path, bigDecimal.toString());
|
||||
}
|
||||
|
||||
public void setProperty(String path, Object object) {
|
||||
public void setProperty(final String path, final Object object) {
|
||||
set(path, object);
|
||||
}
|
||||
|
||||
public void removeProperty(String path) {
|
||||
public void removeProperty(final String path) {
|
||||
set(path, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Object get(String path) {
|
||||
public synchronized Object get(final String path) {
|
||||
return super.get(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Object get(String path, Object def) {
|
||||
public synchronized Object get(final String path, final Object def) {
|
||||
return super.get(path, def);
|
||||
}
|
||||
|
||||
@@ -431,52 +405,38 @@ public class EssentialsConf extends YamlConfiguration {
|
||||
return toBigDecimal(input, def);
|
||||
}
|
||||
|
||||
public static BigDecimal toBigDecimal(final String input, final BigDecimal def) {
|
||||
if (input == null || input.isEmpty()) {
|
||||
return def;
|
||||
} else {
|
||||
try {
|
||||
return new BigDecimal(input, MathContext.DECIMAL128);
|
||||
} catch (NumberFormatException e) {
|
||||
return def;
|
||||
} catch (ArithmeticException e) {
|
||||
return def;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean getBoolean(String path) {
|
||||
public synchronized boolean getBoolean(final String path) {
|
||||
return super.getBoolean(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean getBoolean(String path, boolean def) {
|
||||
public synchronized boolean getBoolean(final String path, final boolean def) {
|
||||
return super.getBoolean(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Boolean> getBooleanList(String path) {
|
||||
public synchronized List<Boolean> getBooleanList(final String path) {
|
||||
return super.getBooleanList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Byte> getByteList(String path) {
|
||||
public synchronized List<Byte> getByteList(final String path) {
|
||||
return super.getByteList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Character> getCharacterList(String path) {
|
||||
public synchronized List<Character> getCharacterList(final String path) {
|
||||
return super.getCharacterList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized ConfigurationSection getConfigurationSection(String path) {
|
||||
public synchronized ConfigurationSection getConfigurationSection(final String path) {
|
||||
return super.getConfigurationSection(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized double getDouble(String path) {
|
||||
public synchronized double getDouble(final String path) {
|
||||
return super.getDouble(path);
|
||||
}
|
||||
|
||||
@@ -486,52 +446,52 @@ public class EssentialsConf extends YamlConfiguration {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Double> getDoubleList(String path) {
|
||||
public synchronized List<Double> getDoubleList(final String path) {
|
||||
return super.getDoubleList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Float> getFloatList(String path) {
|
||||
public synchronized List<Float> getFloatList(final String path) {
|
||||
return super.getFloatList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int getInt(String path) {
|
||||
public synchronized int getInt(final String path) {
|
||||
return super.getInt(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int getInt(String path, int def) {
|
||||
public synchronized int getInt(final String path, final int def) {
|
||||
return super.getInt(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Integer> getIntegerList(String path) {
|
||||
public synchronized List<Integer> getIntegerList(final String path) {
|
||||
return super.getIntegerList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized ItemStack getItemStack(String path, ItemStack def) {
|
||||
public synchronized ItemStack getItemStack(final String path, final ItemStack def) {
|
||||
return super.getItemStack(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Set<String> getKeys(boolean deep) {
|
||||
public synchronized Set<String> getKeys(final boolean deep) {
|
||||
return super.getKeys(deep);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<?> getList(String path) {
|
||||
public synchronized List<?> getList(final String path) {
|
||||
return super.getList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<?> getList(String path, List<?> def) {
|
||||
public synchronized List<?> getList(final String path, final List<?> def) {
|
||||
return super.getList(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized long getLong(String path) {
|
||||
public synchronized long getLong(final String path) {
|
||||
return super.getLong(path);
|
||||
}
|
||||
|
||||
@@ -541,7 +501,7 @@ public class EssentialsConf extends YamlConfiguration {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Long> getLongList(String path) {
|
||||
public synchronized List<Long> getLongList(final String path) {
|
||||
return super.getLongList(path);
|
||||
}
|
||||
|
||||
@@ -550,112 +510,165 @@ public class EssentialsConf extends YamlConfiguration {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Map<?, ?>> getMapList(String path) {
|
||||
public synchronized List<Map<?, ?>> getMapList(final String path) {
|
||||
return super.getMapList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized OfflinePlayer getOfflinePlayer(String path) {
|
||||
public synchronized OfflinePlayer getOfflinePlayer(final String path) {
|
||||
return super.getOfflinePlayer(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized OfflinePlayer getOfflinePlayer(String path, OfflinePlayer def) {
|
||||
public synchronized OfflinePlayer getOfflinePlayer(final String path, final OfflinePlayer def) {
|
||||
return super.getOfflinePlayer(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Short> getShortList(String path) {
|
||||
public synchronized List<Short> getShortList(final String path) {
|
||||
return super.getShortList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized String getString(String path) {
|
||||
public synchronized String getString(final String path) {
|
||||
return super.getString(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized String getString(String path, String def) {
|
||||
public synchronized String getString(final String path, final String def) {
|
||||
return super.getString(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<String> getStringList(String path) {
|
||||
public synchronized List<String> getStringList(final String path) {
|
||||
return super.getStringList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Map<String, Object> getValues(boolean deep) {
|
||||
public synchronized Map<String, Object> getValues(final boolean deep) {
|
||||
return super.getValues(deep);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Vector getVector(String path) {
|
||||
public synchronized Vector getVector(final String path) {
|
||||
return super.getVector(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Vector getVector(String path, Vector def) {
|
||||
public synchronized Vector getVector(final String path, final Vector def) {
|
||||
return super.getVector(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isBoolean(String path) {
|
||||
public synchronized boolean isBoolean(final String path) {
|
||||
return super.isBoolean(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isConfigurationSection(String path) {
|
||||
public synchronized boolean isConfigurationSection(final String path) {
|
||||
return super.isConfigurationSection(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isDouble(String path) {
|
||||
public synchronized boolean isDouble(final String path) {
|
||||
return super.isDouble(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isInt(String path) {
|
||||
public synchronized boolean isInt(final String path) {
|
||||
return super.isInt(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isItemStack(String path) {
|
||||
public synchronized boolean isItemStack(final String path) {
|
||||
return super.isItemStack(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isList(String path) {
|
||||
public synchronized boolean isList(final String path) {
|
||||
return super.isList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isLong(String path) {
|
||||
public synchronized boolean isLong(final String path) {
|
||||
return super.isLong(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isOfflinePlayer(String path) {
|
||||
public synchronized boolean isOfflinePlayer(final String path) {
|
||||
return super.isOfflinePlayer(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isSet(String path) {
|
||||
public synchronized boolean isSet(final String path) {
|
||||
return super.isSet(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isString(String path) {
|
||||
public synchronized boolean isString(final String path) {
|
||||
return super.isString(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isVector(String path) {
|
||||
public synchronized boolean isVector(final String path) {
|
||||
return super.isVector(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void set(String path, Object value) {
|
||||
public synchronized void set(final String path, final Object value) {
|
||||
super.set(path, value);
|
||||
}
|
||||
|
||||
private static final class WriteRunner implements Runnable {
|
||||
private final File configFile;
|
||||
private final String data;
|
||||
private final AtomicInteger pendingDiskWrites;
|
||||
|
||||
private WriteRunner(final File configFile, final String data, final AtomicInteger pendingDiskWrites) {
|
||||
this.configFile = configFile;
|
||||
this.data = data;
|
||||
this.pendingDiskWrites = pendingDiskWrites;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
//long startTime = System.nanoTime();
|
||||
synchronized (configFile) {
|
||||
if (pendingDiskWrites.get() > 1) {
|
||||
// Writes can be skipped, because they are stored in a queue (in the executor).
|
||||
// Only the last is actually written.
|
||||
pendingDiskWrites.decrementAndGet();
|
||||
//LOGGER.log(Level.INFO, configFile + " skipped writing in " + (System.nanoTime() - startTime) + " nsec.");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Files.createParentDirs(configFile);
|
||||
|
||||
if (!configFile.exists()) {
|
||||
try {
|
||||
LOGGER.log(Level.INFO, tl("creatingEmptyConfig", configFile.toString()));
|
||||
if (!configFile.createNewFile()) {
|
||||
LOGGER.log(Level.SEVERE, tl("failedToCreateConfig", configFile.toString()));
|
||||
return;
|
||||
}
|
||||
} catch (final IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, tl("failedToCreateConfig", configFile.toString()), ex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try (final FileOutputStream fos = new FileOutputStream(configFile)) {
|
||||
try (final OutputStreamWriter writer = new OutputStreamWriter(fos, UTF8)) {
|
||||
writer.write(data);
|
||||
}
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
LOGGER.log(Level.SEVERE, e.getMessage(), e);
|
||||
} finally {
|
||||
//LOGGER.log(Level.INFO, configFile + " written to disk in " + (System.nanoTime() - startTime) + " nsec.");
|
||||
pendingDiskWrites.decrementAndGet();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,30 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import net.ess3.api.IEssentials;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Ageable;
|
||||
import org.bukkit.entity.Arrow;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.*;
|
||||
import org.bukkit.event.entity.EntityCombustByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityCombustEvent;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.entity.EntityRegainHealthEvent;
|
||||
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason;
|
||||
import org.bukkit.event.entity.EntityShootBowEvent;
|
||||
import org.bukkit.event.entity.EntityTargetEvent;
|
||||
import org.bukkit.event.entity.FoodLevelChangeEvent;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.event.entity.PotionSplashEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
@@ -17,13 +34,12 @@ import java.util.regex.Pattern;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class EssentialsEntityListener implements Listener {
|
||||
private static final Logger LOGGER = Logger.getLogger("Essentials");
|
||||
private static final transient Pattern powertoolPlayer = Pattern.compile("\\{player\\}");
|
||||
private final IEssentials ess;
|
||||
|
||||
public EssentialsEntityListener(IEssentials ess) {
|
||||
public EssentialsEntityListener(final IEssentials ess) {
|
||||
this.ess = ess;
|
||||
}
|
||||
|
||||
@@ -39,7 +55,7 @@ public class EssentialsEntityListener implements Listener {
|
||||
} else if (eDefend instanceof Ageable) {
|
||||
final ItemStack hand = attacker.getBase().getItemInHand();
|
||||
if (ess.getSettings().isMilkBucketEasterEggEnabled()
|
||||
&& hand != null && hand.getType() == Material.MILK_BUCKET) {
|
||||
&& hand != null && hand.getType() == Material.MILK_BUCKET) {
|
||||
((Ageable) eDefend).setBaby();
|
||||
hand.setType(Material.BUCKET);
|
||||
attacker.getBase().setItemInHand(hand);
|
||||
@@ -96,6 +112,7 @@ public class EssentialsEntityListener implements Listener {
|
||||
LOGGER.log(Level.INFO, String.format("[PT] %s issued server command: /%s", attacker.getName(), command));
|
||||
}
|
||||
}
|
||||
|
||||
ess.scheduleSyncDelayedTask(new PowerToolInteractTask());
|
||||
|
||||
event.setCancelled(true);
|
||||
@@ -125,9 +142,13 @@ public class EssentialsEntityListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onEntityCombustByEntity(final EntityCombustByEntityEvent event) {
|
||||
if (event.getCombuster() instanceof Arrow && event.getEntity() instanceof Player) {
|
||||
Arrow combuster = (Arrow) event.getCombuster();
|
||||
final Arrow combuster = (Arrow) event.getCombuster();
|
||||
if (combuster.getShooter() instanceof Player) {
|
||||
final User srcCombuster = ess.getUser(((Player) combuster.getShooter()).getUniqueId());
|
||||
final Player shooter = (Player) combuster.getShooter();
|
||||
if (shooter.hasMetadata("NPC")) {
|
||||
return;
|
||||
}
|
||||
final User srcCombuster = ess.getUser(shooter.getUniqueId());
|
||||
if (srcCombuster.isGodModeEnabled() && !srcCombuster.isAuthorized("essentials.god.pvp")) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
@@ -140,7 +161,15 @@ public class EssentialsEntityListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerDeathEvent(final PlayerDeathEvent event) {
|
||||
final Entity entity = event.getEntity();
|
||||
if (entity.hasMetadata("NPC")) {
|
||||
return;
|
||||
}
|
||||
final User user = ess.getUser(event.getEntity());
|
||||
if (ess.getSettings().infoAfterDeath()) {
|
||||
final Location loc = user.getLocation();
|
||||
user.sendMessage(tl("infoAfterDeath", loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
|
||||
}
|
||||
if (user.isAuthorized("essentials.back.ondeath") && !ess.getSettings().isCommandDisabled("back")) {
|
||||
user.setLastLocation();
|
||||
user.sendMessage(tl("backAfterDeath"));
|
||||
@@ -164,6 +193,58 @@ public class EssentialsEntityListener implements Listener {
|
||||
final User user = ess.getUser(event.getEntity());
|
||||
if (user.isAuthorized("essentials.keepinv")) {
|
||||
event.setKeepInventory(true);
|
||||
event.getDrops().clear();
|
||||
final ISettings.KeepInvPolicy vanish = ess.getSettings().getVanishingItemsPolicy();
|
||||
final ISettings.KeepInvPolicy bind = ess.getSettings().getBindingItemsPolicy();
|
||||
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_11_2_R01) && (vanish != ISettings.KeepInvPolicy.KEEP || bind != ISettings.KeepInvPolicy.KEEP)) {
|
||||
for (final ItemStack stack : event.getEntity().getInventory()) {
|
||||
if (stack != null) {
|
||||
if (stack.getEnchantments().containsKey(Enchantment.VANISHING_CURSE)) {
|
||||
if (vanish == ISettings.KeepInvPolicy.DELETE) {
|
||||
event.getEntity().getInventory().remove(stack);
|
||||
} else if (vanish == ISettings.KeepInvPolicy.DROP) {
|
||||
event.getDrops().add(stack);
|
||||
event.getEntity().getInventory().remove(stack);
|
||||
}
|
||||
}
|
||||
if (stack.getEnchantments().containsKey(Enchantment.BINDING_CURSE)) {
|
||||
if (bind == ISettings.KeepInvPolicy.DELETE) {
|
||||
event.getEntity().getInventory().remove(stack);
|
||||
} else if (bind == ISettings.KeepInvPolicy.DROP) {
|
||||
event.getEntity().getInventory().remove(stack);
|
||||
event.getDrops().add(stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
final ItemStack[] armor = event.getEntity().getInventory().getArmorContents();
|
||||
for (int i = 0; i < armor.length; i++) {
|
||||
final ItemStack stack = armor[i];
|
||||
if (stack != null) {
|
||||
if (stack.getEnchantments().containsKey(Enchantment.VANISHING_CURSE)) {
|
||||
if (vanish == ISettings.KeepInvPolicy.DELETE) {
|
||||
armor[i] = null;
|
||||
} else if (vanish == ISettings.KeepInvPolicy.DROP) {
|
||||
if (!event.getDrops().contains(stack)) {
|
||||
event.getDrops().add(stack);
|
||||
}
|
||||
armor[i] = null;
|
||||
}
|
||||
}
|
||||
if (stack.getEnchantments().containsKey(Enchantment.BINDING_CURSE)) {
|
||||
if (bind == ISettings.KeepInvPolicy.DELETE) {
|
||||
armor[i] = null;
|
||||
} else if (bind == ISettings.KeepInvPolicy.DROP) {
|
||||
if (!event.getDrops().contains(stack)) {
|
||||
event.getDrops().add(stack);
|
||||
}
|
||||
armor[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
event.getEntity().getInventory().setArmorContents(armor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +271,7 @@ public class EssentialsEntityListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onPotionSplashEvent(final PotionSplashEvent event) {
|
||||
for (LivingEntity entity : event.getAffectedEntities()) {
|
||||
for (final LivingEntity entity : event.getAffectedEntities()) {
|
||||
if (entity instanceof Player && ess.getUser((Player) entity).isGodModeEnabled()) {
|
||||
event.setIntensity(entity, 0d);
|
||||
}
|
||||
@@ -198,7 +279,7 @@ public class EssentialsEntityListener implements Listener {
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onEntityShootBow(EntityShootBowEvent event) {
|
||||
public void onEntityShootBow(final EntityShootBowEvent event) {
|
||||
if (event.getEntity() instanceof Player) {
|
||||
final User user = ess.getUser((Player) event.getEntity());
|
||||
if (user.isAfk()) {
|
||||
@@ -208,7 +289,7 @@ public class EssentialsEntityListener implements Listener {
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onEntityTarget(EntityTargetEvent event) {
|
||||
public void onEntityTarget(final EntityTargetEvent event) {
|
||||
if (event.getTarget() instanceof Player) {
|
||||
final User user = ess.getUser((Player) event.getTarget());
|
||||
if (user.isVanished()) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.commands.Commandfireball;
|
||||
import com.earth2me.essentials.textreader.IText;
|
||||
import com.earth2me.essentials.textreader.KeywordReplacer;
|
||||
import com.earth2me.essentials.textreader.TextInput;
|
||||
@@ -7,9 +8,16 @@ import com.earth2me.essentials.textreader.TextPager;
|
||||
import com.earth2me.essentials.utils.DateUtil;
|
||||
import com.earth2me.essentials.utils.LocationUtil;
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import net.ess3.api.IEssentials;
|
||||
import org.bukkit.*;
|
||||
import net.ess3.api.events.AfkStatusChangeEvent;
|
||||
import org.bukkit.BanEntry;
|
||||
import org.bukkit.BanList;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -20,8 +28,21 @@ import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.event.player.*;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.event.player.PlayerBucketEmptyEvent;
|
||||
import org.bukkit.event.player.PlayerChangedWorldEvent;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
import org.bukkit.event.player.PlayerCommandSendEvent;
|
||||
import org.bukkit.event.player.PlayerEggThrowEvent;
|
||||
import org.bukkit.event.player.PlayerFishEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerLoginEvent;
|
||||
import org.bukkit.event.player.PlayerLoginEvent.Result;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.player.PlayerRespawnEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
@@ -29,16 +50,23 @@ import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class EssentialsPlayerListener implements Listener {
|
||||
private static final Logger LOGGER = Logger.getLogger("Essentials");
|
||||
private final transient IEssentials ess;
|
||||
@@ -47,9 +75,40 @@ public class EssentialsPlayerListener implements Listener {
|
||||
this.ess = parent;
|
||||
}
|
||||
|
||||
private static boolean isEntityPickupEvent() {
|
||||
try {
|
||||
Class.forName("org.bukkit.event.entity.EntityPickupItemEvent");
|
||||
return true;
|
||||
} catch (final ClassNotFoundException ignored) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isCommandSendEvent() {
|
||||
try {
|
||||
Class.forName("org.bukkit.event.player.PlayerCommandSendEvent");
|
||||
return true;
|
||||
} catch (final ClassNotFoundException ignored) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isArrowPickupEvent() {
|
||||
try {
|
||||
Class.forName("org.bukkit.event.player.PlayerPickupArrowEvent");
|
||||
return true;
|
||||
} catch (final ClassNotFoundException ignored) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void registerEvents() {
|
||||
ess.getServer().getPluginManager().registerEvents(this, ess);
|
||||
|
||||
if (isArrowPickupEvent()) {
|
||||
ess.getServer().getPluginManager().registerEvents(new ArrowPickupListener(), ess);
|
||||
}
|
||||
|
||||
if (isEntityPickupEvent()) {
|
||||
ess.getServer().getPluginManager().registerEvents(new PickupListener1_12(), ess);
|
||||
} else {
|
||||
@@ -78,7 +137,12 @@ public class EssentialsPlayerListener implements Listener {
|
||||
if (user.isMuted()) {
|
||||
event.setCancelled(true);
|
||||
|
||||
user.sendMessage(user.hasMuteReason() ? tl("voiceSilencedReason", user.getMuteReason()) : tl("voiceSilenced"));
|
||||
final String dateDiff = user.getMuteTimeout() > 0 ? DateUtil.formatDateDiff(user.getMuteTimeout()) : null;
|
||||
if (dateDiff == null) {
|
||||
user.sendMessage(user.hasMuteReason() ? tl("voiceSilencedReason", user.getMuteReason()) : tl("voiceSilenced"));
|
||||
} else {
|
||||
user.sendMessage(user.hasMuteReason() ? tl("voiceSilencedReasonTime", dateDiff, user.getMuteReason()) : tl("voiceSilencedTime", dateDiff));
|
||||
}
|
||||
|
||||
LOGGER.info(tl("mutedUserSpeaks", user.getName(), event.getMessage()));
|
||||
}
|
||||
@@ -90,7 +154,7 @@ public class EssentialsPlayerListener implements Listener {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
} catch (UnsupportedOperationException ex) {
|
||||
} catch (final UnsupportedOperationException ex) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "Ignore could not block chat due to custom chat plugin event.", ex);
|
||||
} else {
|
||||
@@ -132,7 +196,7 @@ public class EssentialsPlayerListener implements Listener {
|
||||
to.setZ(from.getZ());
|
||||
try {
|
||||
event.setTo(LocationUtil.getSafeDestination(to));
|
||||
} catch (Exception ex) {
|
||||
} catch (final Exception ex) {
|
||||
event.setTo(to);
|
||||
}
|
||||
return;
|
||||
@@ -147,15 +211,16 @@ public class EssentialsPlayerListener implements Listener {
|
||||
public void onPlayerQuit(final PlayerQuitEvent event) {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
|
||||
if (ess.getSettings().allowSilentJoinQuit() && user.isAuthorized("essentials.silentquit")) {
|
||||
if (hideJoinQuitMessages() || (ess.getSettings().allowSilentJoinQuit() && user.isAuthorized("essentials.silentquit"))) {
|
||||
event.setQuitMessage(null);
|
||||
} else if (ess.getSettings().isCustomQuitMessage() && event.getQuitMessage() != null) {
|
||||
final Player player = event.getPlayer();
|
||||
final String msg = ess.getSettings().getCustomQuitMessage()
|
||||
.replace("{PLAYER}", player.getDisplayName())
|
||||
.replace("{USERNAME}", player.getName())
|
||||
.replace("{ONLINE}", NumberFormat.getInstance().format(ess.getOnlinePlayers().size()));
|
||||
|
||||
.replace("{PLAYER}", player.getDisplayName())
|
||||
.replace("{USERNAME}", player.getName())
|
||||
.replace("{ONLINE}", NumberFormat.getInstance().format(ess.getOnlinePlayers().size()))
|
||||
.replace("{UPTIME}", DateUtil.formatDateDiff(ManagementFactory.getRuntimeMXBean().getStartTime()));
|
||||
|
||||
event.setQuitMessage(msg.isEmpty() ? null : msg);
|
||||
}
|
||||
|
||||
@@ -171,16 +236,17 @@ public class EssentialsPlayerListener implements Listener {
|
||||
user.getBase().getOpenInventory().getTopInventory().clear();
|
||||
}
|
||||
|
||||
for (HumanEntity viewer : user.getBase().getInventory().getViewers()) {
|
||||
final ArrayList<HumanEntity> viewers = new ArrayList<>(user.getBase().getInventory().getViewers());
|
||||
for (final HumanEntity viewer : viewers) {
|
||||
if (viewer instanceof Player) {
|
||||
User uviewer = ess.getUser((Player) viewer);
|
||||
final User uviewer = ess.getUser((Player) viewer);
|
||||
if (uviewer.isInvSee()) {
|
||||
uviewer.getBase().closeInventory();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
user.updateActivity(false);
|
||||
user.updateActivity(false, AfkStatusChangeEvent.Cause.QUIT);
|
||||
if (!user.isHidden()) {
|
||||
user.setLastLogout(System.currentTimeMillis());
|
||||
}
|
||||
@@ -192,17 +258,17 @@ public class EssentialsPlayerListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onPlayerJoin(final PlayerJoinEvent event) {
|
||||
final String joinMessage = event.getJoinMessage();
|
||||
ess.runTaskAsynchronously(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
delayedJoin(event.getPlayer(), joinMessage);
|
||||
}
|
||||
});
|
||||
if (ess.getSettings().allowSilentJoinQuit() || ess.getSettings().isCustomJoinMessage()) {
|
||||
ess.runTaskAsynchronously(() -> delayedJoin(event.getPlayer(), joinMessage));
|
||||
|
||||
if (hideJoinQuitMessages() || ess.getSettings().allowSilentJoinQuit() || ess.getSettings().isCustomJoinMessage()) {
|
||||
event.setJoinMessage(null);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hideJoinQuitMessages() {
|
||||
return ess.getSettings().hasJoinQuitMessagePlayerCount() && ess.getServer().getOnlinePlayers().size() > ess.getSettings().getJoinQuitMessagePlayerCount();
|
||||
}
|
||||
|
||||
public void delayedJoin(final Player player, final String message) {
|
||||
if (!player.isOnline()) {
|
||||
return;
|
||||
@@ -218,7 +284,7 @@ public class EssentialsPlayerListener implements Listener {
|
||||
|
||||
final long currentTime = System.currentTimeMillis();
|
||||
dUser.checkMuteTimeout(currentTime);
|
||||
dUser.updateActivity(false);
|
||||
dUser.updateActivity(false, AfkStatusChangeEvent.Cause.JOIN);
|
||||
dUser.stopTransaction();
|
||||
|
||||
class DelayJoinTask implements Runnable {
|
||||
@@ -238,8 +304,8 @@ public class EssentialsPlayerListener implements Listener {
|
||||
updateCompass(user);
|
||||
|
||||
if (!ess.getVanishedPlayersNew().isEmpty() && !user.isAuthorized("essentials.vanish.see")) {
|
||||
for (String p : ess.getVanishedPlayersNew()) {
|
||||
Player toVanish = ess.getServer().getPlayerExact(p);
|
||||
for (final String p : ess.getVanishedPlayersNew()) {
|
||||
final Player toVanish = ess.getServer().getPlayerExact(p);
|
||||
if (toVanish != null && toVanish.isOnline()) {
|
||||
user.getBase().hidePlayer(toVanish);
|
||||
if (ess.getSettings().isDebug()) {
|
||||
@@ -257,13 +323,14 @@ public class EssentialsPlayerListener implements Listener {
|
||||
if (user.isAuthorized("essentials.silentjoin.vanish")) {
|
||||
user.setVanished(true);
|
||||
}
|
||||
} else if (message == null) {
|
||||
} else if (message == null || hideJoinQuitMessages()) {
|
||||
//NOOP
|
||||
} else if (ess.getSettings().isCustomJoinMessage()) {
|
||||
String msg = ess.getSettings().getCustomJoinMessage()
|
||||
final String msg = ess.getSettings().getCustomJoinMessage()
|
||||
.replace("{PLAYER}", player.getDisplayName()).replace("{USERNAME}", player.getName())
|
||||
.replace("{UNIQUE}", NumberFormat.getInstance().format(ess.getUserMap().getUniqueUsers()))
|
||||
.replace("{ONLINE}", NumberFormat.getInstance().format(ess.getOnlinePlayers().size()));
|
||||
.replace("{ONLINE}", NumberFormat.getInstance().format(ess.getOnlinePlayers().size()))
|
||||
.replace("{UPTIME}", DateUtil.formatDateDiff(ManagementFactory.getRuntimeMXBean().getStartTime()));
|
||||
if (!msg.isEmpty()) {
|
||||
ess.getServer().broadcastMessage(msg);
|
||||
}
|
||||
@@ -271,8 +338,8 @@ public class EssentialsPlayerListener implements Listener {
|
||||
ess.getServer().broadcastMessage(message);
|
||||
}
|
||||
|
||||
int motdDelay = ess.getSettings().getMotdDelay() / 50;
|
||||
DelayMotdTask motdTask = new DelayMotdTask(user);
|
||||
final int motdDelay = ess.getSettings().getMotdDelay() / 50;
|
||||
final DelayMotdTask motdTask = new DelayMotdTask(user);
|
||||
if (motdDelay > 0) {
|
||||
ess.scheduleSyncDelayedTask(motdTask, motdDelay);
|
||||
} else {
|
||||
@@ -315,7 +382,7 @@ public class EssentialsPlayerListener implements Listener {
|
||||
user.setGodModeEnabled(false);
|
||||
ess.getLogger().log(Level.INFO, "Set god mode to false for {0} because they had it enabled without permission.", user.getName());
|
||||
}
|
||||
|
||||
|
||||
user.setConfirmingClearCommand(null);
|
||||
user.getConfirmingPayments().clear();
|
||||
|
||||
@@ -323,9 +390,9 @@ public class EssentialsPlayerListener implements Listener {
|
||||
}
|
||||
|
||||
class DelayMotdTask implements Runnable {
|
||||
private User user;
|
||||
private final User user;
|
||||
|
||||
public DelayMotdTask(User user) {
|
||||
DelayMotdTask(final User user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
@@ -336,7 +403,7 @@ public class EssentialsPlayerListener implements Listener {
|
||||
if (!ess.getSettings().isCommandDisabled("motd")) {
|
||||
try {
|
||||
tempInput = new TextInput(user.getSource(), "motd", true, ess);
|
||||
} catch (IOException ex) {
|
||||
} catch (final IOException ex) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
LOGGER.log(Level.WARNING, ex.getMessage(), ex);
|
||||
} else {
|
||||
@@ -364,53 +431,48 @@ public class EssentialsPlayerListener implements Listener {
|
||||
private void updateCompass(final User user) {
|
||||
if (ess.getSettings().isCompassTowardsHomePerm() && !user.isAuthorized("essentials.home.compass")) return;
|
||||
|
||||
Location loc = user.getHome(user.getLocation());
|
||||
final Location loc = user.getHome(user.getLocation());
|
||||
if (loc == null) {
|
||||
loc = user.getBase().getBedSpawnLocation();
|
||||
}
|
||||
if (loc != null) {
|
||||
user.getBase().setCompassTarget(loc);
|
||||
PaperLib.getBedSpawnLocationAsync(user.getBase(), false).thenAccept(location -> {
|
||||
if (location != null) {
|
||||
user.getBase().setCompassTarget(location);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
user.getBase().setCompassTarget(loc);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onPlayerLoginBanned(final PlayerLoginEvent event) {
|
||||
switch (event.getResult()) {
|
||||
case KICK_BANNED:
|
||||
BanEntry banEntry = ess.getServer().getBanList(BanList.Type.NAME).getBanEntry(event.getPlayer().getName());
|
||||
if (banEntry != null) {
|
||||
Date banExpiry = banEntry.getExpiration();
|
||||
if (banExpiry != null) {
|
||||
String expiry = DateUtil.formatDateDiff(banExpiry.getTime());
|
||||
event.setKickMessage(tl("tempbanJoin", expiry, banEntry.getReason()));
|
||||
} else {
|
||||
event.setKickMessage(tl("banJoin", banEntry.getReason()));
|
||||
}
|
||||
if (event.getResult() == Result.KICK_BANNED) {
|
||||
BanEntry banEntry = ess.getServer().getBanList(BanList.Type.NAME).getBanEntry(event.getPlayer().getName());
|
||||
if (banEntry != null) {
|
||||
final Date banExpiry = banEntry.getExpiration();
|
||||
if (banExpiry != null) {
|
||||
final String expiry = DateUtil.formatDateDiff(banExpiry.getTime());
|
||||
event.setKickMessage(tl("tempbanJoin", expiry, banEntry.getReason()));
|
||||
} else {
|
||||
banEntry = ess.getServer().getBanList(BanList.Type.IP).getBanEntry(event.getAddress().getHostAddress());
|
||||
if (banEntry != null) {
|
||||
event.setKickMessage(tl("banIpJoin", banEntry.getReason()));
|
||||
}
|
||||
event.setKickMessage(tl("banJoin", banEntry.getReason()));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
} else {
|
||||
banEntry = ess.getServer().getBanList(BanList.Type.IP).getBanEntry(event.getAddress().getHostAddress());
|
||||
if (banEntry != null) {
|
||||
event.setKickMessage(tl("banIpJoin", banEntry.getReason()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onPlayerLogin(final PlayerLoginEvent event) {
|
||||
switch (event.getResult()) {
|
||||
case KICK_FULL:
|
||||
final User kfuser = ess.getUser(event.getPlayer());
|
||||
if (kfuser.isAuthorized("essentials.joinfullserver")) {
|
||||
event.allow();
|
||||
return;
|
||||
}
|
||||
event.disallow(Result.KICK_FULL, tl("serverFull"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (event.getResult() == Result.KICK_FULL) {
|
||||
final User kfuser = ess.getUser(event.getPlayer());
|
||||
if (kfuser.isAuthorized("essentials.joinfullserver")) {
|
||||
event.allow();
|
||||
return;
|
||||
}
|
||||
event.disallow(Result.KICK_FULL, tl("serverFull"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,9 +481,13 @@ public class EssentialsPlayerListener implements Listener {
|
||||
final boolean backListener = ess.getSettings().registerBackInListener();
|
||||
final boolean teleportInvulnerability = ess.getSettings().isTeleportInvulnerability();
|
||||
if (backListener || teleportInvulnerability) {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
final Player player = event.getPlayer();
|
||||
if (player.hasMetadata("NPC")) {
|
||||
return;
|
||||
}
|
||||
final User user = ess.getUser(player);
|
||||
//There is TeleportCause.COMMMAND but plugins have to actively pass the cause in on their teleports.
|
||||
if (backListener && (event.getCause() == TeleportCause.PLUGIN || event.getCause() == TeleportCause.COMMAND)) {
|
||||
if (user.isAuthorized("essentials.back.onteleport") && backListener && (event.getCause() == TeleportCause.PLUGIN || event.getCause() == TeleportCause.COMMAND)) {
|
||||
user.setLastLocation();
|
||||
}
|
||||
if (teleportInvulnerability && (event.getCause() == TeleportCause.PLUGIN || event.getCause() == TeleportCause.COMMAND)) {
|
||||
@@ -445,12 +511,7 @@ public class EssentialsPlayerListener implements Listener {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (user.hasUnlimited(new ItemStack(event.getBucket()))) {
|
||||
event.getItemStack().setType(event.getBucket());
|
||||
ess.scheduleSyncDelayedTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
user.getBase().updateInventory();
|
||||
}
|
||||
});
|
||||
ess.scheduleSyncDelayedTask(user.getBase()::updateInventory);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -459,14 +520,14 @@ public class EssentialsPlayerListener implements Listener {
|
||||
final Player player = event.getPlayer();
|
||||
final String cmd = event.getMessage().toLowerCase(Locale.ENGLISH).split(" ")[0].replace("/", "").toLowerCase(Locale.ENGLISH);
|
||||
|
||||
PluginCommand pluginCommand = ess.getServer().getPluginCommand(cmd);
|
||||
final PluginCommand pluginCommand = ess.getServer().getPluginCommand(cmd);
|
||||
|
||||
if (ess.getSettings().getSocialSpyCommands().contains(cmd) || ess.getSettings().getSocialSpyCommands().contains("*")) {
|
||||
if (pluginCommand == null
|
||||
|| (!pluginCommand.getName().equals("msg") && !pluginCommand.getName().equals("r"))) { // /msg and /r are handled in SimpleMessageRecipient
|
||||
User user = ess.getUser(player);
|
||||
|| (!pluginCommand.getName().equals("msg") && !pluginCommand.getName().equals("r"))) { // /msg and /r are handled in SimpleMessageRecipient
|
||||
final User user = ess.getUser(player);
|
||||
if (!user.isAuthorized("essentials.chat.spy.exempt")) {
|
||||
for (User spyer : ess.getOnlineUsers()) {
|
||||
for (final User spyer : ess.getOnlineUsers()) {
|
||||
if (spyer.isSocialSpyEnabled() && !player.equals(spyer.getBase())) {
|
||||
if (user.isMuted() && ess.getSettings().getSocialSpyListenMutedPlayers()) {
|
||||
spyer.sendMessage(tl("socialSpyMutedPrefix") + player.getDisplayName() + ": " + event.getMessage());
|
||||
@@ -479,13 +540,19 @@ public class EssentialsPlayerListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
if (ess.getUser(player).isMuted() && (ess.getSettings().getMuteCommands().contains(cmd) || ess.getSettings().getMuteCommands().contains("*"))) {
|
||||
final User user = ess.getUser(player);
|
||||
if (user.isMuted() && (ess.getSettings().getMuteCommands().contains(cmd) || ess.getSettings().getMuteCommands().contains("*"))) {
|
||||
event.setCancelled(true);
|
||||
player.sendMessage(tl("voiceSilenced"));
|
||||
final String dateDiff = user.getMuteTimeout() > 0 ? DateUtil.formatDateDiff(user.getMuteTimeout()) : null;
|
||||
if (dateDiff == null) {
|
||||
player.sendMessage(user.hasMuteReason() ? tl("voiceSilencedReason", user.getMuteReason()) : tl("voiceSilenced"));
|
||||
} else {
|
||||
player.sendMessage(user.hasMuteReason() ? tl("voiceSilencedReasonTime", dateDiff, user.getMuteReason()) : tl("voiceSilencedTime", dateDiff));
|
||||
}
|
||||
LOGGER.info(tl("mutedUserSpeaks", player.getName(), event.getMessage()));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
boolean broadcast = true; // whether to broadcast the updated activity
|
||||
boolean update = true; // Only modified when the command is afk
|
||||
|
||||
@@ -494,28 +561,30 @@ public class EssentialsPlayerListener implements Listener {
|
||||
switch (pluginCommand.getName()) {
|
||||
case "afk":
|
||||
update = false;
|
||||
// fall through
|
||||
case "vanish":
|
||||
broadcast = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
final User user = ess.getUser(player);
|
||||
|
||||
if (update) {
|
||||
user.updateActivityOnInteract(broadcast);
|
||||
}
|
||||
|
||||
if (ess.getSettings().isCommandCooldownsEnabled() && pluginCommand != null
|
||||
&& !user.isAuthorized("essentials.commandcooldowns.bypass")) {
|
||||
int argStartIndex = event.getMessage().indexOf(" ");
|
||||
String args = argStartIndex == -1 ? "" // No arguments present
|
||||
final int argStartIndex = event.getMessage().indexOf(" ");
|
||||
final String args = argStartIndex == -1 ? "" // No arguments present
|
||||
: " " + event.getMessage().substring(argStartIndex); // arguments start at argStartIndex; substring from there.
|
||||
String fullCommand = pluginCommand.getName() + args;
|
||||
final String fullCommand = pluginCommand.getName() + args;
|
||||
|
||||
// Used to determine whether a user already has an existing cooldown
|
||||
// If so, no need to check for (and write) new ones.
|
||||
boolean cooldownFound = false;
|
||||
|
||||
|
||||
// Iterate over a copy of getCommandCooldowns in case of concurrent modifications
|
||||
for (Entry<Pattern, Long> entry : new HashMap<>(user.getCommandCooldowns()).entrySet()) {
|
||||
for (final Entry<Pattern, Long> entry : new HashMap<>(user.getCommandCooldowns()).entrySet()) {
|
||||
// Remove any expired cooldowns
|
||||
if (entry.getValue() <= System.currentTimeMillis()) {
|
||||
user.clearCommandCooldown(entry.getKey());
|
||||
@@ -523,7 +592,7 @@ public class EssentialsPlayerListener implements Listener {
|
||||
} else if (entry.getKey().matcher(fullCommand).matches()) {
|
||||
// User's current cooldown hasn't expired, inform and terminate cooldown code.
|
||||
if (entry.getValue() > System.currentTimeMillis()) {
|
||||
String commandCooldownTime = DateUtil.formatDateDiff(entry.getValue());
|
||||
final String commandCooldownTime = DateUtil.formatDateDiff(entry.getValue());
|
||||
user.sendMessage(tl("commandCooldown", commandCooldownTime));
|
||||
cooldownFound = true;
|
||||
event.setCancelled(true);
|
||||
@@ -533,13 +602,13 @@ public class EssentialsPlayerListener implements Listener {
|
||||
}
|
||||
|
||||
if (!cooldownFound) {
|
||||
Entry<Pattern, Long> cooldownEntry = ess.getSettings().getCommandCooldownEntry(fullCommand);
|
||||
final Entry<Pattern, Long> cooldownEntry = ess.getSettings().getCommandCooldownEntry(fullCommand);
|
||||
|
||||
if (cooldownEntry != null) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().info("Applying " + cooldownEntry.getValue() + "ms cooldown on /" + fullCommand + " for" + user.getName() + ".");
|
||||
}
|
||||
Date expiry = new Date(System.currentTimeMillis() + cooldownEntry.getValue());
|
||||
final Date expiry = new Date(System.currentTimeMillis() + cooldownEntry.getValue());
|
||||
user.addCommandCooldown(cooldownEntry.getKey(), expiry, ess.getSettings().isCommandCooldownPersistent(fullCommand));
|
||||
}
|
||||
}
|
||||
@@ -549,27 +618,31 @@ public class EssentialsPlayerListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.NORMAL)
|
||||
public void onPlayerChangedWorldFlyReset(final PlayerChangedWorldEvent event) {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (user.getBase().getGameMode() != GameMode.CREATIVE
|
||||
// COMPAT: String compare for 1.7.10
|
||||
&& !user.getBase().getGameMode().name().equals("SPECTATOR")
|
||||
&& !user.isAuthorized("essentials.fly")) {
|
||||
user.getBase().setFallDistance(0f);
|
||||
user.getBase().setAllowFlight(false);
|
||||
}
|
||||
if (!user.isAuthorized("essentials.speed")) {
|
||||
user.getBase().setFlySpeed(0.1f);
|
||||
user.getBase().setWalkSpeed(0.2f);
|
||||
} else {
|
||||
if (user.getBase().getFlySpeed() > ess.getSettings().getMaxFlySpeed() && !user.isAuthorized("essentials.speed.bypass")) {
|
||||
user.getBase().setFlySpeed((float) ess.getSettings().getMaxFlySpeed());
|
||||
} else {
|
||||
user.getBase().setFlySpeed(user.getBase().getFlySpeed() * 0.99999f);
|
||||
}
|
||||
|
||||
if (user.getBase().getWalkSpeed() > ess.getSettings().getMaxWalkSpeed() && !user.isAuthorized("essentials.speed.bypass")) {
|
||||
user.getBase().setWalkSpeed((float) ess.getSettings().getMaxWalkSpeed());
|
||||
if (ess.getSettings().isWorldChangeFlyResetEnabled()) {
|
||||
if (user.getBase().getGameMode() != GameMode.CREATIVE
|
||||
// COMPAT: String compare for 1.7.10
|
||||
&& !user.getBase().getGameMode().name().equals("SPECTATOR")
|
||||
&& !user.isAuthorized("essentials.fly")) {
|
||||
user.getBase().setFallDistance(0f);
|
||||
user.getBase().setAllowFlight(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (ess.getSettings().isWorldChangeSpeedResetEnabled()) {
|
||||
if (!user.isAuthorized("essentials.speed")) {
|
||||
user.getBase().setFlySpeed(0.1f);
|
||||
user.getBase().setWalkSpeed(0.2f);
|
||||
} else {
|
||||
user.getBase().setWalkSpeed(user.getBase().getWalkSpeed() * 0.99999f);
|
||||
if (user.getBase().getFlySpeed() > ess.getSettings().getMaxFlySpeed() && !user.isAuthorized("essentials.speed.bypass")) {
|
||||
user.getBase().setFlySpeed((float) ess.getSettings().getMaxFlySpeed());
|
||||
} else {
|
||||
user.getBase().setFlySpeed(user.getBase().getFlySpeed() * 0.99999f);
|
||||
}
|
||||
|
||||
if (user.getBase().getWalkSpeed() > ess.getSettings().getMaxWalkSpeed() && !user.isAuthorized("essentials.speed.bypass")) {
|
||||
user.getBase().setWalkSpeed((float) ess.getSettings().getMaxWalkSpeed());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -601,10 +674,13 @@ public class EssentialsPlayerListener implements Listener {
|
||||
switch (event.getAction()) {
|
||||
case RIGHT_CLICK_BLOCK:
|
||||
if (!event.isCancelled() && MaterialUtil.isBed(event.getClickedBlock().getType()) && ess.getSettings().getUpdateBedAtDaytime()) {
|
||||
User player = ess.getUser(event.getPlayer());
|
||||
final User player = ess.getUser(event.getPlayer());
|
||||
if (player.isAuthorized("essentials.sethome.bed") && player.getWorld().getEnvironment().equals(World.Environment.NORMAL)) {
|
||||
player.getBase().setBedSpawnLocation(event.getClickedBlock().getLocation());
|
||||
player.sendMessage(tl("bedSet", player.getLocation().getWorld().getName(), player.getLocation().getBlockX(), player.getLocation().getBlockY(), player.getLocation().getBlockZ()));
|
||||
// In 1.15 and above, vanilla sends its own bed spawn message.
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_15_R01)) {
|
||||
player.sendMessage(tl("bedSet", player.getLocation().getWorld().getName(), player.getLocation().getBlockX(), player.getLocation().getBlockY(), player.getLocation().getBlockZ()));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -616,6 +692,7 @@ public class EssentialsPlayerListener implements Listener {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
case LEFT_CLICK_BLOCK:
|
||||
if (event.getItem() != null && event.getItem().getType() != Material.AIR) {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
@@ -627,6 +704,8 @@ public class EssentialsPlayerListener implements Listener {
|
||||
case PHYSICAL:
|
||||
updateActivity = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (updateActivity) {
|
||||
@@ -642,7 +721,7 @@ public class EssentialsPlayerListener implements Listener {
|
||||
class DelayedClickJumpTask implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
Location loc = user.getLocation();
|
||||
final Location loc = user.getLocation();
|
||||
loc.setX(otarget.getX());
|
||||
loc.setZ(otarget.getZ());
|
||||
while (LocationUtil.isBlockDamaging(loc.getWorld(), loc.getBlockX(), loc.getBlockY() - 1, loc.getBlockZ())) {
|
||||
@@ -651,8 +730,9 @@ public class EssentialsPlayerListener implements Listener {
|
||||
PaperLib.teleportAsync(user.getBase(), loc, TeleportCause.PLUGIN);
|
||||
}
|
||||
}
|
||||
|
||||
ess.scheduleSyncDelayedTask(new DelayedClickJumpTask());
|
||||
} catch (Exception ex) {
|
||||
} catch (final Exception ex) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
LOGGER.log(Level.WARNING, ex.getMessage(), ex);
|
||||
}
|
||||
@@ -668,7 +748,6 @@ public class EssentialsPlayerListener implements Listener {
|
||||
// We need to loop through each command and execute
|
||||
for (final String command : commandList) {
|
||||
if (command.contains("{player}")) {
|
||||
continue;
|
||||
} else if (command.startsWith("c:")) {
|
||||
used = true;
|
||||
user.getBase().chat(command.substring(2));
|
||||
@@ -682,6 +761,7 @@ public class EssentialsPlayerListener implements Listener {
|
||||
LOGGER.log(Level.INFO, String.format("[PT] %s issued server command: /%s", user.getName(), command));
|
||||
}
|
||||
}
|
||||
|
||||
ess.scheduleSyncDelayedTask(new PowerToolUseTask());
|
||||
|
||||
}
|
||||
@@ -705,7 +785,7 @@ public class EssentialsPlayerListener implements Listener {
|
||||
if (type == InventoryType.PLAYER) {
|
||||
final User user = ess.getUser((Player) event.getWhoClicked());
|
||||
final InventoryHolder invHolder = top.getHolder();
|
||||
if (invHolder != null && invHolder instanceof HumanEntity) {
|
||||
if (invHolder instanceof HumanEntity) {
|
||||
final User invOwner = ess.getUser((Player) invHolder);
|
||||
if (user.isInvSee() && (!user.isAuthorized("essentials.invsee.modify") || invOwner.isAuthorized("essentials.invsee.preventmodify") || !invOwner.getBase().isOnline())) {
|
||||
event.setCancelled(true);
|
||||
@@ -714,12 +794,12 @@ public class EssentialsPlayerListener implements Listener {
|
||||
}
|
||||
} else if (type == InventoryType.ENDER_CHEST) {
|
||||
final User user = ess.getUser((Player) event.getWhoClicked());
|
||||
if (user.isEnderSee() && (!user.isAuthorized("essentials.enderchest.modify"))) {
|
||||
if (user.isEnderSee() && !user.isAuthorized("essentials.enderchest.modify")) {
|
||||
event.setCancelled(true);
|
||||
refreshPlayer = user.getBase();
|
||||
}
|
||||
} else if (type == InventoryType.WORKBENCH) {
|
||||
User user = ess.getUser((Player) event.getWhoClicked());
|
||||
final User user = ess.getUser((Player) event.getWhoClicked());
|
||||
if (user.isRecipeSee()) {
|
||||
event.setCancelled(true);
|
||||
refreshPlayer = user.getBase();
|
||||
@@ -727,7 +807,7 @@ public class EssentialsPlayerListener implements Listener {
|
||||
} else if (type == InventoryType.CHEST && top.getSize() == 9) {
|
||||
final User user = ess.getUser((Player) event.getWhoClicked());
|
||||
final InventoryHolder invHolder = top.getHolder();
|
||||
if (invHolder != null && invHolder instanceof HumanEntity && user.isInvSee()) {
|
||||
if (invHolder instanceof HumanEntity && user.isInvSee()) {
|
||||
event.setCancelled(true);
|
||||
refreshPlayer = user.getBase();
|
||||
}
|
||||
@@ -735,7 +815,7 @@ public class EssentialsPlayerListener implements Listener {
|
||||
if (ess.getSettings().isDirectHatAllowed() && event.getClick() == ClickType.LEFT && event.getSlot() == 39
|
||||
&& event.getCursor().getType() != Material.AIR && event.getCursor().getType().getMaxDurability() == 0
|
||||
&& !MaterialUtil.isSkull(event.getCursor().getType())
|
||||
&& ess.getUser(event.getWhoClicked()).isAuthorized("essentials.hat")) {
|
||||
&& ess.getUser(event.getWhoClicked()).isAuthorized("essentials.hat") && !ess.getUser(event.getWhoClicked()).isAuthorized("essentials.hat.prevent-type." + event.getCursor().getType().name().toLowerCase())) {
|
||||
event.setCancelled(true);
|
||||
final PlayerInventory inv = (PlayerInventory) clickedInventory;
|
||||
final ItemStack head = inv.getHelmet();
|
||||
@@ -745,13 +825,7 @@ public class EssentialsPlayerListener implements Listener {
|
||||
}
|
||||
|
||||
if (refreshPlayer != null) {
|
||||
final Player player = refreshPlayer;
|
||||
ess.scheduleSyncDelayedTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
player.updateInventory();
|
||||
}
|
||||
}, 1);
|
||||
ess.scheduleSyncDelayedTask(refreshPlayer::updateInventory, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -777,7 +851,7 @@ public class EssentialsPlayerListener implements Listener {
|
||||
}
|
||||
} else if (type == InventoryType.CHEST && top.getSize() == 9) {
|
||||
final InventoryHolder invHolder = top.getHolder();
|
||||
if (invHolder != null && invHolder instanceof HumanEntity) {
|
||||
if (invHolder instanceof HumanEntity) {
|
||||
final User user = ess.getUser((Player) event.getPlayer());
|
||||
user.setInvSee(false);
|
||||
refreshPlayer = user.getBase();
|
||||
@@ -785,44 +859,31 @@ public class EssentialsPlayerListener implements Listener {
|
||||
}
|
||||
|
||||
if (refreshPlayer != null) {
|
||||
final Player player = refreshPlayer;
|
||||
ess.scheduleSyncDelayedTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
player.updateInventory();
|
||||
}
|
||||
}, 1);
|
||||
ess.scheduleSyncDelayedTask(refreshPlayer::updateInventory, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onPlayerFishEvent(final PlayerFishEvent event) {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
user.updateActivityOnInteract(true);
|
||||
user.updateActivityOnInteract(true);
|
||||
}
|
||||
|
||||
private static boolean isEntityPickupEvent() {
|
||||
try {
|
||||
Class.forName("org.bukkit.event.entity.EntityPickupItemEvent");
|
||||
return true;
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isCommandSendEvent() {
|
||||
try {
|
||||
Class.forName("org.bukkit.event.player.PlayerCommandSendEvent");
|
||||
return true;
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
return false;
|
||||
private static final class ArrowPickupListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onArrowPickup(final org.bukkit.event.player.PlayerPickupArrowEvent event) {
|
||||
if (event.getItem().hasMetadata(Commandfireball.FIREBALL_META_KEY)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final class PickupListenerPre1_12 implements Listener {
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onPlayerPickupItem(final org.bukkit.event.player.PlayerPickupItemEvent event) {
|
||||
if (ess.getSettings().getDisableItemPickupWhileAfk()) {
|
||||
if (event.getItem().hasMetadata(Commandfireball.FIREBALL_META_KEY)) {
|
||||
event.setCancelled(true);
|
||||
} else if (ess.getSettings().getDisableItemPickupWhileAfk()) {
|
||||
if (ess.getUser(event.getPlayer()).isAfk()) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
@@ -844,32 +905,42 @@ public class EssentialsPlayerListener implements Listener {
|
||||
private final class CommandSendListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.NORMAL)
|
||||
public void onCommandSend(final PlayerCommandSendEvent event) {
|
||||
User user = ess.getUser(event.getPlayer());
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
|
||||
ArrayList<String> removedCmds = new ArrayList<>(event.getCommands());
|
||||
final Set<PluginCommand> checked = new HashSet<>();
|
||||
final Set<PluginCommand> toRemove = new HashSet<>();
|
||||
|
||||
event.getCommands().removeIf(str -> shouldHideFromUser(str, user));
|
||||
event.getCommands().removeIf(label -> {
|
||||
if (isEssentialsCommand(label)) {
|
||||
final PluginCommand command = ess.getServer().getPluginCommand(label);
|
||||
if (!checked.contains(command)) {
|
||||
checked.add(command);
|
||||
if (!user.isAuthorized(command.getName().equals("r") ? "essentials.msg" : "essentials." + command.getName())) {
|
||||
toRemove.add(command);
|
||||
}
|
||||
}
|
||||
return toRemove.contains(command);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
if (ess.getSettings().isDebug()) {
|
||||
removedCmds.removeAll(event.getCommands());
|
||||
ess.getLogger().info("Removed commands: " + removedCmds.toString());
|
||||
ess.getLogger().info("Removed commands: " + toRemove.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if all of the following are true:
|
||||
* - The command is a plugin command
|
||||
* - The plugin command is from Essentials
|
||||
* - There is no known alternative OR the alternative is overridden by Essentials
|
||||
* - The user is not allowed to perform the given Essentials command
|
||||
* - The command is a plugin command
|
||||
* - The plugin command is from a plugin in an essentials-controlled package
|
||||
* - There is no known alternative OR the alternative is overridden by Essentials
|
||||
*/
|
||||
private boolean shouldHideFromUser(String commandLabel, User user) {
|
||||
PluginCommand command = ess.getServer().getPluginCommand(commandLabel);
|
||||
private boolean isEssentialsCommand(final String label) {
|
||||
final PluginCommand command = ess.getServer().getPluginCommand(label);
|
||||
|
||||
return command != null
|
||||
&& command.getPlugin().getName().equals("Essentials")
|
||||
&& (ess.getSettings().isCommandOverridden(commandLabel) || (ess.getAlternativeCommandsHandler().getAlternative(commandLabel) == null))
|
||||
&& !user.isAuthorized("essentials." + command.getName());
|
||||
&& (command.getPlugin() == ess || command.getPlugin().getClass().getName().startsWith("com.earth2me.essentials"))
|
||||
&& (ess.getSettings().isCommandOverridden(label) || (ess.getAlternativeCommandsHandler().getAlternative(label) == null));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,6 @@ import org.bukkit.event.server.PluginEnableEvent;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
|
||||
public class EssentialsPluginListener implements Listener, IConf {
|
||||
private final transient IEssentials ess;
|
||||
|
||||
@@ -27,7 +26,7 @@ public class EssentialsPluginListener implements Listener, IConf {
|
||||
ess.getPermissionsHandler().checkPermissions();
|
||||
ess.getAlternativeCommandsHandler().addPlugin(event.getPlugin());
|
||||
if (!Methods.hasMethod() && Methods.setMethod(ess.getServer().getPluginManager())) {
|
||||
ess.getLogger().log(Level.INFO, "Payment method found (" + Methods.getMethod().getLongName() + " version: " + ess.getPaymentMethod().getMethod().getVersion() + ")");
|
||||
ess.getLogger().log(Level.INFO, "Payment method found (" + Methods.getMethod().getLongName() + " version: " + Methods.getMethod().getVersion() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,9 +35,10 @@ public class EssentialsPluginListener implements Listener, IConf {
|
||||
if (event.getPlugin().getName().equals("EssentialsChat")) {
|
||||
ess.getSettings().setEssentialsChatActive(false);
|
||||
}
|
||||
ess.getPermissionsHandler().checkPermissions();
|
||||
ess.getAlternativeCommandsHandler().removePlugin(event.getPlugin());
|
||||
// Check to see if the plugin thats being disabled is the one we are using
|
||||
if (ess.getPaymentMethod() != null && Methods.hasMethod() && Methods.checkDisabled(event.getPlugin())) {
|
||||
if (Methods.hasMethod() && Methods.checkDisabled(event.getPlugin())) {
|
||||
Methods.reset();
|
||||
ess.getLogger().log(Level.INFO, "Payment method was disabled. No longer accepting payments.");
|
||||
}
|
||||
|
||||
@@ -15,17 +15,17 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
|
||||
public class EssentialsServerListener implements Listener {
|
||||
private static List<String> ignoredSLPECallers = Arrays.asList(
|
||||
private static final List<String> ignoredSLPECallers = Arrays.asList(
|
||||
".LegacyPingHandler.channelRead(", // CB responding to pings from pre-Netty clients
|
||||
"de.dytanic.cloudnet.bridge.BukkitBootstrap" // CloudNet v2 doing... something
|
||||
"de.dytanic.cloudnet.bridge.BukkitBootstrap", // CloudNet v2 doing... something
|
||||
"de.dytanic.cloudnet.ext.bridge.bukkit.BukkitCloudNetBridgePlugin" // CloudNet v3 doing... something else
|
||||
);
|
||||
|
||||
private final transient IEssentials ess;
|
||||
private final boolean isPaperSample;
|
||||
private boolean unsupportedLogged = false;
|
||||
private boolean npeWarned = false;
|
||||
private boolean isPaperSample;
|
||||
private Method setSampleText;
|
||||
private Method getSampleText;
|
||||
|
||||
@@ -51,34 +51,34 @@ public class EssentialsServerListener implements Listener {
|
||||
public void onServerListPing(final ServerListPingEvent event) throws Exception {
|
||||
if (isPaperSample) {
|
||||
try {
|
||||
List<String> playerNames = (List<String>) getSampleText.invoke(event, null);
|
||||
final List<String> playerNames = (List<String>) getSampleText.invoke(event, null);
|
||||
playerNames.removeIf(player -> ess.getUser(player).isVanished());
|
||||
setSampleText.invoke(event, playerNames);
|
||||
} catch (IllegalAccessException | InvocationTargetException | ClassCastException e) {
|
||||
} catch (final IllegalAccessException | InvocationTargetException | ClassCastException e) {
|
||||
if (!unsupportedLogged && shouldWarnSLPECaller(e)) {
|
||||
ess.getLogger().log(Level.WARNING, "Unable to hide players from server list ping "
|
||||
+ "using Paper 1.12 method!", e);
|
||||
+ "using Paper 1.12 method!", e);
|
||||
unsupportedLogged = true;
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
} catch (final NullPointerException e) {
|
||||
if (!npeWarned && shouldWarnSLPECaller(e)) {
|
||||
npeWarned = true;
|
||||
Exception ex = new Exception("A plugin has fired a ServerListPingEvent "
|
||||
+ "without implementing Paper's methods. Point the author to https://git.io/v7Xzl.");
|
||||
final Exception ex = new Exception("A plugin has fired a ServerListPingEvent "
|
||||
+ "without implementing Paper's methods. Point the author to https://git.io/v7Xzl.");
|
||||
ex.setStackTrace(e.getStackTrace());
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
Iterator<Player> iterator = event.iterator();
|
||||
final Iterator<Player> iterator = event.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Player player = iterator.next();
|
||||
final Player player = iterator.next();
|
||||
if (ess.getUser(player).isVanished()) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
} catch (UnsupportedOperationException e) {
|
||||
} catch (final UnsupportedOperationException e) {
|
||||
if (!unsupportedLogged && shouldWarnSLPECaller(e)) {
|
||||
ess.getLogger().log(Level.WARNING, "Could not hide vanished players while handling " + event.getClass().getName(), e);
|
||||
unsupportedLogged = true;
|
||||
@@ -95,16 +95,16 @@ public class EssentialsServerListener implements Listener {
|
||||
* @param throwable A throwable caught by a catch block
|
||||
* @return Whether or not to send a warning about this particular caller
|
||||
*/
|
||||
private boolean shouldWarnSLPECaller(Throwable throwable) {
|
||||
private boolean shouldWarnSLPECaller(final Throwable throwable) {
|
||||
final int maxStackDepth = 20; // Limit the depth when searching through the stack trace
|
||||
int depth = 0;
|
||||
for (StackTraceElement element : throwable.getStackTrace()) {
|
||||
for (final StackTraceElement element : throwable.getStackTrace()) {
|
||||
depth++;
|
||||
if (depth > maxStackDepth) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (String ignoredString : ignoredSLPECallers) {
|
||||
for (final String ignoredString : ignoredSLPECallers) {
|
||||
if (element.toString().contains(ignoredString)) {
|
||||
return false; // We know about this error and should ignore it, so don't warn
|
||||
}
|
||||
|
||||
@@ -3,19 +3,24 @@ package com.earth2me.essentials;
|
||||
import net.ess3.api.IEssentials;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
|
||||
public class EssentialsTimer implements Runnable {
|
||||
private final transient IEssentials ess;
|
||||
private final transient Set<UUID> onlineUsers = new HashSet<>(); // Field is necessary for hidden users
|
||||
private transient long lastPoll = System.nanoTime();
|
||||
private final LinkedList<Double> history = new LinkedList<>();
|
||||
@SuppressWarnings("FieldCanBeLocal")
|
||||
private final long maxTime = 10 * 1000000;
|
||||
@SuppressWarnings("FieldCanBeLocal")
|
||||
private final long tickInterval = 50;
|
||||
private transient long lastPoll = System.nanoTime();
|
||||
private int skip1 = 0;
|
||||
private int skip2 = 0;
|
||||
private final long maxTime = 10 * 1000000;
|
||||
private final long tickInterval = 50;
|
||||
|
||||
EssentialsTimer(final IEssentials ess) {
|
||||
this.ess = ess;
|
||||
@@ -33,13 +38,13 @@ public class EssentialsTimer implements Runnable {
|
||||
if (history.size() > 10) {
|
||||
history.remove();
|
||||
}
|
||||
double tps = tickInterval * 1000000.0 / timeSpent;
|
||||
final double tps = tickInterval * 1000000.0 / timeSpent;
|
||||
if (tps <= 21) {
|
||||
history.add(tps);
|
||||
}
|
||||
lastPoll = startTime;
|
||||
int count = 0;
|
||||
for (Player player : ess.getOnlinePlayers()) {
|
||||
for (final Player player : ess.getOnlinePlayers()) {
|
||||
count++;
|
||||
if (skip1 > 0) {
|
||||
skip1--;
|
||||
@@ -56,7 +61,7 @@ public class EssentialsTimer implements Runnable {
|
||||
onlineUsers.add(user.getBase().getUniqueId());
|
||||
user.setLastOnlineActivity(currentTime);
|
||||
user.checkActivity();
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
ess.getLogger().log(Level.WARNING, "EssentialsTimer Error:", e);
|
||||
}
|
||||
}
|
||||
@@ -96,7 +101,7 @@ public class EssentialsTimer implements Runnable {
|
||||
|
||||
public double getAverageTPS() {
|
||||
double avg = 0;
|
||||
for (Double f : history) {
|
||||
for (final Double f : history) {
|
||||
if (f != null) {
|
||||
avg += f;
|
||||
}
|
||||
|
||||
@@ -14,12 +14,29 @@ import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.math.BigInteger;
|
||||
import java.security.DigestInputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
@@ -27,9 +44,13 @@ import java.util.regex.Pattern;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class EssentialsUpgrade {
|
||||
private final static Logger LOGGER = Logger.getLogger("Essentials");
|
||||
private static final FileFilter YML_FILTER = pathname -> pathname.isFile() && pathname.getName().endsWith(".yml");
|
||||
private static final String PATTERN_CONFIG_UUID_REGEX = "(?mi)^uuid:\\s*([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\\s*$";
|
||||
private static final Pattern PATTERN_CONFIG_UUID = Pattern.compile(PATTERN_CONFIG_UUID_REGEX);
|
||||
private static final String PATTERN_CONFIG_NAME_REGEX = "(?mi)^lastAccountName:\\s*[\"\']?(\\w+)[\"\']?\\s*$";
|
||||
private static final Pattern PATTERN_CONFIG_NAME = Pattern.compile(PATTERN_CONFIG_NAME_REGEX);
|
||||
private final transient IEssentials ess;
|
||||
private final transient EssentialsConf doneFile;
|
||||
|
||||
@@ -42,24 +63,157 @@ public class EssentialsUpgrade {
|
||||
doneFile.load();
|
||||
}
|
||||
|
||||
public static void uuidFileConvert(final IEssentials ess, final Boolean ignoreUFCache) {
|
||||
ess.getLogger().info("Starting Essentials UUID userdata conversion");
|
||||
|
||||
final File userdir = new File(ess.getDataFolder(), "userdata");
|
||||
if (!userdir.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int countFiles = 0;
|
||||
int countFails = 0;
|
||||
int countEssCache = 0;
|
||||
int countBukkit = 0;
|
||||
|
||||
ess.getLogger().info("Found " + userdir.list().length + " files to convert...");
|
||||
|
||||
for (final String string : userdir.list()) {
|
||||
if (!string.endsWith(".yml") || string.length() < 5) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final int showProgress = countFiles % 250;
|
||||
|
||||
if (showProgress == 0) {
|
||||
ess.getUserMap().getUUIDMap().forceWriteUUIDMap();
|
||||
ess.getLogger().info("Converted " + countFiles + "/" + userdir.list().length);
|
||||
}
|
||||
|
||||
countFiles++;
|
||||
|
||||
final String name = string.substring(0, string.length() - 4);
|
||||
final EssentialsUserConf config;
|
||||
UUID uuid = null;
|
||||
try {
|
||||
uuid = UUID.fromString(name);
|
||||
} catch (final IllegalArgumentException ex) {
|
||||
final File file = new File(userdir, string);
|
||||
final EssentialsConf conf = new EssentialsConf(file);
|
||||
conf.load();
|
||||
conf.setProperty("lastAccountName", name);
|
||||
conf.save();
|
||||
|
||||
final String uuidConf = ignoreUFCache ? "force-uuid" : "uuid";
|
||||
|
||||
final String uuidString = conf.getString(uuidConf, null);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
try {
|
||||
uuid = UUID.fromString(uuidString);
|
||||
countEssCache++;
|
||||
break;
|
||||
} catch (final Exception ex2) {
|
||||
if (conf.getBoolean("npc", false)) {
|
||||
uuid = UUID.nameUUIDFromBytes(("NPC:" + name).getBytes(Charsets.UTF_8));
|
||||
break;
|
||||
}
|
||||
|
||||
final org.bukkit.OfflinePlayer player = ess.getServer().getOfflinePlayer(name);
|
||||
uuid = player.getUniqueId();
|
||||
}
|
||||
|
||||
if (uuid != null) {
|
||||
countBukkit++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (uuid != null) {
|
||||
conf.forceSave();
|
||||
config = new EssentialsUserConf(name, uuid, new File(userdir, uuid + ".yml"));
|
||||
config.convertLegacyFile();
|
||||
ess.getUserMap().trackUUID(uuid, name, false);
|
||||
continue;
|
||||
}
|
||||
countFails++;
|
||||
}
|
||||
}
|
||||
ess.getUserMap().getUUIDMap().forceWriteUUIDMap();
|
||||
|
||||
ess.getLogger().info("Converted " + countFiles + "/" + countFiles + ". Conversion complete.");
|
||||
ess.getLogger().info("Converted via cache: " + countEssCache + " :: Converted via lookup: " + countBukkit + " :: Failed to convert: " + countFails);
|
||||
ess.getLogger().info("To rerun the conversion type /essentials uuidconvert");
|
||||
}
|
||||
|
||||
public void convertIgnoreList() {
|
||||
final Pattern pattern = Pattern.compile("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$");
|
||||
if (doneFile.getBoolean("updateUsersIgnoreListUUID", false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOGGER.info("Attempting to migrate ignore list to UUIDs");
|
||||
|
||||
final File userdataFolder = new File(ess.getDataFolder(), "userdata");
|
||||
if (!userdataFolder.exists() || !userdataFolder.isDirectory()) {
|
||||
return;
|
||||
}
|
||||
final File[] userFiles = userdataFolder.listFiles();
|
||||
|
||||
for (final File file : userFiles) {
|
||||
if (!file.isFile() || !file.getName().endsWith(".yml")) {
|
||||
continue;
|
||||
}
|
||||
final EssentialsConf config = new EssentialsConf(file);
|
||||
try {
|
||||
config.load();
|
||||
if (config.hasProperty("ignore")) {
|
||||
final List<String> migratedIgnores = new ArrayList<>();
|
||||
for (final String name : Collections.synchronizedList(config.getStringList("ignore"))) {
|
||||
if (name == null) {
|
||||
continue;
|
||||
}
|
||||
if (pattern.matcher(name.trim()).matches()) {
|
||||
LOGGER.info("Detected already migrated ignore list!");
|
||||
return;
|
||||
}
|
||||
final User user = ess.getOfflineUser(name);
|
||||
if (user != null && user.getBase() != null) {
|
||||
migratedIgnores.add(user.getBase().getUniqueId().toString());
|
||||
}
|
||||
}
|
||||
config.removeProperty("ignore");
|
||||
config.setProperty("ignore", migratedIgnores);
|
||||
config.forceSave();
|
||||
}
|
||||
} catch (final RuntimeException ex) {
|
||||
LOGGER.log(Level.INFO, "File: " + file.toString());
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
doneFile.setProperty("updateUsersIgnoreListUUID", true);
|
||||
doneFile.save();
|
||||
LOGGER.info("Done converting ignore list.");
|
||||
}
|
||||
|
||||
public void convertKits() {
|
||||
Kits kits = ess.getKits();
|
||||
EssentialsConf config = kits.getConfig();
|
||||
final Kits kits = ess.getKits();
|
||||
final EssentialsConf config = kits.getConfig();
|
||||
if (doneFile.getBoolean("kitsyml", false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOGGER.info("Attempting to convert old kits in config.yml to new kits.yml");
|
||||
|
||||
ConfigurationSection section = ess.getSettings().getKitSection();
|
||||
final ConfigurationSection section = ess.getSettings().getKitSection();
|
||||
if (section == null) {
|
||||
LOGGER.info("No kits found to migrate.");
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, Object> legacyKits = ess.getSettings().getKitSection().getValues(true);
|
||||
final Map<String, Object> legacyKits = ess.getSettings().getKitSection().getValues(true);
|
||||
|
||||
for (Map.Entry<String, Object> entry : legacyKits.entrySet()) {
|
||||
for (final Map.Entry<String, Object> entry : legacyKits.entrySet()) {
|
||||
LOGGER.info("Converting " + entry.getKey());
|
||||
config.set("kits." + entry.getKey(), entry.getValue());
|
||||
}
|
||||
@@ -70,7 +224,7 @@ public class EssentialsUpgrade {
|
||||
LOGGER.info("Done converting kits.");
|
||||
}
|
||||
|
||||
private void moveMotdRulesToFile(String name) {
|
||||
private void moveMotdRulesToFile(final String name) {
|
||||
if (doneFile.getBoolean("move" + name + "ToFile", false)) {
|
||||
return;
|
||||
}
|
||||
@@ -85,26 +239,26 @@ public class EssentialsUpgrade {
|
||||
}
|
||||
final EssentialsConf conf = new EssentialsConf(configFile);
|
||||
conf.load();
|
||||
List<String> lines = conf.getStringList(name);
|
||||
final List<String> lines = conf.getStringList(name);
|
||||
if (lines != null && !lines.isEmpty()) {
|
||||
if (!file.createNewFile()) {
|
||||
throw new IOException("Failed to create file " + file);
|
||||
}
|
||||
PrintWriter writer = new PrintWriter(file);
|
||||
final PrintWriter writer = new PrintWriter(file);
|
||||
|
||||
for (String line : lines) {
|
||||
for (final String line : lines) {
|
||||
writer.println(line);
|
||||
}
|
||||
writer.close();
|
||||
}
|
||||
doneFile.setProperty("move" + name + "ToFile", true);
|
||||
doneFile.save();
|
||||
} catch (IOException e) {
|
||||
} catch (final IOException e) {
|
||||
LOGGER.log(Level.SEVERE, tl("upgradingFilesError"), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeLinesFromConfig(File file, String regex, String info) throws Exception {
|
||||
private void removeLinesFromConfig(final File file, final String regex, final String info) throws Exception {
|
||||
boolean needUpdate = false;
|
||||
final BufferedReader bReader = new BufferedReader(new FileReader(file));
|
||||
final File tempFile = File.createTempFile("essentialsupgrade", ".tmp.yml", ess.getDataFolder());
|
||||
@@ -155,7 +309,7 @@ public class EssentialsUpgrade {
|
||||
}
|
||||
final File[] userFiles = userdataFolder.listFiles();
|
||||
|
||||
for (File file : userFiles) {
|
||||
for (final File file : userFiles) {
|
||||
if (!file.isFile() || !file.getName().endsWith(".yml")) {
|
||||
continue;
|
||||
}
|
||||
@@ -163,20 +317,20 @@ public class EssentialsUpgrade {
|
||||
try {
|
||||
config.load();
|
||||
if (config.hasProperty("powertools")) {
|
||||
@SuppressWarnings("unchecked") final Map<String, Object> powertools = config.getConfigurationSection("powertools").getValues(false);
|
||||
final Map<String, Object> powertools = config.getConfigurationSection("powertools").getValues(false);
|
||||
if (powertools == null) {
|
||||
continue;
|
||||
}
|
||||
for (Map.Entry<String, Object> entry : powertools.entrySet()) {
|
||||
for (final Map.Entry<String, Object> entry : powertools.entrySet()) {
|
||||
if (entry.getValue() instanceof String) {
|
||||
List<String> temp = new ArrayList<>();
|
||||
final List<String> temp = new ArrayList<>();
|
||||
temp.add((String) entry.getValue());
|
||||
powertools.put(entry.getKey(), temp);
|
||||
}
|
||||
}
|
||||
config.forceSave();
|
||||
}
|
||||
} catch (RuntimeException ex) {
|
||||
} catch (final RuntimeException ex) {
|
||||
LOGGER.log(Level.INFO, "File: " + file.toString());
|
||||
throw ex;
|
||||
}
|
||||
@@ -195,7 +349,7 @@ public class EssentialsUpgrade {
|
||||
}
|
||||
final File[] userFiles = userdataFolder.listFiles();
|
||||
|
||||
for (File file : userFiles) {
|
||||
for (final File file : userFiles) {
|
||||
if (!file.isFile() || !file.getName().endsWith(".yml")) {
|
||||
continue;
|
||||
}
|
||||
@@ -204,20 +358,20 @@ public class EssentialsUpgrade {
|
||||
|
||||
config.load();
|
||||
if (config.hasProperty("home") && config.hasProperty("home.default")) {
|
||||
@SuppressWarnings("unchecked") final String defworld = (String) config.getProperty("home.default");
|
||||
final String defworld = (String) config.getProperty("home.default");
|
||||
final Location defloc = getFakeLocation(config, "home.worlds." + defworld);
|
||||
if (defloc != null) {
|
||||
config.setProperty("homes.home", defloc);
|
||||
}
|
||||
|
||||
Set<String> worlds = config.getConfigurationSection("home.worlds").getKeys(false);
|
||||
final Set<String> worlds = config.getConfigurationSection("home.worlds").getKeys(false);
|
||||
Location loc;
|
||||
String worldName;
|
||||
|
||||
if (worlds == null) {
|
||||
continue;
|
||||
}
|
||||
for (String world : worlds) {
|
||||
for (final String world : worlds) {
|
||||
if (defworld.equalsIgnoreCase(world)) {
|
||||
continue;
|
||||
}
|
||||
@@ -234,7 +388,7 @@ public class EssentialsUpgrade {
|
||||
config.forceSave();
|
||||
}
|
||||
|
||||
} catch (RuntimeException ex) {
|
||||
} catch (final RuntimeException ex) {
|
||||
LOGGER.log(Level.INFO, "File: " + file.toString());
|
||||
throw ex;
|
||||
}
|
||||
@@ -252,7 +406,7 @@ public class EssentialsUpgrade {
|
||||
return;
|
||||
}
|
||||
final File[] listOfFiles = usersFolder.listFiles();
|
||||
for (File listOfFile : listOfFiles) {
|
||||
for (final File listOfFile : listOfFiles) {
|
||||
final String filename = listOfFile.getName();
|
||||
if (!listOfFile.isFile() || !filename.endsWith(".yml")) {
|
||||
continue;
|
||||
@@ -288,12 +442,12 @@ public class EssentialsUpgrade {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Location getFakeLocation(EssentialsConf config, String path) {
|
||||
String worldName = config.getString((path != null ? path + "." : "") + "world");
|
||||
public Location getFakeLocation(final EssentialsConf config, final String path) {
|
||||
final String worldName = config.getString((path != null ? path + "." : "") + "world");
|
||||
if (worldName == null || worldName.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
World world = getFakeWorld(worldName);
|
||||
final World world = getFakeWorld(worldName);
|
||||
if (world == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -313,21 +467,21 @@ public class EssentialsUpgrade {
|
||||
oldconfigs.add(new BigInteger("c33bc9b8ee003861611bbc2f48eb6f4f", 16)); // jul 24
|
||||
oldconfigs.add(new BigInteger("6ff17925430735129fc2a02f830c1daa", 16)); // crlf
|
||||
|
||||
MessageDigest digest = ManagedFile.getDigest();
|
||||
final MessageDigest digest = ManagedFile.getDigest();
|
||||
final BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
|
||||
final byte[] buffer = new byte[1024];
|
||||
try (DigestInputStream dis = new DigestInputStream(bis, digest)) {
|
||||
try (final DigestInputStream dis = new DigestInputStream(bis, digest)) {
|
||||
while (dis.read(buffer) != -1) {
|
||||
}
|
||||
}
|
||||
|
||||
BigInteger hash = new BigInteger(1, digest.digest());
|
||||
final BigInteger hash = new BigInteger(1, digest.digest());
|
||||
if (oldconfigs.contains(hash) && !file.delete()) {
|
||||
throw new IOException("Could not delete file " + file.toString());
|
||||
}
|
||||
doneFile.setProperty("deleteOldItemsCsv", true);
|
||||
doneFile.save();
|
||||
} catch (IOException ex) {
|
||||
} catch (final IOException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
@@ -345,19 +499,19 @@ public class EssentialsUpgrade {
|
||||
config.load();
|
||||
if (!config.hasProperty("spawns")) {
|
||||
final Spawns spawns = new Spawns();
|
||||
Set<String> keys = config.getKeys(false);
|
||||
for (String group : keys) {
|
||||
Location loc = getFakeLocation(config, group);
|
||||
final Set<String> keys = config.getKeys(false);
|
||||
for (final String group : keys) {
|
||||
final Location loc = getFakeLocation(config, group);
|
||||
spawns.getSpawns().put(group.toLowerCase(Locale.ENGLISH), loc);
|
||||
}
|
||||
if (!configFile.renameTo(new File(ess.getDataFolder(), "spawn.yml.old"))) {
|
||||
throw new Exception(tl("fileRenameError", "spawn.yml"));
|
||||
}
|
||||
try (PrintWriter writer = new PrintWriter(configFile)) {
|
||||
try (final PrintWriter writer = new PrintWriter(configFile)) {
|
||||
new YamlStorageWriter(writer).save(spawns);
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
} catch (final Exception ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
@@ -377,19 +531,19 @@ public class EssentialsUpgrade {
|
||||
config.load();
|
||||
if (!config.hasProperty("jails")) {
|
||||
final com.earth2me.essentials.settings.Jails jails = new com.earth2me.essentials.settings.Jails();
|
||||
Set<String> keys = config.getKeys(false);
|
||||
for (String jailName : keys) {
|
||||
Location loc = getFakeLocation(config, jailName);
|
||||
final Set<String> keys = config.getKeys(false);
|
||||
for (final String jailName : keys) {
|
||||
final Location loc = getFakeLocation(config, jailName);
|
||||
jails.getJails().put(jailName.toLowerCase(Locale.ENGLISH), loc);
|
||||
}
|
||||
if (!configFile.renameTo(new File(ess.getDataFolder(), "jail.yml.old"))) {
|
||||
throw new Exception(tl("fileRenameError", "jail.yml"));
|
||||
}
|
||||
try (PrintWriter writer = new PrintWriter(configFile)) {
|
||||
try (final PrintWriter writer = new PrintWriter(configFile)) {
|
||||
new YamlStorageWriter(writer).save(jails);
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
} catch (final Exception ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
@@ -410,7 +564,7 @@ public class EssentialsUpgrade {
|
||||
return;
|
||||
}
|
||||
|
||||
Boolean ignoreUFCache = doneFile.getBoolean("ignore-userfiles-cache", false);
|
||||
final Boolean ignoreUFCache = doneFile.getBoolean("ignore-userfiles-cache", false);
|
||||
|
||||
final File userdir = new File(ess.getDataFolder(), "userdata");
|
||||
if (!userdir.exists()) {
|
||||
@@ -419,7 +573,7 @@ public class EssentialsUpgrade {
|
||||
|
||||
int countFiles = 0;
|
||||
int countReqFiles = 0;
|
||||
for (String string : userdir.list()) {
|
||||
for (final String string : userdir.list()) {
|
||||
if (!string.endsWith(".yml") || string.length() < 5) {
|
||||
continue;
|
||||
}
|
||||
@@ -431,7 +585,7 @@ public class EssentialsUpgrade {
|
||||
|
||||
try {
|
||||
uuid = UUID.fromString(name);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
} catch (final IllegalArgumentException ex) {
|
||||
countReqFiles++;
|
||||
}
|
||||
|
||||
@@ -449,7 +603,7 @@ public class EssentialsUpgrade {
|
||||
|
||||
try {
|
||||
Thread.sleep(15000);
|
||||
} catch (InterruptedException ex) {
|
||||
} catch (final InterruptedException ex) {
|
||||
// NOOP
|
||||
}
|
||||
|
||||
@@ -459,89 +613,6 @@ public class EssentialsUpgrade {
|
||||
doneFile.save();
|
||||
}
|
||||
|
||||
public static void uuidFileConvert(IEssentials ess, Boolean ignoreUFCache) {
|
||||
ess.getLogger().info("Starting Essentials UUID userdata conversion");
|
||||
|
||||
final File userdir = new File(ess.getDataFolder(), "userdata");
|
||||
if (!userdir.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int countFiles = 0;
|
||||
int countFails = 0;
|
||||
int countEssCache = 0;
|
||||
int countBukkit = 0;
|
||||
|
||||
ess.getLogger().info("Found " + userdir.list().length + " files to convert...");
|
||||
|
||||
for (String string : userdir.list()) {
|
||||
if (!string.endsWith(".yml") || string.length() < 5) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final int showProgress = countFiles % 250;
|
||||
|
||||
if (showProgress == 0) {
|
||||
ess.getUserMap().getUUIDMap().forceWriteUUIDMap();
|
||||
ess.getLogger().info("Converted " + countFiles + "/" + userdir.list().length);
|
||||
}
|
||||
|
||||
countFiles++;
|
||||
|
||||
String name = string.substring(0, string.length() - 4);
|
||||
EssentialsUserConf config;
|
||||
UUID uuid = null;
|
||||
try {
|
||||
uuid = UUID.fromString(name);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
File file = new File(userdir, string);
|
||||
EssentialsConf conf = new EssentialsConf(file);
|
||||
conf.load();
|
||||
conf.setProperty("lastAccountName", name);
|
||||
conf.save();
|
||||
|
||||
String uuidConf = ignoreUFCache ? "force-uuid" : "uuid";
|
||||
|
||||
String uuidString = conf.getString(uuidConf, null);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
try {
|
||||
uuid = UUID.fromString(uuidString);
|
||||
countEssCache++;
|
||||
break;
|
||||
} catch (Exception ex2) {
|
||||
if (conf.getBoolean("npc", false)) {
|
||||
uuid = UUID.nameUUIDFromBytes(("NPC:" + name).getBytes(Charsets.UTF_8));
|
||||
break;
|
||||
}
|
||||
|
||||
org.bukkit.OfflinePlayer player = ess.getServer().getOfflinePlayer(name);
|
||||
uuid = player.getUniqueId();
|
||||
}
|
||||
|
||||
if (uuid != null) {
|
||||
countBukkit++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (uuid != null) {
|
||||
conf.forceSave();
|
||||
config = new EssentialsUserConf(name, uuid, new File(userdir, uuid + ".yml"));
|
||||
config.convertLegacyFile();
|
||||
ess.getUserMap().trackUUID(uuid, name, false);
|
||||
continue;
|
||||
}
|
||||
countFails++;
|
||||
}
|
||||
}
|
||||
ess.getUserMap().getUUIDMap().forceWriteUUIDMap();
|
||||
|
||||
ess.getLogger().info("Converted " + countFiles + "/" + countFiles + ". Conversion complete.");
|
||||
ess.getLogger().info("Converted via cache: " + countEssCache + " :: Converted via lookup: " + countBukkit + " :: Failed to convert: " + countFails);
|
||||
ess.getLogger().info("To rerun the conversion type /essentials uuidconvert");
|
||||
}
|
||||
|
||||
public void banFormatChange() {
|
||||
if (doneFile.getBoolean("banFormatChange", false)) {
|
||||
return;
|
||||
@@ -558,7 +629,7 @@ public class EssentialsUpgrade {
|
||||
|
||||
ess.getLogger().info("Found " + userdir.list().length + " files to convert...");
|
||||
|
||||
for (String string : userdir.list()) {
|
||||
for (final String string : userdir.list()) {
|
||||
if (!string.endsWith(".yml") || string.length() < 5) {
|
||||
continue;
|
||||
}
|
||||
@@ -575,11 +646,11 @@ public class EssentialsUpgrade {
|
||||
conf.load();
|
||||
|
||||
String banReason;
|
||||
Long banTimeout;
|
||||
long banTimeout;
|
||||
|
||||
try {
|
||||
banReason = conf.getConfigurationSection("ban").getString("reason");
|
||||
} catch (NullPointerException n) {
|
||||
} catch (final NullPointerException n) {
|
||||
banReason = null;
|
||||
}
|
||||
|
||||
@@ -591,7 +662,7 @@ public class EssentialsUpgrade {
|
||||
} else {
|
||||
banTimeout = 0L;
|
||||
}
|
||||
} catch (NumberFormatException n) {
|
||||
} catch (final NumberFormatException n) {
|
||||
banTimeout = 0L;
|
||||
}
|
||||
|
||||
@@ -608,7 +679,7 @@ public class EssentialsUpgrade {
|
||||
ess.getLogger().info("Ban format update complete.");
|
||||
}
|
||||
|
||||
private void updateBan(String playerName, String banReason, Long banTimeout) {
|
||||
private void updateBan(final String playerName, final String banReason, final Long banTimeout) {
|
||||
if (banTimeout == 0) {
|
||||
Bukkit.getBanList(BanList.Type.NAME).addBan(playerName, banReason, null, Console.NAME);
|
||||
} else {
|
||||
@@ -616,31 +687,18 @@ public class EssentialsUpgrade {
|
||||
}
|
||||
}
|
||||
|
||||
private static final FileFilter YML_FILTER = new FileFilter() {
|
||||
@Override
|
||||
public boolean accept(File pathname) {
|
||||
return pathname.isFile() && pathname.getName().endsWith(".yml");
|
||||
}
|
||||
};
|
||||
|
||||
private static final String PATTERN_CONFIG_UUID_REGEX = "(?mi)^uuid:\\s*([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\\s*$";
|
||||
private static final Pattern PATTERN_CONFIG_UUID = Pattern.compile(PATTERN_CONFIG_UUID_REGEX);
|
||||
|
||||
private static final String PATTERN_CONFIG_NAME_REGEX = "(?mi)^lastAccountName:\\s*[\"\']?(\\w+)[\"\']?\\s*$";
|
||||
private static final Pattern PATTERN_CONFIG_NAME = Pattern.compile(PATTERN_CONFIG_NAME_REGEX);
|
||||
|
||||
private void repairUserMap() {
|
||||
if (doneFile.getBoolean("userMapRepaired", false)) {
|
||||
return;
|
||||
}
|
||||
ess.getLogger().info("Starting usermap repair");
|
||||
|
||||
File userdataFolder = new File(ess.getDataFolder(), "userdata");
|
||||
final File userdataFolder = new File(ess.getDataFolder(), "userdata");
|
||||
if (!userdataFolder.isDirectory()) {
|
||||
ess.getLogger().warning("Missing userdata folder, aborting");
|
||||
return;
|
||||
}
|
||||
File[] files = userdataFolder.listFiles(YML_FILTER);
|
||||
final File[] files = userdataFolder.listFiles(YML_FILTER);
|
||||
|
||||
final DecimalFormat format = new DecimalFormat("#0.00");
|
||||
final Map<String, UUID> names = Maps.newHashMap();
|
||||
@@ -656,7 +714,7 @@ public class EssentialsUpgrade {
|
||||
try {
|
||||
// ".yml" ending has 4 chars...
|
||||
uuid = UUID.fromString(filename.substring(0, filename.length() - 4));
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
} catch (final IllegalArgumentException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -664,7 +722,7 @@ public class EssentialsUpgrade {
|
||||
if (uuidMatcher.find()) {
|
||||
try {
|
||||
uuid = UUID.fromString(uuidMatcher.group(1));
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
} catch (final IllegalArgumentException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -683,7 +741,7 @@ public class EssentialsUpgrade {
|
||||
|
||||
if (index % 1000 == 0) {
|
||||
ess.getLogger().info("Reading: " + format.format((100d * (double) index) / files.length)
|
||||
+ "%");
|
||||
+ "%");
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
ess.getLogger().log(Level.SEVERE, "Error while reading file: ", e);
|
||||
@@ -718,5 +776,6 @@ public class EssentialsUpgrade {
|
||||
banFormatChange();
|
||||
warnMetrics();
|
||||
repairUserMap();
|
||||
convertIgnoreList();
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,6 @@ import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
|
||||
public class EssentialsUserConf extends EssentialsConf {
|
||||
public final String username;
|
||||
public final UUID uuid;
|
||||
@@ -32,7 +31,7 @@ public class EssentialsUserConf extends EssentialsConf {
|
||||
final File file = new File(configFile.getParentFile(), username + ".yml");
|
||||
try {
|
||||
Files.move(file, new File(configFile.getParentFile(), uuid + ".yml"));
|
||||
} catch (IOException ex) {
|
||||
} catch (final IOException ex) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Failed to migrate user: " + username, ex);
|
||||
}
|
||||
|
||||
@@ -56,7 +55,7 @@ public class EssentialsUserConf extends EssentialsConf {
|
||||
public void convertAltFile() {
|
||||
try {
|
||||
Files.move(getAltFile(), new File(configFile.getParentFile(), uuid + ".yml"));
|
||||
} catch (IOException ex) {
|
||||
} catch (final IOException ex) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Failed to migrate user: " + username, ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,14 +6,12 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
|
||||
public class ExecuteTimer {
|
||||
private final transient List<ExecuteRecord> times;
|
||||
private final transient DecimalFormat decimalFormat = new DecimalFormat("#0.000", DecimalFormatSymbols.getInstance(Locale.US));
|
||||
|
||||
|
||||
public ExecuteTimer() {
|
||||
times = new ArrayList<ExecuteRecord>();
|
||||
times = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void start() {
|
||||
@@ -37,7 +35,7 @@ public class ExecuteTimer {
|
||||
long time2 = 0;
|
||||
double duration;
|
||||
|
||||
for (ExecuteRecord pair : times) {
|
||||
for (final ExecuteRecord pair : times) {
|
||||
mark = pair.getMark();
|
||||
time2 = pair.getTime();
|
||||
if (time1 > 0) {
|
||||
@@ -54,12 +52,11 @@ public class ExecuteTimer {
|
||||
return output.toString();
|
||||
}
|
||||
|
||||
|
||||
private static class ExecuteRecord {
|
||||
private final String mark;
|
||||
private final long time;
|
||||
|
||||
public ExecuteRecord(final String mark, final long time) {
|
||||
ExecuteRecord(final String mark, final long time) {
|
||||
this.mark = mark;
|
||||
this.time = time;
|
||||
}
|
||||
@@ -72,4 +69,4 @@ public class ExecuteTimer {
|
||||
return time;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,44 +5,68 @@ import net.ess3.api.IEssentials;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.*;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.PropertyResourceBundle;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
public class I18n implements net.ess3.api.II18n {
|
||||
private static I18n instance;
|
||||
private static final String MESSAGES = "messages";
|
||||
private final transient Locale defaultLocale = Locale.getDefault();
|
||||
private transient Locale currentLocale = defaultLocale;
|
||||
private transient ResourceBundle customBundle;
|
||||
private transient ResourceBundle localeBundle;
|
||||
private final transient ResourceBundle defaultBundle;
|
||||
private transient Map<String, MessageFormat> messageFormatCache = new HashMap<String, MessageFormat>();
|
||||
private final transient IEssentials ess;
|
||||
private static final Pattern NODOUBLEMARK = Pattern.compile("''");
|
||||
private static final ResourceBundle NULL_BUNDLE = new ResourceBundle() {
|
||||
public Enumeration<String> getKeys() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Object handleGetObject(String key) {
|
||||
protected Object handleGetObject(final String key) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
private static I18n instance;
|
||||
private final transient Locale defaultLocale = Locale.getDefault();
|
||||
private final transient ResourceBundle defaultBundle;
|
||||
private final transient IEssentials ess;
|
||||
private transient Locale currentLocale = defaultLocale;
|
||||
private transient ResourceBundle customBundle;
|
||||
private transient ResourceBundle localeBundle;
|
||||
private transient Map<String, MessageFormat> messageFormatCache = new HashMap<>();
|
||||
|
||||
public I18n(final IEssentials ess) {
|
||||
this.ess = ess;
|
||||
defaultBundle = ResourceBundle.getBundle(MESSAGES, Locale.ENGLISH);
|
||||
defaultBundle = ResourceBundle.getBundle(MESSAGES, Locale.ENGLISH, new UTF8PropertiesControl());
|
||||
localeBundle = defaultBundle;
|
||||
customBundle = NULL_BUNDLE;
|
||||
}
|
||||
|
||||
public static String tl(final String string, final Object... objects) {
|
||||
if (instance == null) {
|
||||
return "";
|
||||
}
|
||||
if (objects.length == 0) {
|
||||
return NODOUBLEMARK.matcher(instance.translate(string)).replaceAll("'");
|
||||
} else {
|
||||
return instance.format(string, objects);
|
||||
}
|
||||
}
|
||||
|
||||
public static String capitalCase(final String input) {
|
||||
return input == null || input.length() == 0 ? input : input.toUpperCase(Locale.ENGLISH).charAt(0) + input.toLowerCase(Locale.ENGLISH).substring(1);
|
||||
}
|
||||
|
||||
public void onEnable() {
|
||||
instance = this;
|
||||
}
|
||||
@@ -60,33 +84,22 @@ public class I18n implements net.ess3.api.II18n {
|
||||
try {
|
||||
try {
|
||||
return customBundle.getString(string);
|
||||
} catch (MissingResourceException ex) {
|
||||
} catch (final MissingResourceException ex) {
|
||||
return localeBundle.getString(string);
|
||||
}
|
||||
} catch (MissingResourceException ex) {
|
||||
} catch (final MissingResourceException ex) {
|
||||
Logger.getLogger("Essentials").log(Level.WARNING, String.format("Missing translation key \"%s\" in translation file %s", ex.getKey(), localeBundle.getLocale().toString()), ex);
|
||||
return defaultBundle.getString(string);
|
||||
}
|
||||
}
|
||||
|
||||
public static String tl(final String string, final Object... objects) {
|
||||
if (instance == null) {
|
||||
return "";
|
||||
}
|
||||
if (objects.length == 0) {
|
||||
return NODOUBLEMARK.matcher(instance.translate(string)).replaceAll("'");
|
||||
} else {
|
||||
return instance.format(string, objects);
|
||||
}
|
||||
}
|
||||
|
||||
public String format(final String string, final Object... objects) {
|
||||
String format = translate(string);
|
||||
MessageFormat messageFormat = messageFormatCache.get(format);
|
||||
if (messageFormat == null) {
|
||||
try {
|
||||
messageFormat = new MessageFormat(format);
|
||||
} catch (IllegalArgumentException e) {
|
||||
} catch (final IllegalArgumentException e) {
|
||||
ess.getLogger().log(Level.SEVERE, "Invalid Translation key for '" + string + "': " + e.getMessage());
|
||||
format = format.replaceAll("\\{(\\D*?)\\}", "\\[$1\\]");
|
||||
messageFormat = new MessageFormat(format);
|
||||
@@ -110,27 +123,25 @@ public class I18n implements net.ess3.api.II18n {
|
||||
}
|
||||
}
|
||||
ResourceBundle.clearCache();
|
||||
messageFormatCache = new HashMap<String, MessageFormat>();
|
||||
messageFormatCache = new HashMap<>();
|
||||
Logger.getLogger("Essentials").log(Level.INFO, String.format("Using locale %s", currentLocale.toString()));
|
||||
|
||||
try {
|
||||
localeBundle = ResourceBundle.getBundle(MESSAGES, currentLocale);
|
||||
} catch (MissingResourceException ex) {
|
||||
localeBundle = ResourceBundle.getBundle(MESSAGES, currentLocale, new UTF8PropertiesControl());
|
||||
} catch (final MissingResourceException ex) {
|
||||
localeBundle = NULL_BUNDLE;
|
||||
}
|
||||
|
||||
try {
|
||||
customBundle = ResourceBundle.getBundle(MESSAGES, currentLocale, new FileResClassLoader(I18n.class.getClassLoader(), ess));
|
||||
} catch (MissingResourceException ex) {
|
||||
customBundle = ResourceBundle.getBundle(MESSAGES, currentLocale, new FileResClassLoader(I18n.class.getClassLoader(), ess), new UTF8PropertiesControl());
|
||||
} catch (final MissingResourceException ex) {
|
||||
customBundle = NULL_BUNDLE;
|
||||
}
|
||||
}
|
||||
|
||||
public static String capitalCase(final String input) {
|
||||
return input == null || input.length() == 0 ? input : input.toUpperCase(Locale.ENGLISH).charAt(0) + input.toLowerCase(Locale.ENGLISH).substring(1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attempts to load properties files from the plugin directory before falling back to the jar.
|
||||
*/
|
||||
private static class FileResClassLoader extends ClassLoader {
|
||||
private final transient File dataFolder;
|
||||
|
||||
@@ -145,7 +156,7 @@ public class I18n implements net.ess3.api.II18n {
|
||||
if (file.exists()) {
|
||||
try {
|
||||
return file.toURI().toURL();
|
||||
} catch (MalformedURLException ex) {
|
||||
} catch (final MalformedURLException ignored) {
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -157,10 +168,43 @@ public class I18n implements net.ess3.api.II18n {
|
||||
if (file.exists()) {
|
||||
try {
|
||||
return new FileInputStream(file);
|
||||
} catch (FileNotFoundException ex) {
|
||||
} catch (final FileNotFoundException ignored) {
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads .properties files as UTF-8 instead of ISO-8859-1, which is the default on Java 8/below.
|
||||
* Java 9 fixes this by defaulting to UTF-8 for .properties files.
|
||||
*/
|
||||
private static class UTF8PropertiesControl extends ResourceBundle.Control {
|
||||
public ResourceBundle newBundle(final String baseName, final Locale locale, final String format, final ClassLoader loader, final boolean reload) throws IOException {
|
||||
final String resourceName = toResourceName(toBundleName(baseName, locale), "properties");
|
||||
ResourceBundle bundle = null;
|
||||
InputStream stream = null;
|
||||
if (reload) {
|
||||
final URL url = loader.getResource(resourceName);
|
||||
if (url != null) {
|
||||
final URLConnection connection = url.openConnection();
|
||||
if (connection != null) {
|
||||
connection.setUseCaches(false);
|
||||
stream = connection.getInputStream();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
stream = loader.getResourceAsStream(resourceName);
|
||||
}
|
||||
if (stream != null) {
|
||||
try {
|
||||
// use UTF-8 here, this is the important bit
|
||||
bundle = new PropertyResourceBundle(new InputStreamReader(stream, StandardCharsets.UTF_8));
|
||||
} finally {
|
||||
stream.close();
|
||||
}
|
||||
}
|
||||
return bundle;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,12 @@ package com.earth2me.essentials;
|
||||
import com.earth2me.essentials.api.IItemDb;
|
||||
import com.earth2me.essentials.api.IJails;
|
||||
import com.earth2me.essentials.api.IWarps;
|
||||
import com.earth2me.essentials.metrics.Metrics;
|
||||
import com.earth2me.essentials.perm.PermissionsHandler;
|
||||
import com.earth2me.essentials.register.payment.Methods;
|
||||
import net.ess3.nms.SpawnerProvider;
|
||||
import net.ess3.provider.ContainerProvider;
|
||||
import net.ess3.provider.KnownCommandsProvider;
|
||||
import net.ess3.provider.ServerStateProvider;
|
||||
import net.ess3.provider.SpawnerBlockProvider;
|
||||
import net.ess3.provider.SpawnerItemProvider;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -18,6 +20,7 @@ import org.bukkit.scheduler.BukkitTask;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public interface IEssentials extends Plugin {
|
||||
void addReloadListener(IConf listener);
|
||||
@@ -47,6 +50,8 @@ public interface IEssentials extends Plugin {
|
||||
|
||||
int broadcastMessage(IUser sender, String message);
|
||||
|
||||
int broadcastMessage(IUser sender, String message, Predicate<IUser> shouldExclude);
|
||||
|
||||
int broadcastMessage(String permission, String message);
|
||||
|
||||
ISettings getSettings();
|
||||
@@ -63,7 +68,7 @@ public interface IEssentials extends Plugin {
|
||||
|
||||
Kits getKits();
|
||||
|
||||
Methods getPaymentMethod();
|
||||
RandomTeleport getRandomTeleport();
|
||||
|
||||
BukkitTask runTaskAsynchronously(Runnable run);
|
||||
|
||||
@@ -89,12 +94,14 @@ public interface IEssentials extends Plugin {
|
||||
|
||||
UserMap getUserMap();
|
||||
|
||||
Metrics getMetrics();
|
||||
|
||||
void setMetrics(Metrics metrics);
|
||||
|
||||
EssentialsTimer getTimer();
|
||||
|
||||
/**
|
||||
* Get a list of players who are vanished.
|
||||
*
|
||||
* @return A list of players who are vanished
|
||||
* @deprecated Use {@link net.ess3.api.IEssentials#getVanishedPlayersNew()} where possible.
|
||||
*/
|
||||
@Deprecated
|
||||
List<String> getVanishedPlayers();
|
||||
|
||||
@@ -102,5 +109,13 @@ public interface IEssentials extends Plugin {
|
||||
|
||||
Iterable<User> getOnlineUsers();
|
||||
|
||||
SpawnerProvider getSpawnerProvider();
|
||||
SpawnerItemProvider getSpawnerItemProvider();
|
||||
|
||||
SpawnerBlockProvider getSpawnerBlockProvider();
|
||||
|
||||
ServerStateProvider getServerStateProvider();
|
||||
|
||||
ContainerProvider getContainerProvider();
|
||||
|
||||
KnownCommandsProvider getKnownCommandsProvider();
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
|
||||
public interface IEssentialsModule {
|
||||
}
|
||||
@@ -3,8 +3,6 @@ package com.earth2me.essentials;
|
||||
import com.earth2me.essentials.commands.IEssentialsCommand;
|
||||
import com.earth2me.essentials.signs.EssentialsSign;
|
||||
import com.earth2me.essentials.textreader.IText;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.event.EventPriority;
|
||||
@@ -15,9 +13,9 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
public interface ISettings extends IConf {
|
||||
boolean areSignsDisabled();
|
||||
|
||||
@@ -31,6 +29,8 @@ public interface ISettings extends IConf {
|
||||
|
||||
long getBackupInterval();
|
||||
|
||||
boolean isAlwaysRunBackup();
|
||||
|
||||
String getChatFormat(String group);
|
||||
|
||||
int getChatRadius();
|
||||
@@ -47,6 +47,8 @@ public interface ISettings extends IConf {
|
||||
|
||||
String getCurrencySymbol();
|
||||
|
||||
boolean isCurrencySymbolSuffixed();
|
||||
|
||||
int getOversizedStackSize();
|
||||
|
||||
int getDefaultStackSize();
|
||||
@@ -88,7 +90,7 @@ public interface ISettings extends IConf {
|
||||
|
||||
String getNicknamePrefix();
|
||||
|
||||
ChatColor getOperatorColor() throws Exception;
|
||||
String getOperatorColor() throws Exception;
|
||||
|
||||
boolean getPerWarpPermission();
|
||||
|
||||
@@ -104,6 +106,8 @@ public interface ISettings extends IConf {
|
||||
|
||||
boolean getRespawnAtHome();
|
||||
|
||||
boolean isRespawnAtAnchor();
|
||||
|
||||
Set getMultipleHomes();
|
||||
|
||||
int getHomeLimit(String set);
|
||||
@@ -118,6 +122,12 @@ public interface ISettings extends IConf {
|
||||
|
||||
boolean isForceDisableTeleportSafety();
|
||||
|
||||
boolean isAlwaysTeleportSafety();
|
||||
|
||||
boolean isTeleportPassengerDismount();
|
||||
|
||||
boolean isForcePassengerTeleport();
|
||||
|
||||
double getTeleportCooldown();
|
||||
|
||||
double getTeleportDelay();
|
||||
@@ -132,6 +142,8 @@ public interface ISettings extends IConf {
|
||||
|
||||
boolean isDebug();
|
||||
|
||||
void setDebug(boolean debug);
|
||||
|
||||
boolean isEcoDisabled();
|
||||
|
||||
@Deprecated
|
||||
@@ -159,6 +171,8 @@ public interface ISettings extends IConf {
|
||||
|
||||
boolean isEcoLogUpdateEnabled();
|
||||
|
||||
boolean realNamesOnList();
|
||||
|
||||
boolean removeGodOnDisconnect();
|
||||
|
||||
boolean changeDisplayName();
|
||||
@@ -191,9 +205,17 @@ public interface ISettings extends IConf {
|
||||
|
||||
String getAfkListName();
|
||||
|
||||
boolean broadcastAfkMessage();
|
||||
|
||||
boolean areDeathMessagesEnabled();
|
||||
|
||||
void setDebug(boolean debug);
|
||||
KeepInvPolicy getVanishingItemsPolicy();
|
||||
|
||||
KeepInvPolicy getBindingItemsPolicy();
|
||||
|
||||
int getJoinQuitMessagePlayerCount();
|
||||
|
||||
boolean hasJoinQuitMessagePlayerCount();
|
||||
|
||||
Set<String> getNoGodWorlds();
|
||||
|
||||
@@ -237,6 +259,8 @@ public interface ISettings extends IConf {
|
||||
|
||||
void setEssentialsChatActive(boolean b);
|
||||
|
||||
long getMaxMute();
|
||||
|
||||
long getMaxTempban();
|
||||
|
||||
Map<String, Object> getListGroupConfig();
|
||||
@@ -265,8 +289,12 @@ public interface ISettings extends IConf {
|
||||
|
||||
boolean isLastMessageReplyRecipient();
|
||||
|
||||
boolean isReplyToVanished();
|
||||
|
||||
BigDecimal getMinimumPayAmount();
|
||||
|
||||
boolean isPayExcludesIgnoreList();
|
||||
|
||||
long getLastMessageReplyRecipientTimeout();
|
||||
|
||||
boolean isMilkBucketEasterEggEnabled();
|
||||
@@ -285,6 +313,10 @@ public interface ISettings extends IConf {
|
||||
|
||||
boolean isCommandCooldownsEnabled();
|
||||
|
||||
boolean isWorldChangeFlyResetEnabled();
|
||||
|
||||
boolean isWorldChangeSpeedResetEnabled();
|
||||
|
||||
long getCommandCooldownMs(String label);
|
||||
|
||||
Entry<Pattern, Long> getCommandCooldownEntry(String label);
|
||||
@@ -301,6 +333,8 @@ public interface ISettings extends IConf {
|
||||
|
||||
boolean isAllowBulkBuySell();
|
||||
|
||||
boolean isAllowSellNamedItems();
|
||||
|
||||
boolean isAddingPrefixInPlayerlist();
|
||||
|
||||
boolean isAddingSuffixInPlayerlist();
|
||||
@@ -323,11 +357,30 @@ public interface ISettings extends IConf {
|
||||
|
||||
String getItemDbType();
|
||||
|
||||
boolean isForceEnableRecipe();
|
||||
|
||||
boolean allowOldIdSigns();
|
||||
|
||||
boolean isWaterSafe();
|
||||
|
||||
|
||||
boolean isSafeUsermap();
|
||||
|
||||
boolean logCommandBlockCommands();
|
||||
|
||||
Set<Predicate<String>> getNickBlacklist();
|
||||
|
||||
double getMaxProjectileSpeed();
|
||||
|
||||
boolean isRemovingEffectsOnHeal();
|
||||
|
||||
boolean isSpawnIfNoHome();
|
||||
|
||||
boolean isConfirmHomeOverwrite();
|
||||
|
||||
boolean infoAfterDeath();
|
||||
|
||||
enum KeepInvPolicy {
|
||||
KEEP,
|
||||
DELETE,
|
||||
DROP
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package com.earth2me.essentials;
|
||||
|
||||
import org.bukkit.Location;
|
||||
|
||||
|
||||
public interface ITarget {
|
||||
Location getLocation();
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.api.IAsyncTeleport;
|
||||
import com.earth2me.essentials.commands.IEssentialsCommand;
|
||||
import net.ess3.api.ITeleport;
|
||||
import net.ess3.api.MaxMoneyException;
|
||||
import net.ess3.api.events.AfkStatusChangeEvent;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
@@ -14,7 +17,12 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
/**
|
||||
* Provides access to the user abstraction and stored data. Maintainers should add methods to <i>this interface</i>.
|
||||
*
|
||||
* @deprecated External plugins should use {@link net.ess3.api.IUser} instead of this interface, in case future APIs are added.
|
||||
*/
|
||||
@Deprecated
|
||||
public interface IUser {
|
||||
boolean isAuthorized(String node);
|
||||
|
||||
@@ -53,21 +61,26 @@ public interface IUser {
|
||||
*/
|
||||
boolean hasOutstandingTeleportRequest();
|
||||
|
||||
/**
|
||||
* @deprecated This API is not asynchronous. Use {@link com.earth2me.essentials.api.IAsyncTeleport IAsyncTeleport} with {@link IUser#getAsyncTeleport()}
|
||||
*/
|
||||
@Deprecated
|
||||
ITeleport getTeleport();
|
||||
|
||||
IAsyncTeleport getAsyncTeleport();
|
||||
|
||||
BigDecimal getMoney();
|
||||
|
||||
void setMoney(final BigDecimal value) throws MaxMoneyException;
|
||||
|
||||
void setAfk(final boolean set);
|
||||
void setAfk(final boolean set, final AfkStatusChangeEvent.Cause cause);
|
||||
|
||||
/**
|
||||
* 'Hidden' Represents when a player is hidden from others. This status includes when the player is hidden via other
|
||||
* supported plugins. Use isVanished() if you want to check if a user is vanished by Essentials.
|
||||
*
|
||||
* @return If the user is hidden or not
|
||||
*
|
||||
* @see isVanished
|
||||
* @see IUser#isVanished()
|
||||
*/
|
||||
boolean isHidden();
|
||||
|
||||
@@ -95,8 +108,7 @@ public interface IUser {
|
||||
* plugin.
|
||||
*
|
||||
* @return If the user is vanished or not
|
||||
*
|
||||
* @see isHidden
|
||||
* @see IUser#isHidden()
|
||||
*/
|
||||
boolean isVanished();
|
||||
|
||||
@@ -139,10 +151,13 @@ public interface IUser {
|
||||
|
||||
boolean isAfk();
|
||||
|
||||
void setIgnoreMsg(boolean ignoreMsg);
|
||||
@Deprecated
|
||||
void setAfk(final boolean set);
|
||||
|
||||
boolean isIgnoreMsg();
|
||||
|
||||
void setIgnoreMsg(boolean ignoreMsg);
|
||||
|
||||
void setConfigProperty(String node, Object object);
|
||||
|
||||
Set<String> getConfigKeys();
|
||||
@@ -150,13 +165,13 @@ public interface IUser {
|
||||
Map<String, Object> getConfigMap();
|
||||
|
||||
Map<String, Object> getConfigMap(String node);
|
||||
|
||||
|
||||
Map<Pattern, Long> getCommandCooldowns();
|
||||
|
||||
Date getCommandCooldownExpiry(String label);
|
||||
|
||||
|
||||
void addCommandCooldown(Pattern pattern, Date expiresAt, boolean save);
|
||||
|
||||
|
||||
boolean clearCommandCooldown(Pattern pattern);
|
||||
|
||||
/*
|
||||
@@ -168,22 +183,24 @@ public interface IUser {
|
||||
|
||||
String getName();
|
||||
|
||||
String getDisplayName();
|
||||
|
||||
String getAfkMessage();
|
||||
|
||||
void setAfkMessage(final String message);
|
||||
|
||||
|
||||
long getAfkSince();
|
||||
|
||||
|
||||
boolean isAcceptingPay();
|
||||
|
||||
|
||||
void setAcceptingPay(boolean acceptingPay);
|
||||
|
||||
|
||||
boolean isPromptingPayConfirm();
|
||||
|
||||
|
||||
void setPromptingPayConfirm(boolean prompt);
|
||||
|
||||
|
||||
boolean isPromptingClearConfirm();
|
||||
|
||||
|
||||
void setPromptingClearConfirm(boolean prompt);
|
||||
|
||||
boolean isLastMessageReplyRecipient();
|
||||
@@ -191,4 +208,6 @@ public interface IUser {
|
||||
void setLastMessageReplyRecipient(boolean enabled);
|
||||
|
||||
Map<User, BigDecimal> getConfirmingPayments();
|
||||
|
||||
Block getTargetBlock(int maxDistance);
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import org.bukkit.event.block.BlockDamageEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.event.player.PlayerGameModeChangeEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerRespawnEvent;
|
||||
@@ -24,13 +25,17 @@ import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Jails extends AsyncStorageObjectHolder<com.earth2me.essentials.settings.Jails> implements net.ess3.api.IJails {
|
||||
private static final transient Logger LOGGER = Bukkit.getLogger();
|
||||
private static transient boolean enabled = false;
|
||||
@@ -71,7 +76,7 @@ public class Jails extends AsyncStorageObjectHolder<com.earth2me.essentials.sett
|
||||
}
|
||||
|
||||
private void checkRegister() {
|
||||
if (enabled == false && getCount() > 0) {
|
||||
if (!enabled && getCount() > 0) {
|
||||
registerListeners();
|
||||
}
|
||||
}
|
||||
@@ -83,7 +88,7 @@ public class Jails extends AsyncStorageObjectHolder<com.earth2me.essentials.sett
|
||||
if (getData().getJails() == null || jailName == null || !getData().getJails().containsKey(jailName.toLowerCase(Locale.ENGLISH))) {
|
||||
throw new Exception(tl("jailNotExist"));
|
||||
}
|
||||
Location loc = getData().getJails().get(jailName.toLowerCase(Locale.ENGLISH));
|
||||
final Location loc = getData().getJails().get(jailName.toLowerCase(Locale.ENGLISH));
|
||||
if (loc == null || loc.getWorld() == null) {
|
||||
throw new Exception(tl("jailNotExist"));
|
||||
}
|
||||
@@ -100,7 +105,7 @@ public class Jails extends AsyncStorageObjectHolder<com.earth2me.essentials.sett
|
||||
if (getData().getJails() == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return new ArrayList<String>(getData().getJails().keySet());
|
||||
return new ArrayList<>(getData().getJails().keySet());
|
||||
} finally {
|
||||
unlock();
|
||||
}
|
||||
@@ -119,12 +124,16 @@ public class Jails extends AsyncStorageObjectHolder<com.earth2me.essentials.sett
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated This method does not use asynchronous teleportation. Use {@link Jails#sendToJail(IUser, String, CompletableFuture)}
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public void sendToJail(final IUser user, final String jail) throws Exception {
|
||||
acquireReadLock();
|
||||
try {
|
||||
if (user.getBase().isOnline()) {
|
||||
Location loc = getJail(jail);
|
||||
final Location loc = getJail(jail);
|
||||
user.getTeleport().now(loc, false, TeleportCause.COMMAND);
|
||||
}
|
||||
user.setJail(jail);
|
||||
@@ -133,12 +142,28 @@ public class Jails extends AsyncStorageObjectHolder<com.earth2me.essentials.sett
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendToJail(final IUser user, final String jail, final CompletableFuture<Boolean> future) throws Exception {
|
||||
acquireReadLock();
|
||||
try {
|
||||
if (user.getBase().isOnline()) {
|
||||
final Location loc = getJail(jail);
|
||||
user.getAsyncTeleport().now(loc, false, TeleportCause.COMMAND, future);
|
||||
future.thenAccept(success -> user.setJail(jail));
|
||||
return;
|
||||
}
|
||||
user.setJail(jail);
|
||||
} finally {
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setJail(final String jailName, final Location loc) throws Exception {
|
||||
acquireWriteLock();
|
||||
try {
|
||||
if (getData().getJails() == null) {
|
||||
getData().setJails(new HashMap<String, Location>());
|
||||
getData().setJails(new HashMap<>());
|
||||
}
|
||||
getData().getJails().put(jailName.toLowerCase(Locale.ENGLISH), loc);
|
||||
} finally {
|
||||
@@ -150,17 +175,16 @@ public class Jails extends AsyncStorageObjectHolder<com.earth2me.essentials.sett
|
||||
public int getCount() {
|
||||
try {
|
||||
return getList().size();
|
||||
} catch (Exception ex) {
|
||||
} catch (final Exception ex) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class JailListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onJailBlockBreak(final BlockBreakEvent event) {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (user.isJailed()) {
|
||||
if (user.isJailed() && !user.isAuthorized("essentials.jail.allow-break")) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@@ -168,7 +192,7 @@ public class Jails extends AsyncStorageObjectHolder<com.earth2me.essentials.sett
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onJailBlockPlace(final BlockPlaceEvent event) {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (user.isJailed()) {
|
||||
if (user.isJailed() && !user.isAuthorized("essentials.jail.allow-place")) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@@ -176,7 +200,7 @@ public class Jails extends AsyncStorageObjectHolder<com.earth2me.essentials.sett
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onJailBlockDamage(final BlockDamageEvent event) {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (user.isJailed()) {
|
||||
if (user.isJailed() && !user.isAuthorized("essentials.jail.allow-block-damage")) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@@ -197,6 +221,14 @@ public class Jails extends AsyncStorageObjectHolder<com.earth2me.essentials.sett
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onJailPlayerInteract(final PlayerInteractEvent event) {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (user.isJailed() && !user.isAuthorized("essentials.jail.allow-interact")) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onJailPlayerGameModeChange(final PlayerGameModeChangeEvent event) {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (user.isJailed()) {
|
||||
event.setCancelled(true);
|
||||
@@ -212,7 +244,7 @@ public class Jails extends AsyncStorageObjectHolder<com.earth2me.essentials.sett
|
||||
|
||||
try {
|
||||
event.setRespawnLocation(getJail(user.getJail()));
|
||||
} catch (Exception ex) {
|
||||
} catch (final Exception ex) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
LOGGER.log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()), ex);
|
||||
} else {
|
||||
@@ -230,7 +262,7 @@ public class Jails extends AsyncStorageObjectHolder<com.earth2me.essentials.sett
|
||||
|
||||
try {
|
||||
event.setTo(getJail(user.getJail()));
|
||||
} catch (Exception ex) {
|
||||
} catch (final Exception ex) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
LOGGER.log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()), ex);
|
||||
} else {
|
||||
@@ -249,16 +281,22 @@ public class Jails extends AsyncStorageObjectHolder<com.earth2me.essentials.sett
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
sendToJail(user, user.getJail());
|
||||
} catch (Exception ex) {
|
||||
final CompletableFuture<Boolean> future = new CompletableFuture<>();
|
||||
future.exceptionally(ex -> {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
LOGGER.log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()), ex);
|
||||
} else {
|
||||
LOGGER.log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()));
|
||||
}
|
||||
return false;
|
||||
});
|
||||
future.thenAccept(success -> user.sendMessage(tl("jailMessage")));
|
||||
|
||||
try {
|
||||
sendToJail(user, user.getJail(), future);
|
||||
} catch (final Exception ex) {
|
||||
future.completeExceptionally(ex);
|
||||
}
|
||||
user.sendMessage(tl("jailMessage"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,18 +7,23 @@ import com.earth2me.essentials.textreader.IText;
|
||||
import com.earth2me.essentials.textreader.KeywordReplacer;
|
||||
import com.earth2me.essentials.textreader.SimpleTextInput;
|
||||
import com.earth2me.essentials.utils.DateUtil;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.events.KitClaimEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Kit {
|
||||
final IEssentials ess;
|
||||
final String kitName;
|
||||
@@ -47,10 +52,9 @@ public class Kit {
|
||||
}
|
||||
|
||||
public void checkDelay(final User user) throws Exception {
|
||||
long nextUse = getNextUse(user);
|
||||
final long nextUse = getNextUse(user);
|
||||
|
||||
if (nextUse == 0L) {
|
||||
return;
|
||||
} else if (nextUse < 0L) {
|
||||
user.sendMessage(tl("kitOnce"));
|
||||
throw new NoChargeException();
|
||||
@@ -84,7 +88,7 @@ public class Kit {
|
||||
try {
|
||||
// Make sure delay is valid
|
||||
delay = kit.containsKey("delay") ? ((Number) kit.get("delay")).doubleValue() : 0.0d;
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
throw new Exception(tl("kitError2"));
|
||||
}
|
||||
|
||||
@@ -122,10 +126,10 @@ public class Kit {
|
||||
throw new Exception(tl("kitNotFound"));
|
||||
}
|
||||
try {
|
||||
final List<String> itemList = new ArrayList<String>();
|
||||
final List<String> itemList = new ArrayList<>();
|
||||
final Object kitItems = kit.get("items");
|
||||
if (kitItems instanceof List) {
|
||||
for (Object item : (List) kitItems) {
|
||||
for (final Object item : (List) kitItems) {
|
||||
if (item instanceof String) {
|
||||
itemList.add(item.toString());
|
||||
continue;
|
||||
@@ -135,36 +139,44 @@ public class Kit {
|
||||
return itemList;
|
||||
}
|
||||
throw new Exception("Invalid item list");
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
ess.getLogger().log(Level.WARNING, "Error parsing kit " + kitName + ": " + e.getMessage());
|
||||
throw new Exception(tl("kitError2"), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void expandItems(final User user) throws Exception {
|
||||
expandItems(user, getItems(user));
|
||||
public boolean expandItems(final User user) throws Exception {
|
||||
return expandItems(user, getItems(user));
|
||||
}
|
||||
|
||||
public void expandItems(final User user, final List<String> items) throws Exception {
|
||||
public boolean expandItems(final User user, final List<String> items) throws Exception {
|
||||
try {
|
||||
IText input = new SimpleTextInput(items);
|
||||
IText output = new KeywordReplacer(input, user.getSource(), ess, true, true);
|
||||
final IText input = new SimpleTextInput(items);
|
||||
final IText output = new KeywordReplacer(input, user.getSource(), ess, true, true);
|
||||
|
||||
final KitClaimEvent event = new KitClaimEvent(user, this);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean spew = false;
|
||||
final boolean allowUnsafe = ess.getSettings().allowUnsafeEnchantments();
|
||||
for (String kitItem : output.getLines()) {
|
||||
if (kitItem.startsWith(ess.getSettings().getCurrencySymbol())) {
|
||||
BigDecimal value = new BigDecimal(kitItem.substring(ess.getSettings().getCurrencySymbol().length()).trim());
|
||||
Trade t = new Trade(value, ess);
|
||||
t.pay(user, OverflowType.DROP);
|
||||
final boolean currencyIsSuffix = ess.getSettings().isCurrencySymbolSuffixed();
|
||||
final List<ItemStack> itemList = new ArrayList<>();
|
||||
final List<String> commandQueue = new ArrayList<>();
|
||||
final List<String> moneyQueue = new ArrayList<>();
|
||||
for (final String kitItem : output.getLines()) {
|
||||
if (!currencyIsSuffix ? kitItem.startsWith(ess.getSettings().getCurrencySymbol()) : kitItem.endsWith(ess.getSettings().getCurrencySymbol())) {
|
||||
moneyQueue.add(NumberUtil.sanitizeCurrencyString(kitItem, ess));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (kitItem.startsWith("/")) {
|
||||
String command = kitItem.substring(1);
|
||||
String name = user.getName();
|
||||
final String name = user.getName();
|
||||
command = command.replace("{player}", name);
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command);
|
||||
commandQueue.add(command);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -182,17 +194,22 @@ public class Kit {
|
||||
metaStack.parseStringMeta(null, allowUnsafe, parts, 2, ess);
|
||||
}
|
||||
|
||||
final Map<Integer, ItemStack> overfilled;
|
||||
final boolean allowOversizedStacks = user.isAuthorized("essentials.oversizedstacks");
|
||||
itemList.add(metaStack.getItemStack());
|
||||
}
|
||||
|
||||
final Map<Integer, ItemStack> overfilled;
|
||||
final boolean allowOversizedStacks = user.isAuthorized("essentials.oversizedstacks");
|
||||
final boolean isDropItemsIfFull = ess.getSettings().isDropItemsIfFull();
|
||||
if (isDropItemsIfFull) {
|
||||
if (allowOversizedStacks) {
|
||||
overfilled = InventoryWorkaround.addOversizedItems(user.getBase().getInventory(), ess.getSettings().getOversizedStackSize(), metaStack.getItemStack());
|
||||
overfilled = InventoryWorkaround.addOversizedItems(user.getBase().getInventory(), ess.getSettings().getOversizedStackSize(), itemList.toArray(new ItemStack[0]));
|
||||
} else {
|
||||
overfilled = InventoryWorkaround.addItems(user.getBase().getInventory(), metaStack.getItemStack());
|
||||
overfilled = InventoryWorkaround.addItems(user.getBase().getInventory(), itemList.toArray(new ItemStack[0]));
|
||||
}
|
||||
for (ItemStack itemStack : overfilled.values()) {
|
||||
for (final ItemStack itemStack : overfilled.values()) {
|
||||
int spillAmount = itemStack.getAmount();
|
||||
if (!allowOversizedStacks) {
|
||||
itemStack.setAmount(spillAmount < itemStack.getMaxStackSize() ? spillAmount : itemStack.getMaxStackSize());
|
||||
itemStack.setAmount(Math.min(spillAmount, itemStack.getMaxStackSize()));
|
||||
}
|
||||
while (spillAmount > 0) {
|
||||
user.getWorld().dropItemNaturally(user.getLocation(), itemStack);
|
||||
@@ -200,15 +217,40 @@ public class Kit {
|
||||
}
|
||||
spew = true;
|
||||
}
|
||||
} else {
|
||||
if (allowOversizedStacks) {
|
||||
overfilled = InventoryWorkaround.addAllOversizedItems(user.getBase().getInventory(), ess.getSettings().getOversizedStackSize(), itemList.toArray(new ItemStack[0]));
|
||||
} else {
|
||||
overfilled = InventoryWorkaround.addAllItems(user.getBase().getInventory(), itemList.toArray(new ItemStack[0]));
|
||||
}
|
||||
if (overfilled != null) {
|
||||
user.sendMessage(tl("kitInvFullNoDrop"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
user.getBase().updateInventory();
|
||||
|
||||
// Process money & command queues
|
||||
// Done after all items have been processed so commands are not run and money is not given if
|
||||
// an error occurs during the item giving process
|
||||
for (final String valueString : moneyQueue) {
|
||||
final BigDecimal value = new BigDecimal(valueString.trim());
|
||||
final Trade t = new Trade(value, ess);
|
||||
t.pay(user, OverflowType.DROP);
|
||||
}
|
||||
|
||||
for (final String cmd : commandQueue) {
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), cmd);
|
||||
}
|
||||
|
||||
if (spew) {
|
||||
user.sendMessage(tl("kitInvFull"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
user.getBase().updateInventory();
|
||||
ess.getLogger().log(Level.WARNING, e.getMessage());
|
||||
throw new Exception(tl("kitError2"), e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -35,7 +35,7 @@ public class Kits implements IConf {
|
||||
if (config.isConfigurationSection("kits")) {
|
||||
final ConfigurationSection section = config.getConfigurationSection("kits");
|
||||
final ConfigurationSection newSection = new MemoryConfiguration();
|
||||
for (String kitItem : section.getKeys(false)) {
|
||||
for (final String kitItem : section.getKeys(false)) {
|
||||
if (section.isConfigurationSection(kitItem)) {
|
||||
newSection.set(kitItem.toLowerCase(Locale.ENGLISH), section.getConfigurationSection(kitItem));
|
||||
}
|
||||
@@ -64,14 +64,28 @@ public class Kits implements IConf {
|
||||
// you just found if you don't toLowercase it.
|
||||
if (kits.isConfigurationSection(name.toLowerCase())) {
|
||||
return kits.getConfigurationSection(name.toLowerCase()).getValues(true);
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addKit(String name, List<String> lines, long delay) {
|
||||
// Tries to find an existing kit name that matches the given name, ignoring case. Returns null if no match.
|
||||
public String matchKit(final String name) {
|
||||
if (config.isConfigurationSection("kits")) {
|
||||
final ConfigurationSection section = config.getConfigurationSection("kits");
|
||||
if (section != null) {
|
||||
for (final String kitName : section.getKeys(false)) {
|
||||
if (kitName.equalsIgnoreCase(name)) {
|
||||
return kitName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addKit(final String name, final List<String> lines, final long delay) {
|
||||
// Will overwrite but w/e
|
||||
config.set("kits." + name + ".delay", delay);
|
||||
config.set("kits." + name + ".items", lines);
|
||||
@@ -79,23 +93,29 @@ public class Kits implements IConf {
|
||||
config.save();
|
||||
}
|
||||
|
||||
public void removeKit(final String name) {
|
||||
config.set("kits." + name, null);
|
||||
kits = _getKits();
|
||||
config.save();
|
||||
}
|
||||
|
||||
public String listKits(final net.ess3.api.IEssentials ess, final User user) throws Exception {
|
||||
try {
|
||||
final ConfigurationSection kits = config.getConfigurationSection("kits");
|
||||
final StringBuilder list = new StringBuilder();
|
||||
for (String kitItem : kits.getKeys(false)) {
|
||||
for (final String kitItem : kits.getKeys(false)) {
|
||||
if (user == null) {
|
||||
list.append(" ").append(capitalCase(kitItem));
|
||||
} else if (user.isAuthorized("essentials.kits." + kitItem.toLowerCase(Locale.ENGLISH))) {
|
||||
String cost = "";
|
||||
String name = capitalCase(kitItem);
|
||||
BigDecimal costPrice = new Trade("kit-" + kitItem.toLowerCase(Locale.ENGLISH), ess).getCommandCost(user);
|
||||
final BigDecimal costPrice = new Trade("kit-" + kitItem.toLowerCase(Locale.ENGLISH), ess).getCommandCost(user);
|
||||
if (costPrice.signum() > 0) {
|
||||
cost = tl("kitCost", NumberUtil.displayCurrency(costPrice, ess));
|
||||
}
|
||||
|
||||
Kit kit = new Kit(kitItem, ess);
|
||||
double nextUse = kit.getNextUse(user);
|
||||
final Kit kit = new Kit(kitItem, ess);
|
||||
final double nextUse = kit.getNextUse(user);
|
||||
if (nextUse == -1 && ess.getSettings().isSkippingUsedOneTimeKitsFromKitList()) {
|
||||
continue;
|
||||
} else if (nextUse != 0) {
|
||||
@@ -106,7 +126,7 @@ public class Kits implements IConf {
|
||||
}
|
||||
}
|
||||
return list.toString().trim();
|
||||
} catch (Exception ex) {
|
||||
} catch (final Exception ex) {
|
||||
throw new Exception(tl("kitError"), ex);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,11 +2,10 @@ package com.earth2me.essentials;
|
||||
|
||||
import org.bukkit.Location;
|
||||
|
||||
|
||||
public class LocationTarget implements ITarget {
|
||||
private final Location location;
|
||||
|
||||
LocationTarget(Location location) {
|
||||
LocationTarget(final Location location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
@@ -14,4 +13,4 @@ public class LocationTarget implements ITarget {
|
||||
public Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,16 @@ package com.earth2me.essentials;
|
||||
import net.ess3.api.IEssentials;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.math.BigInteger;
|
||||
import java.security.DigestInputStream;
|
||||
import java.security.DigestOutputStream;
|
||||
@@ -16,7 +25,6 @@ import java.util.logging.Level;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class ManagedFile {
|
||||
private static final int BUFFERSIZE = 1024 * 8;
|
||||
private final transient File file;
|
||||
@@ -29,7 +37,7 @@ public class ManagedFile {
|
||||
if (checkForVersion(file, ess.getDescription().getVersion()) && !file.delete()) {
|
||||
throw new IOException("Could not delete file " + file.toString());
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
} catch (final IOException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
@@ -37,20 +45,17 @@ public class ManagedFile {
|
||||
if (!file.exists()) {
|
||||
try {
|
||||
copyResourceAscii("/" + filename, file);
|
||||
} catch (IOException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, tl("itemsCsvNotLoaded"), ex);
|
||||
} catch (final IOException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, tl("itemsCsvNotLoaded", filename), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void copyResourceAscii(final String resourceName, final File file) throws IOException {
|
||||
final InputStreamReader reader = new InputStreamReader(ManagedFile.class.getResourceAsStream(resourceName));
|
||||
try {
|
||||
try (final InputStreamReader reader = new InputStreamReader(ManagedFile.class.getResourceAsStream(resourceName))) {
|
||||
final MessageDigest digest = getDigest();
|
||||
final DigestOutputStream digestStream = new DigestOutputStream(new FileOutputStream(file), digest);
|
||||
try {
|
||||
final OutputStreamWriter writer = new OutputStreamWriter(digestStream);
|
||||
try {
|
||||
try (final DigestOutputStream digestStream = new DigestOutputStream(new FileOutputStream(file), digest)) {
|
||||
try (final OutputStreamWriter writer = new OutputStreamWriter(digestStream)) {
|
||||
final char[] buffer = new char[BUFFERSIZE];
|
||||
do {
|
||||
final int length = reader.read(buffer);
|
||||
@@ -66,14 +71,8 @@ public class ManagedFile {
|
||||
digestStream.on(false);
|
||||
digestStream.write('#');
|
||||
digestStream.write(hashInt.toString(16).getBytes());
|
||||
} finally {
|
||||
writer.close();
|
||||
}
|
||||
} finally {
|
||||
digestStream.close();
|
||||
}
|
||||
} finally {
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,8 +80,7 @@ public class ManagedFile {
|
||||
if (file.length() < 33) {
|
||||
return false;
|
||||
}
|
||||
final BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
|
||||
try {
|
||||
try (final BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) {
|
||||
final byte[] buffer = new byte[(int) file.length()];
|
||||
int position = 0;
|
||||
do {
|
||||
@@ -96,8 +94,7 @@ public class ManagedFile {
|
||||
if (bais.skip(file.length() - 33) != file.length() - 33) {
|
||||
return false;
|
||||
}
|
||||
final BufferedReader reader = new BufferedReader(new InputStreamReader(bais));
|
||||
try {
|
||||
try (final BufferedReader reader = new BufferedReader(new InputStreamReader(bais))) {
|
||||
String hash = reader.readLine();
|
||||
if (hash != null && hash.matches("#[a-f0-9]{32}")) {
|
||||
hash = hash.substring(1);
|
||||
@@ -108,8 +105,7 @@ public class ManagedFile {
|
||||
if (!versioncheck.equalsIgnoreCase(version)) {
|
||||
bais.reset();
|
||||
final MessageDigest digest = getDigest();
|
||||
final DigestInputStream digestStream = new DigestInputStream(bais, digest);
|
||||
try {
|
||||
try (final DigestInputStream digestStream = new DigestInputStream(bais, digest)) {
|
||||
final byte[] bytes = new byte[(int) file.length() - 33];
|
||||
digestStream.read(bytes);
|
||||
final BigInteger correct = new BigInteger(hash, 16);
|
||||
@@ -119,17 +115,11 @@ public class ManagedFile {
|
||||
} else {
|
||||
Bukkit.getLogger().warning("File " + file.toString() + " has been modified by user and file version differs, please update the file manually.");
|
||||
}
|
||||
} finally {
|
||||
digestStream.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
reader.close();
|
||||
}
|
||||
} finally {
|
||||
bis.close();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -137,16 +127,15 @@ public class ManagedFile {
|
||||
public static MessageDigest getDigest() throws IOException {
|
||||
try {
|
||||
return MessageDigest.getInstance("MD5");
|
||||
} catch (NoSuchAlgorithmException ex) {
|
||||
} catch (final NoSuchAlgorithmException ex) {
|
||||
throw new IOException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getLines() {
|
||||
try {
|
||||
final BufferedReader reader = new BufferedReader(new FileReader(file));
|
||||
try {
|
||||
final List<String> lines = new ArrayList<String>();
|
||||
try (final BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
||||
final List<String> lines = new ArrayList<>();
|
||||
do {
|
||||
final String line = reader.readLine();
|
||||
if (line == null) {
|
||||
@@ -156,10 +145,8 @@ public class ManagedFile {
|
||||
}
|
||||
} while (true);
|
||||
return lines;
|
||||
} finally {
|
||||
reader.close();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
} catch (final IOException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@@ -10,8 +10,6 @@ import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.google.common.base.Joiner;
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.nms.refl.ReflUtil;
|
||||
|
||||
import org.apache.commons.lang.ArrayUtils;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.FireworkEffect;
|
||||
@@ -21,28 +19,44 @@ import org.bukkit.block.banner.PatternType;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.*;
|
||||
import org.bukkit.inventory.meta.BannerMeta;
|
||||
import org.bukkit.inventory.meta.BlockStateMeta;
|
||||
import org.bukkit.inventory.meta.BookMeta;
|
||||
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
|
||||
import org.bukkit.inventory.meta.FireworkMeta;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.LeatherArmorMeta;
|
||||
import org.bukkit.inventory.meta.PotionMeta;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
import org.bukkit.potion.Potion;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class MetaItemStack {
|
||||
private static final Map<String, DyeColor> colorMap = new HashMap<>();
|
||||
private static final Map<String, FireworkEffect.Type> fireworkShape = new HashMap<>();
|
||||
private static int bukkitUnbreakableSupport = -1;
|
||||
private static Method spigotMethod;
|
||||
private static Method setUnbreakableMethod;
|
||||
private static boolean useNewSkullMethod = true;
|
||||
|
||||
static {
|
||||
for (DyeColor color : DyeColor.values()) {
|
||||
for (final DyeColor color : DyeColor.values()) {
|
||||
colorMap.put(color.name(), color);
|
||||
}
|
||||
for (FireworkEffect.Type type : FireworkEffect.Type.values()) {
|
||||
for (final FireworkEffect.Type type : FireworkEffect.Type.values()) {
|
||||
fireworkShape.put(type.name(), type);
|
||||
}
|
||||
}
|
||||
@@ -65,6 +79,24 @@ public class MetaItemStack {
|
||||
this.stack = stack.clone();
|
||||
}
|
||||
|
||||
private static void setSkullOwner(final IEssentials ess, final ItemStack stack, final String owner) {
|
||||
if (!(stack.getItemMeta() instanceof SkullMeta)) return;
|
||||
|
||||
final SkullMeta meta = (SkullMeta) stack.getItemMeta();
|
||||
if (useNewSkullMethod) {
|
||||
try {
|
||||
meta.setOwningPlayer(ess.getServer().getOfflinePlayer(owner));
|
||||
stack.setItemMeta(meta);
|
||||
return;
|
||||
} catch (final NoSuchMethodError e) {
|
||||
useNewSkullMethod = false;
|
||||
}
|
||||
}
|
||||
|
||||
meta.setOwner(owner);
|
||||
stack.setItemMeta(meta);
|
||||
}
|
||||
|
||||
public ItemStack getItemStack() {
|
||||
return stack;
|
||||
}
|
||||
@@ -103,32 +135,27 @@ public class MetaItemStack {
|
||||
try {
|
||||
ess.getServer().getUnsafe().modifyItemStack(stack.clone(), "{}");
|
||||
return true;
|
||||
} catch (NullPointerException npe) {
|
||||
} catch (final NoSuchMethodError nsme) {
|
||||
return true;
|
||||
} catch (final Throwable npe) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "Itemstack is invalid", npe);
|
||||
}
|
||||
return false;
|
||||
} catch (NoSuchMethodError nsme) {
|
||||
return true;
|
||||
} catch (Throwable throwable) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "Itemstack is invalid", throwable);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void parseStringMeta(final CommandSource sender, final boolean allowUnsafe, String[] string, int fromArg, final IEssentials ess) throws Exception {
|
||||
public void parseStringMeta(final CommandSource sender, final boolean allowUnsafe, final String[] string, final int fromArg, final IEssentials ess) throws Exception {
|
||||
if (string[fromArg].startsWith("{") && hasMetaPermission(sender, "vanilla", false, true, ess)) {
|
||||
try {
|
||||
stack = ess.getServer().getUnsafe().modifyItemStack(stack, Joiner.on(' ').join(Arrays.asList(string).subList(fromArg, string.length)));
|
||||
} catch (NullPointerException npe) {
|
||||
} catch (final NullPointerException npe) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "Itemstack is invalid", npe);
|
||||
}
|
||||
} catch (NoSuchMethodError nsme) {
|
||||
} catch (final NoSuchMethodError nsme) {
|
||||
throw new Exception(tl("noMetaJson"), nsme);
|
||||
} catch (Throwable throwable) {
|
||||
} catch (final Throwable throwable) {
|
||||
throw new Exception(throwable.getMessage(), throwable);
|
||||
}
|
||||
} else {
|
||||
@@ -139,8 +166,8 @@ public class MetaItemStack {
|
||||
if (!hasMetaPermission(sender, "firework", true, true, ess)) {
|
||||
throw new Exception(tl("noMetaFirework"));
|
||||
}
|
||||
FireworkEffect effect = builder.build();
|
||||
FireworkMeta fmeta = (FireworkMeta) stack.getItemMeta();
|
||||
final FireworkEffect effect = builder.build();
|
||||
final FireworkMeta fmeta = (FireworkMeta) stack.getItemMeta();
|
||||
fmeta.addEffect(effect);
|
||||
if (fmeta.getEffects().size() > 1 && !hasMetaPermission(sender, "firework-multiple", true, true, ess)) {
|
||||
throw new Exception(tl("multipleCharges"));
|
||||
@@ -156,7 +183,7 @@ public class MetaItemStack {
|
||||
return;
|
||||
}
|
||||
|
||||
Material WRITTEN_BOOK = EnumUtil.getMaterial("WRITTEN_BOOK");
|
||||
final Material WRITTEN_BOOK = EnumUtil.getMaterial("WRITTEN_BOOK");
|
||||
|
||||
if (split.length > 1 && split[0].equalsIgnoreCase("name") && hasMetaPermission(sender, "name", false, true, ess)) {
|
||||
final String displayName = FormatUtil.replaceFormat(split[1].replace('_', ' '));
|
||||
@@ -164,22 +191,20 @@ public class MetaItemStack {
|
||||
meta.setDisplayName(displayName);
|
||||
stack.setItemMeta(meta);
|
||||
} else if (split.length > 1 && (split[0].equalsIgnoreCase("lore") || split[0].equalsIgnoreCase("desc")) && hasMetaPermission(sender, "lore", false, true, ess)) {
|
||||
final List<String> lore = new ArrayList<String>();
|
||||
for (String line : split[1].split("\\|")) {
|
||||
lore.add(FormatUtil.replaceFormat(line.replace('_', ' ')));
|
||||
final List<String> lore = new ArrayList<>();
|
||||
for (final String line : split[1].split("(?<!\\\\)\\|")) {
|
||||
lore.add(FormatUtil.replaceFormat(line.replace('_', ' ').replace("\\|", "|")));
|
||||
}
|
||||
final ItemMeta meta = stack.getItemMeta();
|
||||
meta.setLore(lore);
|
||||
stack.setItemMeta(meta);
|
||||
} else if (split[0].equalsIgnoreCase("unbreakable") && hasMetaPermission(sender, "unbreakable", false, true, ess)) {
|
||||
boolean value = split.length > 1 ? Boolean.valueOf(split[1]) : true;
|
||||
final boolean value = split.length <= 1 || Boolean.parseBoolean(split[1]);
|
||||
setUnbreakable(stack, value);
|
||||
} else if (split.length > 1 && (split[0].equalsIgnoreCase("player") || split[0].equalsIgnoreCase("owner")) && hasMetaPermission(sender, "head", false, true, ess)) {
|
||||
if (MaterialUtil.isPlayerHead(stack.getType(), stack.getDurability())) {
|
||||
final String owner = split[1];
|
||||
final SkullMeta meta = (SkullMeta) stack.getItemMeta();
|
||||
meta.setOwningPlayer(ess.getServer().getOfflinePlayer(owner));
|
||||
stack.setItemMeta(meta);
|
||||
setSkullOwner(ess, stack, owner);
|
||||
} else {
|
||||
throw new Exception(tl("onlyPlayerSkulls"));
|
||||
}
|
||||
@@ -188,7 +213,7 @@ public class MetaItemStack {
|
||||
final IText input = new BookInput("book", true, ess);
|
||||
final BookPager pager = new BookPager(input);
|
||||
|
||||
List<String> pages = pager.getPages(split[1]);
|
||||
final List<String> pages = pager.getPages(split[1]);
|
||||
meta.setPages(pages);
|
||||
stack.setItemMeta(meta);
|
||||
} else if (split.length > 1 && split[0].equalsIgnoreCase("author") && stack.getType() == WRITTEN_BOOK && hasMetaPermission(sender, "author", false, true, ess)) {
|
||||
@@ -201,7 +226,7 @@ public class MetaItemStack {
|
||||
final BookMeta meta = (BookMeta) stack.getItemMeta();
|
||||
meta.setTitle(title);
|
||||
stack.setItemMeta(meta);
|
||||
} else if (split.length > 1 && split[0].equalsIgnoreCase("power") && (MaterialUtil.isFirework(stack.getType()))&& hasMetaPermission(sender, "firework-power", false, true, ess)) {
|
||||
} else if (split.length > 1 && split[0].equalsIgnoreCase("power") && MaterialUtil.isFirework(stack.getType()) && hasMetaPermission(sender, "firework-power", false, true, ess)) {
|
||||
final int power = NumberUtil.isInt(split[1]) ? Integer.parseInt(split[1]) : 0;
|
||||
final FireworkMeta meta = (FireworkMeta) stack.getItemMeta();
|
||||
meta.setPower(power > 3 ? 4 : power);
|
||||
@@ -226,7 +251,7 @@ public class MetaItemStack {
|
||||
if (color.length == 1 && (NumberUtil.isInt(color[0]) || color[0].startsWith("#"))) {
|
||||
// Either integer or hexadecimal
|
||||
final LeatherArmorMeta meta = (LeatherArmorMeta) stack.getItemMeta();
|
||||
String input = color[0];
|
||||
final String input = color[0];
|
||||
if (input.startsWith("#")) { // Hex
|
||||
meta.setColor(Color.fromRGB(
|
||||
Integer.valueOf(input.substring(1, 3), 16),
|
||||
@@ -252,16 +277,16 @@ public class MetaItemStack {
|
||||
}
|
||||
|
||||
public void addItemFlags(final String string) throws Exception {
|
||||
String[] separate = splitPattern.split(string, 2);
|
||||
final String[] separate = splitPattern.split(string, 2);
|
||||
if (separate.length != 2) {
|
||||
throw new Exception(tl("invalidItemFlagMeta", string));
|
||||
}
|
||||
|
||||
String[] split = separate[1].split(",");
|
||||
ItemMeta meta = stack.getItemMeta();
|
||||
final String[] split = separate[1].split(",");
|
||||
final ItemMeta meta = stack.getItemMeta();
|
||||
|
||||
for (String s : split) {
|
||||
for (ItemFlag flag : ItemFlag.values()) {
|
||||
for (final String s : split) {
|
||||
for (final ItemFlag flag : ItemFlag.values()) {
|
||||
if (s.equalsIgnoreCase(flag.name())) {
|
||||
meta.addItemFlags(flag);
|
||||
}
|
||||
@@ -276,7 +301,7 @@ public class MetaItemStack {
|
||||
}
|
||||
|
||||
public void addFireworkMeta(final CommandSource sender, final boolean allowShortName, final String string, final IEssentials ess) throws Exception {
|
||||
if (MaterialUtil.isFirework(stack.getType())) {
|
||||
if (MaterialUtil.isFirework(stack.getType())) {
|
||||
final String[] split = splitPattern.split(string, 2);
|
||||
if (split.length < 2) {
|
||||
return;
|
||||
@@ -287,8 +312,8 @@ public class MetaItemStack {
|
||||
if (!hasMetaPermission(sender, "firework", true, true, ess)) {
|
||||
throw new Exception(tl("noMetaFirework"));
|
||||
}
|
||||
FireworkEffect effect = builder.build();
|
||||
FireworkMeta fmeta = (FireworkMeta) stack.getItemMeta();
|
||||
final FireworkEffect effect = builder.build();
|
||||
final FireworkMeta fmeta = (FireworkMeta) stack.getItemMeta();
|
||||
fmeta.addEffect(effect);
|
||||
if (fmeta.getEffects().size() > 1 && !hasMetaPermission(sender, "firework-multiple", true, true, ess)) {
|
||||
throw new Exception(tl("multipleCharges"));
|
||||
@@ -297,9 +322,9 @@ public class MetaItemStack {
|
||||
builder = FireworkEffect.builder();
|
||||
}
|
||||
|
||||
List<Color> primaryColors = new ArrayList<Color>();
|
||||
String[] colors = split[1].split(",");
|
||||
for (String color : colors) {
|
||||
final List<Color> primaryColors = new ArrayList<>();
|
||||
final String[] colors = split[1].split(",");
|
||||
for (final String color : colors) {
|
||||
if (colorMap.containsKey(color.toUpperCase())) {
|
||||
validFirework = true;
|
||||
primaryColors.add(colorMap.get(color.toUpperCase()).getFireworkColor());
|
||||
@@ -310,7 +335,7 @@ public class MetaItemStack {
|
||||
builder.withColor(primaryColors);
|
||||
} else if (split[0].equalsIgnoreCase("shape") || split[0].equalsIgnoreCase("type") || (allowShortName && (split[0].equalsIgnoreCase("s") || split[0].equalsIgnoreCase("t")))) {
|
||||
FireworkEffect.Type finalEffect = null;
|
||||
split[1] = (split[1].equalsIgnoreCase("large") ? "BALL_LARGE" : split[1]);
|
||||
split[1] = split[1].equalsIgnoreCase("large") ? "BALL_LARGE" : split[1];
|
||||
if (fireworkShape.containsKey(split[1].toUpperCase())) {
|
||||
finalEffect = fireworkShape.get(split[1].toUpperCase());
|
||||
} else {
|
||||
@@ -320,9 +345,9 @@ public class MetaItemStack {
|
||||
builder.with(finalEffect);
|
||||
}
|
||||
} else if (split[0].equalsIgnoreCase("fade") || (allowShortName && split[0].equalsIgnoreCase("f"))) {
|
||||
List<Color> fadeColors = new ArrayList<Color>();
|
||||
String[] colors = split[1].split(",");
|
||||
for (String color : colors) {
|
||||
final List<Color> fadeColors = new ArrayList<>();
|
||||
final String[] colors = split[1].split(",");
|
||||
for (final String color : colors) {
|
||||
if (colorMap.containsKey(color.toUpperCase())) {
|
||||
fadeColors.add(colorMap.get(color.toUpperCase()).getFireworkColor());
|
||||
} else {
|
||||
@@ -333,8 +358,8 @@ public class MetaItemStack {
|
||||
builder.withFade(fadeColors);
|
||||
}
|
||||
} else if (split[0].equalsIgnoreCase("effect") || (allowShortName && split[0].equalsIgnoreCase("e"))) {
|
||||
String[] effects = split[1].split(",");
|
||||
for (String effect : effects) {
|
||||
final String[] effects = split[1].split(",");
|
||||
for (final String effect : effects) {
|
||||
if (effect.equalsIgnoreCase("twinkle")) {
|
||||
builder.flicker(true);
|
||||
} else if (effect.equalsIgnoreCase("trail")) {
|
||||
@@ -376,6 +401,13 @@ public class MetaItemStack {
|
||||
} else {
|
||||
throw new Exception(tl("invalidPotionMeta", split[1]));
|
||||
}
|
||||
} else if (split[0].equalsIgnoreCase("amplifier") || (allowShortName && split[0].equalsIgnoreCase("a"))) {
|
||||
if (NumberUtil.isInt(split[1])) {
|
||||
validPotionPower = true;
|
||||
power = Integer.parseInt(split[1]);
|
||||
} else {
|
||||
throw new Exception(tl("invalidPotionMeta", split[1]));
|
||||
}
|
||||
} else if (split[0].equalsIgnoreCase("duration") || (allowShortName && split[0].equalsIgnoreCase("d"))) {
|
||||
if (NumberUtil.isInt(split[1])) {
|
||||
validPotionDuration = true;
|
||||
@@ -384,11 +416,11 @@ public class MetaItemStack {
|
||||
throw new Exception(tl("invalidPotionMeta", split[1]));
|
||||
}
|
||||
} else if (split[0].equalsIgnoreCase("splash") || (allowShortName && split[0].equalsIgnoreCase("s"))) {
|
||||
isSplashPotion = Boolean.valueOf(split[1]);
|
||||
isSplashPotion = Boolean.parseBoolean(split[1]);
|
||||
}
|
||||
|
||||
if (isValidPotion()) {
|
||||
PotionMeta pmeta = (PotionMeta) stack.getItemMeta();
|
||||
final PotionMeta pmeta = (PotionMeta) stack.getItemMeta();
|
||||
pEffect = pEffectType.createEffect(duration, power);
|
||||
if (pmeta.getCustomEffects().size() > 1 && !hasMetaPermission(sender, "potions.multiple", true, false, ess)) {
|
||||
throw new Exception(tl("multiplePotionEffects"));
|
||||
@@ -402,7 +434,7 @@ public class MetaItemStack {
|
||||
stack.setType(Material.POTION);
|
||||
}
|
||||
} else {
|
||||
Potion potion = Potion.fromItemStack(stack);
|
||||
final Potion potion = Potion.fromItemStack(stack);
|
||||
potion.setSplash(isSplashPotion);
|
||||
potion.apply(stack);
|
||||
}
|
||||
@@ -421,7 +453,7 @@ public class MetaItemStack {
|
||||
if (split.length > 1) {
|
||||
try {
|
||||
level = Integer.parseInt(split[1]);
|
||||
} catch (NumberFormatException ex) {
|
||||
} catch (final NumberFormatException ex) {
|
||||
level = -1;
|
||||
}
|
||||
}
|
||||
@@ -438,15 +470,14 @@ public class MetaItemStack {
|
||||
}
|
||||
try {
|
||||
if (stack.getType().equals(Material.ENCHANTED_BOOK)) {
|
||||
EnchantmentStorageMeta meta = (EnchantmentStorageMeta) stack.getItemMeta();
|
||||
final EnchantmentStorageMeta meta = (EnchantmentStorageMeta) stack.getItemMeta();
|
||||
if (level == 0) {
|
||||
meta.removeStoredEnchant(enchantment);
|
||||
} else {
|
||||
meta.addStoredEnchant(enchantment, level, allowUnsafe);
|
||||
}
|
||||
stack.setItemMeta(meta);
|
||||
} else // all other material types besides ENCHANTED_BOOK
|
||||
{
|
||||
} else { // all other material types besides ENCHANTED_BOOK
|
||||
if (level == 0) {
|
||||
stack.removeEnchantment(enchantment);
|
||||
} else {
|
||||
@@ -457,7 +488,7 @@ public class MetaItemStack {
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
} catch (final Exception ex) {
|
||||
throw new Exception("Enchantment " + enchantment.getName() + ": " + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
@@ -487,16 +518,17 @@ public class MetaItemStack {
|
||||
PatternType patternType = null;
|
||||
try {
|
||||
patternType = PatternType.valueOf(split[0]);
|
||||
} catch (Exception ignored ) {}
|
||||
} catch (final Exception ignored) {
|
||||
}
|
||||
|
||||
final BannerMeta meta = (BannerMeta) stack.getItemMeta();
|
||||
if (split[0].equalsIgnoreCase("basecolor")) {
|
||||
Color color = Color.fromRGB(Integer.valueOf(split[1]));
|
||||
final Color color = Color.fromRGB(Integer.parseInt(split[1]));
|
||||
meta.setBaseColor(DyeColor.getByColor(color));
|
||||
} else if (patternType != null) {
|
||||
PatternType type = PatternType.valueOf(split[0]);
|
||||
DyeColor color = DyeColor.getByColor(Color.fromRGB(Integer.valueOf(split[1])));
|
||||
org.bukkit.block.banner.Pattern pattern = new org.bukkit.block.banner.Pattern(color, type);
|
||||
final PatternType type = PatternType.valueOf(split[0]);
|
||||
final DyeColor color = DyeColor.getByColor(Color.fromRGB(Integer.parseInt(split[1])));
|
||||
final org.bukkit.block.banner.Pattern pattern = new org.bukkit.block.banner.Pattern(color, type);
|
||||
meta.addPattern(pattern);
|
||||
}
|
||||
|
||||
@@ -511,18 +543,19 @@ public class MetaItemStack {
|
||||
PatternType patternType = null;
|
||||
try {
|
||||
patternType = PatternType.valueOf(split[0]);
|
||||
} catch (Exception ignored ) {}
|
||||
} catch (final Exception ignored) {
|
||||
}
|
||||
|
||||
// Hacky fix for accessing Shield meta - https://github.com/drtshock/Essentials/pull/745#issuecomment-234843795
|
||||
BlockStateMeta meta = (BlockStateMeta) stack.getItemMeta();
|
||||
Banner banner = (Banner) meta.getBlockState();
|
||||
final BlockStateMeta meta = (BlockStateMeta) stack.getItemMeta();
|
||||
final Banner banner = (Banner) meta.getBlockState();
|
||||
if (split[0].equalsIgnoreCase("basecolor")) {
|
||||
Color color = Color.fromRGB(Integer.valueOf(split[1]));
|
||||
final Color color = Color.fromRGB(Integer.parseInt(split[1]));
|
||||
banner.setBaseColor(DyeColor.getByColor(color));
|
||||
} else if (patternType != null) {
|
||||
PatternType type = PatternType.valueOf(split[0]);
|
||||
DyeColor color = DyeColor.getByColor(Color.fromRGB(Integer.valueOf(split[1])));
|
||||
org.bukkit.block.banner.Pattern pattern = new org.bukkit.block.banner.Pattern(color, type);
|
||||
final PatternType type = PatternType.valueOf(split[0]);
|
||||
final DyeColor color = DyeColor.getByColor(Color.fromRGB(Integer.parseInt(split[1])));
|
||||
final org.bukkit.block.banner.Pattern pattern = new org.bukkit.block.banner.Pattern(color, type);
|
||||
banner.addPattern(pattern);
|
||||
}
|
||||
banner.update();
|
||||
@@ -549,18 +582,14 @@ public class MetaItemStack {
|
||||
}
|
||||
}
|
||||
|
||||
private static int bukkitUnbreakableSupport = -1;
|
||||
private static Method spigotMethod;
|
||||
private static Method setUnbreakableMethod;
|
||||
|
||||
private void setUnbreakable(ItemStack is, boolean unbreakable) {
|
||||
ItemMeta meta = is.getItemMeta();
|
||||
private void setUnbreakable(final ItemStack is, final boolean unbreakable) {
|
||||
final ItemMeta meta = is.getItemMeta();
|
||||
try {
|
||||
if (bukkitUnbreakableSupport == -1) {
|
||||
try {
|
||||
ItemMeta.class.getDeclaredMethod("setUnbreakable", boolean.class);
|
||||
bukkitUnbreakableSupport = 1;
|
||||
} catch (NoSuchMethodException | SecurityException ex) {
|
||||
} catch (final NoSuchMethodException | SecurityException ex) {
|
||||
bukkitUnbreakableSupport = 0;
|
||||
}
|
||||
}
|
||||
@@ -572,7 +601,7 @@ public class MetaItemStack {
|
||||
spigotMethod = meta.getClass().getDeclaredMethod("spigot");
|
||||
spigotMethod.setAccessible(true);
|
||||
}
|
||||
Object itemStackSpigot = spigotMethod.invoke(meta);
|
||||
final Object itemStackSpigot = spigotMethod.invoke(meta);
|
||||
if (setUnbreakableMethod == null) {
|
||||
setUnbreakableMethod = itemStackSpigot.getClass().getDeclaredMethod("setUnbreakable", Boolean.TYPE);
|
||||
setUnbreakableMethod.setAccessible(true);
|
||||
@@ -580,7 +609,7 @@ public class MetaItemStack {
|
||||
setUnbreakableMethod.invoke(itemStackSpigot, unbreakable);
|
||||
}
|
||||
is.setItemMeta(meta);
|
||||
} catch (Throwable t) {
|
||||
} catch (final Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,15 +4,19 @@ import com.earth2me.essentials.utils.EnumUtil;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
// Suffixes can be appended on the end of a mob name to make it plural
|
||||
// Entities without a suffix, will default to 's'
|
||||
public enum Mob {
|
||||
@@ -23,7 +27,8 @@ public enum Mob {
|
||||
GIANT("Giant", Enemies.ENEMY, EntityType.GIANT),
|
||||
HORSE("Horse", Enemies.FRIENDLY, EntityType.HORSE),
|
||||
PIG("Pig", Enemies.FRIENDLY, EntityType.PIG),
|
||||
PIGZOMB("PigZombie", Enemies.NEUTRAL, EntityType.PIG_ZOMBIE),
|
||||
PIGZOMB("PigZombie", Enemies.NEUTRAL, MobCompat.ZOMBIFIED_PIGLIN),
|
||||
ZOMBIFIED_PIGLIN("ZombifiedPiglin", Enemies.NEUTRAL, MobCompat.ZOMBIFIED_PIGLIN),
|
||||
SHEEP("Sheep", Enemies.FRIENDLY, "", EntityType.SHEEP),
|
||||
SKELETON("Skeleton", Enemies.ENEMY, EntityType.SKELETON),
|
||||
SLIME("Slime", Enemies.ENEMY, EntityType.SLIME),
|
||||
@@ -89,46 +94,22 @@ public enum Mob {
|
||||
PILLAGER("Pillager", Enemies.ENEMY, "PILLAGER"),
|
||||
RAVAGER("Ravager", Enemies.ENEMY, "RAVAGER"),
|
||||
TRADER_LLAMA("TraderLlama", Enemies.FRIENDLY, "TRADER_LLAMA"),
|
||||
WANDERING_TRADER("WanderingTrader", Enemies.FRIENDLY, "WANDERING_TRADER")
|
||||
WANDERING_TRADER("WanderingTrader", Enemies.FRIENDLY, "WANDERING_TRADER"),
|
||||
BEE("Bee", Enemies.NEUTRAL, "BEE"),
|
||||
STRAY("Stray", Enemies.ENEMY, "STRAY"),
|
||||
HOGLIN("Hoglin", Enemies.ADULT_ENEMY, "HOGLIN"),
|
||||
PIGLIN("Piglin", Enemies.ADULT_ENEMY, "PIGLIN"),
|
||||
STRIDER("Strider", Enemies.FRIENDLY, "STRIDER"),
|
||||
ZOGLIN("Zoglin", Enemies.ENEMY, "ZOGLIN"),
|
||||
PIGLIN_BRUTE("PiglinBrute", Enemies.ADULT_ENEMY, "PIGLIN_BRUTE"),
|
||||
;
|
||||
|
||||
public static final Logger logger = Logger.getLogger("Essentials");
|
||||
|
||||
Mob(String n, Enemies en, String s, EntityType type) {
|
||||
this.suffix = s;
|
||||
this.name = n;
|
||||
this.type = en;
|
||||
this.bukkitType = type;
|
||||
}
|
||||
|
||||
Mob(String n, Enemies en, EntityType type) {
|
||||
this.name = n;
|
||||
this.type = en;
|
||||
this.bukkitType = type;
|
||||
}
|
||||
|
||||
Mob(String n, Enemies en, String s, String typeName) {
|
||||
this.suffix = s;
|
||||
this.name = n;
|
||||
this.type = en;
|
||||
bukkitType = EnumUtil.getEntityType(typeName);
|
||||
}
|
||||
|
||||
Mob(String n, Enemies en, String typeName) {
|
||||
this.name = n;
|
||||
this.type = en;
|
||||
bukkitType = EnumUtil.getEntityType(typeName);
|
||||
}
|
||||
|
||||
public String suffix = "s";
|
||||
final public String name;
|
||||
final public Enemies type;
|
||||
final private EntityType bukkitType;
|
||||
private static final Map<String, Mob> hashMap = new HashMap<>();
|
||||
private static final Map<EntityType, Mob> bukkitMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (Mob mob : Mob.values()) {
|
||||
for (final Mob mob : Mob.values()) {
|
||||
hashMap.put(mob.name.toLowerCase(Locale.ENGLISH), mob);
|
||||
if (mob.bukkitType != null) {
|
||||
bukkitMap.put(mob.bukkitType, mob);
|
||||
@@ -136,10 +117,49 @@ public enum Mob {
|
||||
}
|
||||
}
|
||||
|
||||
final public String name;
|
||||
final public Enemies type;
|
||||
final private EntityType bukkitType;
|
||||
public String suffix = "s";
|
||||
|
||||
Mob(final String n, final Enemies en, final String s, final EntityType type) {
|
||||
this.suffix = s;
|
||||
this.name = n;
|
||||
this.type = en;
|
||||
this.bukkitType = type;
|
||||
}
|
||||
|
||||
Mob(final String n, final Enemies en, final EntityType type) {
|
||||
this.name = n;
|
||||
this.type = en;
|
||||
this.bukkitType = type;
|
||||
}
|
||||
|
||||
Mob(final String n, final Enemies en, final String s, final String typeName) {
|
||||
this.suffix = s;
|
||||
this.name = n;
|
||||
this.type = en;
|
||||
bukkitType = EnumUtil.getEntityType(typeName);
|
||||
}
|
||||
|
||||
Mob(final String n, final Enemies en, final String typeName) {
|
||||
this.name = n;
|
||||
this.type = en;
|
||||
bukkitType = EnumUtil.getEntityType(typeName);
|
||||
}
|
||||
|
||||
public static Set<String> getMobList() {
|
||||
return Collections.unmodifiableSet(hashMap.keySet());
|
||||
}
|
||||
|
||||
public static Mob fromName(final String name) {
|
||||
return hashMap.get(name.toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
|
||||
public static Mob fromBukkitType(final EntityType type) {
|
||||
return bukkitMap.get(type);
|
||||
}
|
||||
|
||||
public Entity spawn(final World world, final Server server, final Location loc) throws MobException {
|
||||
final Entity entity = world.spawn(loc, this.bukkitType.getEntityClass());
|
||||
if (entity == null) {
|
||||
@@ -149,31 +169,22 @@ public enum Mob {
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
||||
public enum Enemies {
|
||||
FRIENDLY("friendly"),
|
||||
NEUTRAL("neutral"),
|
||||
ENEMY("enemy");
|
||||
|
||||
Enemies(final String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
final protected String type;
|
||||
}
|
||||
|
||||
public EntityType getType() {
|
||||
return bukkitType;
|
||||
}
|
||||
|
||||
public static Mob fromName(final String name) {
|
||||
return hashMap.get(name.toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
public enum Enemies {
|
||||
FRIENDLY("friendly"),
|
||||
NEUTRAL("neutral"),
|
||||
ENEMY("enemy"),
|
||||
ADULT_ENEMY("adult_enemy");
|
||||
|
||||
public static Mob fromBukkitType(final EntityType type) {
|
||||
return bukkitMap.get(type);
|
||||
}
|
||||
final protected String type;
|
||||
|
||||
Enemies(final String type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MobException extends Exception {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -1,18 +1,28 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.utils.EnumUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import net.ess3.nms.refl.ReflUtil;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Fox;
|
||||
import org.bukkit.entity.Llama;
|
||||
import org.bukkit.entity.MushroomCow;
|
||||
import org.bukkit.entity.Ocelot;
|
||||
import org.bukkit.entity.Panda;
|
||||
import org.bukkit.entity.Parrot;
|
||||
import org.bukkit.entity.TropicalFish;
|
||||
import org.bukkit.entity.Villager;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static com.earth2me.essentials.utils.EnumUtil.getEntityType;
|
||||
|
||||
public class MobCompat {
|
||||
public final class MobCompat {
|
||||
|
||||
// Constants for mob interfaces added in later versions
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static final Class RAIDER = ReflUtil.getClassCached("org.bukkit.entity.Raider");
|
||||
|
||||
// Constants for mobs added in later versions
|
||||
public static final EntityType LLAMA = getEntityType("LLAMA");
|
||||
@@ -20,9 +30,127 @@ public class MobCompat {
|
||||
public static final EntityType TROPICAL_FISH = getEntityType("TROPICAL_FISH");
|
||||
public static final EntityType PANDA = getEntityType("PANDA");
|
||||
public static final EntityType TRADER_LLAMA = getEntityType("TRADER_LLAMA");
|
||||
public static final EntityType SHULKER = getEntityType("SHULKER");
|
||||
public static final EntityType STRAY = getEntityType("STRAY");
|
||||
public static final EntityType FOX = getEntityType("FOX");
|
||||
public static final EntityType PHANTOM = getEntityType("PHANTOM");
|
||||
|
||||
// Constants for mobs that have changed since earlier versions
|
||||
public static final EntityType CAT = getEntityType("CAT", "OCELOT");
|
||||
public static final EntityType ZOMBIFIED_PIGLIN = getEntityType("ZOMBIFIED_PIGLIN", "PIG_ZOMBIE");
|
||||
|
||||
private MobCompat() {
|
||||
}
|
||||
|
||||
// Older cats are Ocelots, whereas 1.14+ cats are Cats
|
||||
public static void setCatType(final Entity entity, final CatType type) {
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_14_R01)) {
|
||||
((Ocelot) entity).setCatType(Ocelot.Type.valueOf(type.ocelotTypeName));
|
||||
} else {
|
||||
final Class cat = ReflUtil.getClassCached("org.bukkit.entity.Cat");
|
||||
final Class catType = ReflUtil.getClassCached("org.bukkit.entity.Cat$Type");
|
||||
final Method setCatType = ReflUtil.getMethodCached(cat, "setCatType", catType);
|
||||
try {
|
||||
setCatType.invoke(entity, EnumUtil.valueOf(catType, type.catTypeName));
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Older villagers have professions and careers, 1.14+ villagers only have professions
|
||||
public static void setVillagerProfession(final Entity entity, final VillagerProfession profession) {
|
||||
if (!(entity instanceof Villager)) {
|
||||
return;
|
||||
}
|
||||
final Villager villager = (Villager) entity;
|
||||
villager.setProfession(profession.asEnum());
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_14_R01)) {
|
||||
final Class villagerCareer = ReflUtil.getClassCached("org.bukkit.entity.Villager$Career");
|
||||
final Method setCareer = ReflUtil.getMethodCached(Villager.class, "setCareer", villagerCareer);
|
||||
try {
|
||||
setCareer.invoke(entity, EnumUtil.valueOf(villagerCareer, profession.oldCareer));
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only 1.14+ villagers have biome variants
|
||||
public static void setVillagerType(final Entity entity, final String type) {
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_14_R01)) {
|
||||
return;
|
||||
}
|
||||
if (entity instanceof Villager) {
|
||||
((Villager) entity).setVillagerType(Villager.Type.valueOf(type));
|
||||
}
|
||||
}
|
||||
|
||||
// Llamas only exist in 1.11+
|
||||
public static void setLlamaColor(final Entity entity, final String color) {
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_11_R01)) {
|
||||
return;
|
||||
}
|
||||
if (entity instanceof Llama) {
|
||||
((Llama) entity).setColor(Llama.Color.valueOf(color));
|
||||
}
|
||||
}
|
||||
|
||||
// Parrots only exist in 1.12+
|
||||
public static void setParrotVariant(final Entity entity, final String variant) {
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_12_0_R01)) {
|
||||
return;
|
||||
}
|
||||
if (entity instanceof Parrot) {
|
||||
((Parrot) entity).setVariant(Parrot.Variant.valueOf(variant));
|
||||
}
|
||||
}
|
||||
|
||||
// Tropical fish only exist in 1.13+
|
||||
public static void setTropicalFishPattern(final Entity entity, final String pattern) {
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_12_0_R01)) {
|
||||
return;
|
||||
}
|
||||
if (entity instanceof TropicalFish) {
|
||||
((TropicalFish) entity).setPattern(TropicalFish.Pattern.valueOf(pattern));
|
||||
}
|
||||
}
|
||||
|
||||
// Mushroom cow variant API only exists in 1.14+
|
||||
public static void setMooshroomVariant(final Entity entity, final String variant) {
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_14_R01)) {
|
||||
return;
|
||||
}
|
||||
if (entity instanceof MushroomCow) {
|
||||
((MushroomCow) entity).setVariant(MushroomCow.Variant.valueOf(variant));
|
||||
}
|
||||
}
|
||||
|
||||
// Pandas only exists in 1.14+
|
||||
public static void setPandaGene(final Entity entity, final String gene, final boolean mainGene) {
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_14_R01)) {
|
||||
return;
|
||||
}
|
||||
if (entity instanceof Panda) {
|
||||
final Panda panda = (Panda) entity;
|
||||
final Panda.Gene pandaGene = Panda.Gene.valueOf(gene);
|
||||
if (mainGene) {
|
||||
panda.setMainGene(pandaGene);
|
||||
} else {
|
||||
panda.setHiddenGene(pandaGene);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Foxes only exist in 1.14+
|
||||
public static void setFoxType(final Entity entity, final String type) {
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_14_R01)) {
|
||||
return;
|
||||
}
|
||||
if (entity instanceof Fox) {
|
||||
((Fox) entity).setFoxType(Fox.Type.valueOf(type));
|
||||
}
|
||||
}
|
||||
|
||||
public enum CatType {
|
||||
// These are (loosely) Mojang names for the cats
|
||||
@@ -64,12 +192,12 @@ public class MobCompat {
|
||||
NITWIT("NITWIT", "NITWIT"),
|
||||
SHEPHERD("FARMER", "SHEPHERD"),
|
||||
TOOLSMITH("BLACKSMITH", "TOOL_SMITH", "TOOLSMITH"),
|
||||
WEAPONSMITH("BLACKSMITH", "WEAPON_SMITH", "WEAPONSMITH")
|
||||
WEAPONSMITH("BLACKSMITH", "WEAPON_SMITH", "WEAPONSMITH"),
|
||||
;
|
||||
|
||||
private String oldProfession;
|
||||
private String oldCareer;
|
||||
private String newProfession;
|
||||
private final String oldProfession;
|
||||
private final String oldCareer;
|
||||
private final String newProfession;
|
||||
|
||||
VillagerProfession(final String oldProfession, final String career) {
|
||||
this.oldProfession = oldProfession;
|
||||
@@ -88,137 +216,4 @@ public class MobCompat {
|
||||
}
|
||||
}
|
||||
|
||||
// Older cats are Ocelots, whereas 1.14+ cats are Cats
|
||||
private static Class catClass = ReflUtil.getClassCached("org.bukkit.entity.Cat");
|
||||
private static Class catTypeClass = ReflUtil.getClassCached("org.bukkit.entity.Cat.Type");
|
||||
private static Method catSetTypeMethod = (catClass == null || catTypeClass == null) ? null : ReflUtil.getMethodCached(catClass, "setCatType", catTypeClass);
|
||||
|
||||
private static boolean isNewCat() {
|
||||
return (catClass != null && catTypeClass != null && catSetTypeMethod != null);
|
||||
}
|
||||
|
||||
public static void setCatType(final Entity entity, final CatType type) {
|
||||
if (isNewCat()) {
|
||||
try {
|
||||
catSetTypeMethod.invoke(entity, EnumUtil.valueOf(catTypeClass, type.catTypeName));
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
((Ocelot) entity).setCatType(Ocelot.Type.valueOf(type.ocelotTypeName));
|
||||
}
|
||||
}
|
||||
|
||||
// Older villagers have professions and careers, 1.14+ villagers only have professions
|
||||
private static Class villagerCareerClass = ReflUtil.getClassCached("org.bukkit.entity.Villager.Career");
|
||||
private static Method villagerSetCareerMethod = (villagerCareerClass == null) ? null : ReflUtil.getMethodCached(Villager.class, "setCareer", villagerCareerClass);
|
||||
|
||||
private static boolean isCareerVillager() {
|
||||
return (villagerCareerClass != null && villagerSetCareerMethod != null);
|
||||
}
|
||||
|
||||
public static void setVillagerProfession(final Entity entity, final VillagerProfession profession) {
|
||||
if (!isCareerVillager()) {
|
||||
((Villager) entity).setProfession(profession.asEnum());
|
||||
} else {
|
||||
((Villager) entity).setProfession(profession.asEnum());
|
||||
try {
|
||||
villagerSetCareerMethod.invoke(entity, EnumUtil.valueOf(villagerCareerClass, profession.oldCareer));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only 1.14+ villagers have biome variants
|
||||
public static void setVillagerType(final Entity entity, final String type) {
|
||||
Class typeEnum = ReflUtil.getClassCached("org.bukkit.entity.Villager.Type");
|
||||
if (typeEnum == null) return;
|
||||
|
||||
Method villagerSetTypeMethod = ReflUtil.getMethodCached(Villager.class, "setVillagerType", typeEnum);
|
||||
try {
|
||||
villagerSetTypeMethod.invoke(entity, EnumUtil.valueOf(typeEnum, type));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Llamas only exist in 1.11+
|
||||
public static void setLlamaColor(final Entity entity, final String color) {
|
||||
Class llamaClass = ReflUtil.getClassCached("org.bukkit.entity.Llama");
|
||||
if (llamaClass == null) return;
|
||||
|
||||
Class colorEnum = ReflUtil.getClassCached("org.bukkit.entity.Llama.Color");
|
||||
Method setVariantMethod = ReflUtil.getMethodCached(llamaClass, "setColor");
|
||||
|
||||
try {
|
||||
setVariantMethod.invoke(entity, EnumUtil.valueOf(colorEnum, color));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Parrots only exist in 1.12+
|
||||
public static void setParrotVariant(final Entity entity, final String variant) {
|
||||
Class parrotClass = ReflUtil.getClassCached("org.bukkit.entity.Parrot");
|
||||
if (parrotClass == null) return;
|
||||
|
||||
Class variantEnum = ReflUtil.getClassCached("org.bukkit.entity.Parrot.Variant");
|
||||
Method setVariantMethod = ReflUtil.getMethodCached(parrotClass, "setVariant");
|
||||
try {
|
||||
setVariantMethod.invoke(entity, EnumUtil.valueOf(variantEnum, variant));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Tropical fish only exist in 1.13+
|
||||
public static void setTropicalFishPattern(final Entity entity, final String pattern) {
|
||||
Class tropicalFishClass = ReflUtil.getClassCached("org.bukkit.entity.TropicalFish");
|
||||
if (tropicalFishClass == null) return;
|
||||
|
||||
Class patternEnum = ReflUtil.getClassCached("org.bukkit.entity.TropicalFish.Pattern");
|
||||
Method setPatternMethod = ReflUtil.getMethodCached(tropicalFishClass, "setPattern");
|
||||
try {
|
||||
setPatternMethod.invoke(entity, EnumUtil.valueOf(patternEnum, pattern));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Mushroom cow variant API only exists in 1.14+
|
||||
public static void setMooshroomVariant(final Entity entity, final String variant) {
|
||||
Class mushroomCowClass = ReflUtil.getClassCached("org.bukkit.entity.MushroomCow");
|
||||
Class variantEnum = ReflUtil.getClassCached("org.bukkit.entity.MushroomCow.Variant");
|
||||
if (mushroomCowClass == null || variantEnum == null) return;
|
||||
|
||||
Method setVariantMethod = ReflUtil.getMethodCached(mushroomCowClass, "setVariant");
|
||||
try {
|
||||
setVariantMethod.invoke(entity, EnumUtil.valueOf(variantEnum, variant));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Pandas only exists in 1.14+
|
||||
public static void setPandaGene(final Entity entity, final String gene, final boolean mainGene) {
|
||||
Class pandaClass = ReflUtil.getClassCached("org.bukkit.entity.Panda");
|
||||
if (pandaClass == null) return;
|
||||
|
||||
Class geneEnum = ReflUtil.getClassCached("org.bukkit.entity.Panda.Gene");
|
||||
Method setGeneMethod;
|
||||
|
||||
if (mainGene) {
|
||||
setGeneMethod = ReflUtil.getMethodCached(pandaClass, "setMainGene");
|
||||
} else {
|
||||
setGeneMethod = ReflUtil.getMethodCached(pandaClass, "setHiddenGene");
|
||||
}
|
||||
|
||||
try {
|
||||
setGeneMethod.invoke(entity, EnumUtil.valueOf(geneEnum, gene));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,17 +5,38 @@ import com.earth2me.essentials.utils.EnumUtil;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.entity.Ageable;
|
||||
import org.bukkit.entity.Creeper;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.ExperienceOrb;
|
||||
import org.bukkit.entity.Horse;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Phantom;
|
||||
import org.bukkit.entity.Pig;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Raider;
|
||||
import org.bukkit.entity.Slime;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.entity.TropicalFish;
|
||||
import org.bukkit.entity.Wolf;
|
||||
import org.bukkit.entity.Zombie;
|
||||
import org.bukkit.inventory.EntityEquipment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.material.Colorable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Random;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public enum MobData {
|
||||
|
||||
BABY_AGEABLE("baby", Ageable.class, Data.BABY, true),
|
||||
@@ -32,7 +53,7 @@ public enum MobData {
|
||||
TAMED_TAMEABLE("tamed", Tameable.class, Data.TAMED, true),
|
||||
TAME_TAMEABLE("tame", Tameable.class, Data.TAMED, false),
|
||||
RANDOM_SHEEP("random", EntityType.SHEEP, Data.COLORABLE, true),
|
||||
COLORABLE_SHEEP("", StringUtil.joinList(DyeColor.values()).toLowerCase(Locale.ENGLISH), EntityType.SHEEP, Data.COLORABLE, true),
|
||||
COLORABLE_SHEEP("", Arrays.stream(DyeColor.values()).map(color -> color.name().toLowerCase(Locale.ENGLISH)).collect(Collectors.toList()), EntityType.SHEEP, Data.COLORABLE, true),
|
||||
POLKA_HORSE("polka", EntityType.HORSE, Horse.Style.BLACK_DOTS, true),
|
||||
SOOTY_HORSE("sooty", EntityType.HORSE, Horse.Style.BLACK_DOTS, false),
|
||||
BLAZE_HORSE("blaze", EntityType.HORSE, Horse.Style.WHITE, true),
|
||||
@@ -113,8 +134,8 @@ public enum MobData {
|
||||
SNOWY_VILLAGER("snowy", EntityType.VILLAGER, "villagertype:SNOWY", true),
|
||||
SWAMP_VILLAGER("swamp", EntityType.VILLAGER, "villagertype:SWAMP", true),
|
||||
TAIGA_VILLAGER("taiga", EntityType.VILLAGER, "villagertype:TAIGA", true),
|
||||
SIZE_SLIME("", "<1-100>", EntityType.SLIME.getEntityClass(), Data.SIZE, true),
|
||||
NUM_EXPERIENCE_ORB("", "<1-2000000000>", EntityType.EXPERIENCE_ORB, Data.EXP, true),
|
||||
SIZE_SLIME("", Collections.singletonList("<1-100>"), EntityType.SLIME.getEntityClass(), Data.SIZE, true),
|
||||
NUM_EXPERIENCE_ORB("", Collections.singletonList("<1-2000000000>"), EntityType.EXPERIENCE_ORB, Data.EXP, true),
|
||||
RED_PARROT("red", MobCompat.PARROT, "parrot:RED", true),
|
||||
GREEN_PARROT("green", MobCompat.PARROT, "parrot:GREEN", true),
|
||||
BLUE_PARROT("blue", MobCompat.PARROT, "parrot:BLUE", true),
|
||||
@@ -153,60 +174,49 @@ public enum MobData {
|
||||
CREAMY_TRADER_LLAMA("creamy", MobCompat.TRADER_LLAMA, "llama:CREAMY", true),
|
||||
WHITE_TRADER_LLAMA("white", MobCompat.TRADER_LLAMA, "llama:WHITE", true),
|
||||
BROWN_TRADER_LLAMA("brown", MobCompat.TRADER_LLAMA, "llama:BROWN", true),
|
||||
GRAY_TRADER_LLAMA("gray", MobCompat.TRADER_LLAMA, "llama:GRAY", true)
|
||||
GRAY_TRADER_LLAMA("gray", MobCompat.TRADER_LLAMA, "llama:GRAY", true),
|
||||
RANDOM_SHULKER("random", MobCompat.SHULKER, Data.COLORABLE, true),
|
||||
COLORABLE_SHULKER("", Arrays.stream(DyeColor.values()).map(color -> color.name().toLowerCase(Locale.ENGLISH)).collect(Collectors.toList()), MobCompat.SHULKER, Data.COLORABLE, true),
|
||||
RED_FOX("red", MobCompat.FOX, "fox:RED", true),
|
||||
SNOW_FOX("snow", MobCompat.FOX, "fox:SNOW", true),
|
||||
SIZE_PHANTOM("", Collections.singletonList("<1-100>"), MobCompat.PHANTOM, Data.SIZE, true),
|
||||
RAID_LEADER("leader", MobCompat.RAIDER, Data.RAID_LEADER, true),
|
||||
TROPICAL_FISH_BODY_COLOR("fish_body_color", Arrays.stream(DyeColor.values()).map(color -> color.name().toLowerCase(Locale.ENGLISH) + "body").collect(Collectors.toList()), MobCompat.TROPICAL_FISH, Data.FISH_BODY_COLOR, true),
|
||||
TROPICAL_FISH_PATTERN_COLOR("fish_pattern_color", Arrays.stream(DyeColor.values()).map(color -> color.name().toLowerCase(Locale.ENGLISH) + "pattern").collect(Collectors.toList()), MobCompat.TROPICAL_FISH, Data.FISH_PATTERN_COLOR, true),
|
||||
;
|
||||
|
||||
|
||||
public enum Data {
|
||||
ADULT,
|
||||
BABY,
|
||||
CHEST,
|
||||
ADULTZOMBIE,
|
||||
BABYZOMBIE,
|
||||
HORSESADDLE,
|
||||
PIGSADDLE,
|
||||
ELECTRIFIED,
|
||||
ANGRY,
|
||||
TAMED,
|
||||
COLORABLE,
|
||||
EXP,
|
||||
SIZE
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static final Logger logger = Logger.getLogger("Essentials");
|
||||
|
||||
MobData(String n, Object type, Object value, boolean isPublic) {
|
||||
this.nickname = n;
|
||||
this.matched = n;
|
||||
this.helpMessage = n;
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
this.isPublic = isPublic;
|
||||
}
|
||||
|
||||
MobData(String n, String h, Object type, Object value, boolean isPublic) {
|
||||
this.nickname = n;
|
||||
this.matched = n;
|
||||
this.helpMessage = h;
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
this.isPublic = isPublic;
|
||||
}
|
||||
|
||||
final private String nickname;
|
||||
final private String helpMessage;
|
||||
final private List<String> suggestions;
|
||||
final private Object type;
|
||||
final private Object value;
|
||||
final private boolean isPublic;
|
||||
private String matched;
|
||||
|
||||
public static LinkedHashMap<String, MobData> getPossibleData(final Entity spawned, boolean publicOnly) {
|
||||
LinkedHashMap<String, MobData> mobList = new LinkedHashMap<String, MobData>();
|
||||
for (MobData data : MobData.values()) {
|
||||
if (data.type == null || (publicOnly && !data.isPublic)) continue;
|
||||
|
||||
MobData(final String n, final Object type, final Object value, final boolean isPublic) {
|
||||
this.nickname = n;
|
||||
this.matched = n;
|
||||
this.suggestions = Collections.singletonList(n);
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
this.isPublic = isPublic;
|
||||
}
|
||||
|
||||
MobData(final String n, final List<String> s, final Object type, final Object value, final boolean isPublic) {
|
||||
this.nickname = n;
|
||||
this.matched = n;
|
||||
this.suggestions = s;
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
this.isPublic = isPublic;
|
||||
}
|
||||
|
||||
public static LinkedHashMap<String, MobData> getPossibleData(final Entity spawned, final boolean publicOnly) {
|
||||
final LinkedHashMap<String, MobData> mobList = new LinkedHashMap<>();
|
||||
for (final MobData data : MobData.values()) {
|
||||
if (data.type == null || (publicOnly && !data.isPublic)) {
|
||||
continue;
|
||||
}
|
||||
if (data.type instanceof EntityType && spawned.getType().equals(data.type)) {
|
||||
mobList.put(data.nickname.toLowerCase(Locale.ENGLISH), data);
|
||||
} else if (data.type instanceof Class && ((Class) data.type).isAssignableFrom(spawned.getClass())) {
|
||||
@@ -218,11 +228,11 @@ public enum MobData {
|
||||
}
|
||||
|
||||
public static List<String> getValidHelp(final Entity spawned) {
|
||||
List<String> output = new ArrayList<String>();
|
||||
LinkedHashMap<String, MobData> posData = getPossibleData(spawned, true);
|
||||
final List<String> output = new ArrayList<>();
|
||||
final LinkedHashMap<String, MobData> posData = getPossibleData(spawned, true);
|
||||
|
||||
for (MobData data : posData.values()) {
|
||||
output.add(data.helpMessage);
|
||||
for (final MobData data : posData.values()) {
|
||||
output.add(StringUtil.joinList(data.suggestions));
|
||||
}
|
||||
return output;
|
||||
}
|
||||
@@ -232,10 +242,12 @@ public enum MobData {
|
||||
return null;
|
||||
}
|
||||
|
||||
LinkedHashMap<String, MobData> posData = getPossibleData(spawned, false);
|
||||
for (String data : posData.keySet()) {
|
||||
if (name.contains(data)) {
|
||||
return posData.get(data);
|
||||
final LinkedHashMap<String, MobData> posData = getPossibleData(spawned, false);
|
||||
for (final MobData data : posData.values()) {
|
||||
for (final String suggestion : data.suggestions) {
|
||||
if (name.contains(suggestion)) {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -259,14 +271,14 @@ public enum MobData {
|
||||
} else if (this.value.equals(Data.ELECTRIFIED)) {
|
||||
((Creeper) spawned).setPowered(true);
|
||||
} else if (this.value.equals(Data.HORSESADDLE)) {
|
||||
final Horse horse = ((Horse) spawned);
|
||||
final Horse horse = (Horse) spawned;
|
||||
horse.setTamed(true);
|
||||
horse.setOwner(target);
|
||||
horse.getInventory().setSaddle(new ItemStack(Material.SADDLE, 1));
|
||||
} else if (this.value.equals(Data.PIGSADDLE)) {
|
||||
((Pig) spawned).setSaddle(true);
|
||||
} else if (this.value.equals(Data.TAMED)) {
|
||||
final Tameable tameable = ((Tameable) spawned);
|
||||
final Tameable tameable = (Tameable) spawned;
|
||||
tameable.setTamed(true);
|
||||
tameable.setOwner(target);
|
||||
} else if (this.value.equals(Data.COLORABLE)) {
|
||||
@@ -279,21 +291,26 @@ public enum MobData {
|
||||
((Colorable) spawned).setColor(DyeColor.valueOf(color));
|
||||
}
|
||||
this.matched = rawData;
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
throw new Exception(tl("sheepMalformedColor"), e);
|
||||
}
|
||||
} else if (this.value.equals(Data.EXP)) {
|
||||
try {
|
||||
((ExperienceOrb) spawned).setExperience(Integer.parseInt(rawData));
|
||||
this.matched = rawData;
|
||||
} catch (NumberFormatException e) {
|
||||
} catch (final NumberFormatException e) {
|
||||
throw new Exception(tl("invalidNumber"), e);
|
||||
}
|
||||
} else if (this.value.equals(Data.SIZE)) {
|
||||
try {
|
||||
((Slime) spawned).setSize(Integer.parseInt(rawData));
|
||||
final int size = Integer.parseInt(rawData);
|
||||
if (spawned instanceof Slime) {
|
||||
((Slime) spawned).setSize(size);
|
||||
} else if (spawned.getType() == MobCompat.PHANTOM) {
|
||||
((Phantom) spawned).setSize(size);
|
||||
}
|
||||
this.matched = rawData;
|
||||
} catch (NumberFormatException e) {
|
||||
} catch (final NumberFormatException e) {
|
||||
throw new Exception(tl("slimeMalformedSize"), e);
|
||||
}
|
||||
} else if (this.value instanceof Horse.Color) {
|
||||
@@ -313,6 +330,26 @@ public enum MobData {
|
||||
InventoryWorkaround.setItemInMainHand(invent, new ItemStack((Material) this.value, 1));
|
||||
InventoryWorkaround.setItemInMainHandDropChance(invent, 0.1f);
|
||||
}
|
||||
} else if (this.value.equals(Data.RAID_LEADER)) {
|
||||
((Raider) spawned).setPatrolLeader(true);
|
||||
} else if (this.value.equals(Data.FISH_BODY_COLOR)) {
|
||||
for (final String match : TROPICAL_FISH_BODY_COLOR.suggestions) {
|
||||
if (rawData.contains(match)) {
|
||||
this.matched = match;
|
||||
final String color = match.substring(0, match.indexOf("body")).toUpperCase(Locale.ENGLISH);
|
||||
((TropicalFish) spawned).setBodyColor(DyeColor.valueOf(color));
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (this.value.equals(Data.FISH_PATTERN_COLOR)) {
|
||||
for (final String match : TROPICAL_FISH_PATTERN_COLOR.suggestions) {
|
||||
if (rawData.contains(match)) {
|
||||
this.matched = match;
|
||||
final String color = match.substring(0, match.indexOf("pattern")).toUpperCase(Locale.ENGLISH);
|
||||
((TropicalFish) spawned).setPatternColor(DyeColor.valueOf(color));
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (this.value instanceof String) {
|
||||
final String[] split = ((String) this.value).split(":");
|
||||
switch (split[0]) {
|
||||
@@ -337,9 +374,31 @@ public enum MobData {
|
||||
case "villagertype":
|
||||
MobCompat.setVillagerType(spawned, split[1]);
|
||||
break;
|
||||
case "fox":
|
||||
MobCompat.setFoxType(spawned, split[1]);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
logger.warning("Unknown mob data type: " + this.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public enum Data {
|
||||
ADULT,
|
||||
BABY,
|
||||
CHEST,
|
||||
ADULTZOMBIE,
|
||||
BABYZOMBIE,
|
||||
HORSESADDLE,
|
||||
PIGSADDLE,
|
||||
ELECTRIFIED,
|
||||
ANGRY,
|
||||
TAMED,
|
||||
COLORABLE,
|
||||
EXP,
|
||||
SIZE,
|
||||
RAID_LEADER,
|
||||
FISH_BODY_COLOR,
|
||||
FISH_PATTERN_COLOR,
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@ import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
|
||||
public class PlayerExtension {
|
||||
protected Player base;
|
||||
|
||||
|
||||
@@ -1,20 +1,30 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.utils.FormatUtil;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public final class PlayerList {
|
||||
|
||||
private PlayerList() {
|
||||
}
|
||||
|
||||
public class PlayerList {
|
||||
// Cosmetic list formatting
|
||||
public static String listUsers(final IEssentials ess, final List<User> users, final String seperator) {
|
||||
final StringBuilder groupString = new StringBuilder();
|
||||
Collections.sort(users);
|
||||
boolean needComma = false;
|
||||
for (User user : users) {
|
||||
for (final User user : users) {
|
||||
if (needComma) {
|
||||
groupString.append(seperator);
|
||||
}
|
||||
@@ -27,6 +37,9 @@ public class PlayerList {
|
||||
}
|
||||
user.setDisplayNick();
|
||||
groupString.append(user.getDisplayName());
|
||||
if (ess.getSettings().realNamesOnList() && !ChatColor.stripColor(user.getDisplayName()).equals(user.getName())) {
|
||||
groupString.append(" (").append(user.getName()).append(")");
|
||||
}
|
||||
groupString.append("\u00a7f");
|
||||
}
|
||||
return groupString.toString();
|
||||
@@ -34,18 +47,18 @@ public class PlayerList {
|
||||
|
||||
// Produce a user summary: There are 5 out of maximum 10 players online.
|
||||
public static String listSummary(final IEssentials ess, final User user, final boolean showHidden) {
|
||||
Server server = ess.getServer();
|
||||
final Server server = ess.getServer();
|
||||
int playerHidden = 0;
|
||||
int hiddenCount = 0;
|
||||
for (User onlinePlayer : ess.getOnlineUsers()) {
|
||||
for (final User onlinePlayer : ess.getOnlineUsers()) {
|
||||
if (onlinePlayer.isHidden() || (user != null && !user.getBase().canSee(onlinePlayer.getBase()))) {
|
||||
playerHidden++;
|
||||
if (showHidden || user.getBase().canSee(onlinePlayer.getBase())) {
|
||||
if (showHidden || user != null && user.getBase().canSee(onlinePlayer.getBase())) {
|
||||
hiddenCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
String online;
|
||||
final String online;
|
||||
if (hiddenCount > 0) {
|
||||
online = tl("listAmountHidden", ess.getOnlinePlayers().size() - playerHidden, hiddenCount, server.getMaxPlayers());
|
||||
} else {
|
||||
@@ -55,19 +68,14 @@ public class PlayerList {
|
||||
}
|
||||
|
||||
// Build the basic player list, divided by groups.
|
||||
public static Map<String, List<User>> getPlayerLists(final IEssentials ess, final User sender, final boolean showHidden) {
|
||||
Server server = ess.getServer();
|
||||
final Map<String, List<User>> playerList = new HashMap<String, List<User>>();
|
||||
for (User onlineUser : ess.getOnlineUsers()) {
|
||||
public static Map<String, List<User>> getPlayerLists(final IEssentials ess, final IUser sender, final boolean showHidden) {
|
||||
final Map<String, List<User>> playerList = new HashMap<>();
|
||||
for (final User onlineUser : ess.getOnlineUsers()) {
|
||||
if ((sender == null && !showHidden && onlineUser.isHidden()) || (sender != null && !showHidden && !sender.getBase().canSee(onlineUser.getBase()))) {
|
||||
continue;
|
||||
}
|
||||
final String group = FormatUtil.stripFormat(FormatUtil.stripEssentialsFormat(onlineUser.getGroup().toLowerCase()));
|
||||
List<User> list = playerList.get(group);
|
||||
if (list == null) {
|
||||
list = new ArrayList<User>();
|
||||
playerList.put(group, list);
|
||||
}
|
||||
final List<User> list = playerList.computeIfAbsent(group, k -> new ArrayList<>());
|
||||
list.add(onlineUser);
|
||||
}
|
||||
return playerList;
|
||||
@@ -76,16 +84,16 @@ public class PlayerList {
|
||||
// Handle the merging of groups
|
||||
public static List<User> getMergedList(final IEssentials ess, final Map<String, List<User>> playerList, final String groupName) {
|
||||
final Set<String> configGroups = ess.getSettings().getListGroupConfig().keySet();
|
||||
final List<User> users = new ArrayList<User>();
|
||||
for (String configGroup : configGroups) {
|
||||
final List<User> users = new ArrayList<>();
|
||||
for (final String configGroup : configGroups) {
|
||||
if (configGroup.equalsIgnoreCase(groupName)) {
|
||||
String[] groupValues = ess.getSettings().getListGroupConfig().get(configGroup).toString().trim().split(" ");
|
||||
final String[] groupValues = ess.getSettings().getListGroupConfig().get(configGroup).toString().trim().split(" ");
|
||||
for (String groupValue : groupValues) {
|
||||
groupValue = groupValue.toLowerCase(Locale.ENGLISH);
|
||||
if (groupValue == null || groupValue.isEmpty()) {
|
||||
if (groupValue.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
List<User> u = playerList.get(groupValue.trim());
|
||||
final List<User> u = playerList.get(groupValue.trim());
|
||||
if (u == null || u.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
@@ -104,20 +112,17 @@ public class PlayerList {
|
||||
if (groupUsers != null && !groupUsers.isEmpty()) {
|
||||
users.addAll(groupUsers);
|
||||
}
|
||||
if (users == null || users.isEmpty()) {
|
||||
if (users.isEmpty()) {
|
||||
throw new Exception(tl("groupDoesNotExist"));
|
||||
}
|
||||
final StringBuilder displayGroupName = new StringBuilder();
|
||||
displayGroupName.append(Character.toTitleCase(groupName.charAt(0)));
|
||||
displayGroupName.append(groupName.substring(1));
|
||||
return outputFormat(displayGroupName.toString(), listUsers(ess, users, ", "));
|
||||
final String displayGroupName = Character.toTitleCase(groupName.charAt(0)) +
|
||||
groupName.substring(1);
|
||||
return outputFormat(displayGroupName, listUsers(ess, users, ", "));
|
||||
}
|
||||
|
||||
// Build the output string
|
||||
public static String outputFormat(final String group, final String message) {
|
||||
final StringBuilder outputString = new StringBuilder();
|
||||
outputString.append(tl("listGroupTag", FormatUtil.replaceFormat(group)));
|
||||
outputString.append(message);
|
||||
return outputString.toString();
|
||||
return tl("listGroupTag", FormatUtil.replaceFormat(group)) +
|
||||
message;
|
||||
}
|
||||
}
|
||||
@@ -4,11 +4,10 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
|
||||
public class PlayerTarget implements ITarget {
|
||||
private final String name;
|
||||
|
||||
public PlayerTarget(Player entity) {
|
||||
public PlayerTarget(final Player entity) {
|
||||
this.name = entity.getName();
|
||||
}
|
||||
|
||||
@@ -16,4 +15,4 @@ public class PlayerTarget implements ITarget {
|
||||
public Location getLocation() {
|
||||
return Bukkit.getServer().getPlayerExact(name).getLocation();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,8 +9,7 @@ import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
public class Potions {
|
||||
public final class Potions {
|
||||
private static final Map<String, PotionEffectType> POTIONS = new HashMap<>();
|
||||
private static final Map<String, PotionEffectType> ALIASPOTIONS = new HashMap<>();
|
||||
|
||||
@@ -124,10 +123,14 @@ public class Potions {
|
||||
|
||||
POTIONS.put("luck", PotionEffectType.LUCK);
|
||||
POTIONS.put("unluck", PotionEffectType.UNLUCK);
|
||||
} catch (Throwable ignored) {}
|
||||
} catch (final Throwable ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
public static PotionEffectType getByName(String name) {
|
||||
private Potions() {
|
||||
}
|
||||
|
||||
public static PotionEffectType getByName(final String name) {
|
||||
PotionEffectType peffect;
|
||||
if (NumberUtil.isInt(name)) {
|
||||
peffect = PotionEffectType.getById(Integer.parseInt(name));
|
||||
|
||||
@@ -0,0 +1,209 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.utils.LocationUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import net.ess3.api.InvalidWorldException;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
public class RandomTeleport implements IConf {
|
||||
private static final Random RANDOM = new Random();
|
||||
private static final int HIGHEST_BLOCK_Y_OFFSET = VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_15_R01) ? 1 : 0;
|
||||
private final IEssentials essentials;
|
||||
private final EssentialsConf config;
|
||||
private final ConcurrentLinkedQueue<Location> cachedLocations = new ConcurrentLinkedQueue<>();
|
||||
|
||||
public RandomTeleport(final IEssentials essentials) {
|
||||
this.essentials = essentials;
|
||||
final File file = new File(essentials.getDataFolder(), "tpr.yml");
|
||||
config = new EssentialsConf(file);
|
||||
config.setTemplateName("/tpr.yml");
|
||||
config.options().copyHeader(true);
|
||||
reloadConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadConfig() {
|
||||
config.load();
|
||||
cachedLocations.clear();
|
||||
}
|
||||
|
||||
public Location getCenter() {
|
||||
try {
|
||||
final Location center = config.getLocation("center", essentials.getServer());
|
||||
if (center != null) {
|
||||
return center;
|
||||
}
|
||||
} catch (final InvalidWorldException ignored) {
|
||||
}
|
||||
final Location center = essentials.getServer().getWorlds().get(0).getWorldBorder().getCenter();
|
||||
center.setY(center.getWorld().getHighestBlockYAt(center) + 1);
|
||||
setCenter(center);
|
||||
return center;
|
||||
}
|
||||
|
||||
public void setCenter(final Location center) {
|
||||
config.setProperty("center", center);
|
||||
config.save();
|
||||
}
|
||||
|
||||
public double getMinRange() {
|
||||
return config.getDouble("min-range", 0d);
|
||||
}
|
||||
|
||||
public void setMinRange(final double minRange) {
|
||||
config.setProperty("min-range", minRange);
|
||||
config.save();
|
||||
}
|
||||
|
||||
public double getMaxRange() {
|
||||
return config.getDouble("max-range", getCenter().getWorld().getWorldBorder().getSize() / 2);
|
||||
}
|
||||
|
||||
public void setMaxRange(final double maxRange) {
|
||||
config.setProperty("max-range", maxRange);
|
||||
config.save();
|
||||
}
|
||||
|
||||
public Set<Biome> getExcludedBiomes() {
|
||||
final List<String> biomeNames = config.getStringList("excluded-biomes");
|
||||
final Set<Biome> excludedBiomes = new HashSet<>();
|
||||
for (final String biomeName : biomeNames) {
|
||||
try {
|
||||
excludedBiomes.add(Biome.valueOf(biomeName.toUpperCase()));
|
||||
} catch (final IllegalArgumentException ignored) {
|
||||
}
|
||||
}
|
||||
return excludedBiomes;
|
||||
}
|
||||
|
||||
public int getFindAttempts() {
|
||||
return config.getInt("find-attempts", 10);
|
||||
}
|
||||
|
||||
public int getCacheThreshold() {
|
||||
return config.getInt("cache-threshold", 10);
|
||||
}
|
||||
|
||||
public boolean getPreCache() {
|
||||
return config.getBoolean("pre-cache", false);
|
||||
}
|
||||
|
||||
public Queue<Location> getCachedLocations() {
|
||||
return cachedLocations;
|
||||
}
|
||||
|
||||
// Get a random location; cached if possible. Otherwise on demand.
|
||||
public CompletableFuture<Location> getRandomLocation(final Location center, final double minRange, final double maxRange) {
|
||||
final int findAttempts = this.getFindAttempts();
|
||||
final Queue<Location> cachedLocations = this.getCachedLocations();
|
||||
// Try to build up the cache if it is below the threshold
|
||||
if (cachedLocations.size() < this.getCacheThreshold()) {
|
||||
cacheRandomLocations(center, minRange, maxRange);
|
||||
}
|
||||
final CompletableFuture<Location> future = new CompletableFuture<>();
|
||||
// Return a random location immediately if one is available, otherwise try to find one now
|
||||
if (cachedLocations.isEmpty()) {
|
||||
attemptRandomLocation(findAttempts, center, minRange, maxRange).thenAccept(future::complete);
|
||||
} else {
|
||||
future.complete(cachedLocations.poll());
|
||||
}
|
||||
return future;
|
||||
}
|
||||
|
||||
// Prompts caching random valid locations, up to a maximum number of attempts
|
||||
public void cacheRandomLocations(final Location center, final double minRange, final double maxRange) {
|
||||
essentials.getServer().getScheduler().scheduleSyncDelayedTask(essentials, () -> {
|
||||
for (int i = 0; i < this.getFindAttempts(); ++i) {
|
||||
calculateRandomLocation(center, minRange, maxRange).thenAccept(location -> {
|
||||
if (isValidRandomLocation(location)) {
|
||||
this.getCachedLocations().add(location);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Recursively attempt to find a random location. After a maximum number of attempts, the center is returned.
|
||||
private CompletableFuture<Location> attemptRandomLocation(final int attempts, final Location center, final double minRange, final double maxRange) {
|
||||
final CompletableFuture<Location> future = new CompletableFuture<>();
|
||||
if (attempts > 0) {
|
||||
calculateRandomLocation(center, minRange, maxRange).thenAccept(location -> {
|
||||
if (isValidRandomLocation(location)) {
|
||||
future.complete(location);
|
||||
} else {
|
||||
attemptRandomLocation(attempts - 1, center, minRange, maxRange).thenAccept(future::complete);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
future.complete(center);
|
||||
}
|
||||
return future;
|
||||
}
|
||||
|
||||
// Calculates a random location asynchronously.
|
||||
private CompletableFuture<Location> calculateRandomLocation(final Location center, final double minRange, final double maxRange) {
|
||||
final CompletableFuture<Location> future = new CompletableFuture<>();
|
||||
// Find an equally distributed offset by randomly rotating a point inside a rectangle about the origin
|
||||
final double rectX = RANDOM.nextDouble() * (maxRange - minRange) + minRange;
|
||||
final double rectZ = RANDOM.nextDouble() * (maxRange + minRange) - minRange;
|
||||
final double offsetX;
|
||||
final double offsetZ;
|
||||
final int transform = RANDOM.nextInt(4);
|
||||
if (transform == 0) {
|
||||
offsetX = rectX;
|
||||
offsetZ = rectZ;
|
||||
} else if (transform == 1) {
|
||||
offsetX = -rectZ;
|
||||
offsetZ = rectX;
|
||||
} else if (transform == 2) {
|
||||
offsetX = -rectX;
|
||||
offsetZ = -rectZ;
|
||||
} else {
|
||||
offsetX = rectZ;
|
||||
offsetZ = -rectX;
|
||||
}
|
||||
final Location location = new Location(
|
||||
center.getWorld(),
|
||||
center.getX() + offsetX,
|
||||
center.getWorld().getMaxHeight(),
|
||||
center.getZ() + offsetZ,
|
||||
360 * RANDOM.nextFloat() - 180,
|
||||
0
|
||||
);
|
||||
PaperLib.getChunkAtAsync(location).thenAccept(chunk -> {
|
||||
if (World.Environment.NETHER.equals(center.getWorld().getEnvironment())) {
|
||||
location.setY(getNetherYAt(location));
|
||||
} else {
|
||||
location.setY(center.getWorld().getHighestBlockYAt(location) + HIGHEST_BLOCK_Y_OFFSET);
|
||||
}
|
||||
future.complete(location);
|
||||
});
|
||||
return future;
|
||||
}
|
||||
|
||||
// Returns an appropriate elevation for a given location in the nether, or -1 if none is found
|
||||
private double getNetherYAt(final Location location) {
|
||||
for (int y = 32; y < location.getWorld().getMaxHeight() / 2; ++y) {
|
||||
if (!LocationUtil.isBlockUnsafe(location.getWorld(), location.getBlockX(), y, location.getBlockZ())) {
|
||||
return y;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private boolean isValidRandomLocation(final Location location) {
|
||||
return location.getBlockY() > 0 && !this.getExcludedBiomes().contains(location.getBlock().getBiome());
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -10,16 +10,25 @@ import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.entity.Ageable;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Horse;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.PigZombie;
|
||||
import org.bukkit.entity.Zombie;
|
||||
import org.bukkit.inventory.EntityEquipment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class SpawnMob {
|
||||
public final class SpawnMob {
|
||||
|
||||
private static final Material GOLDEN_HELMET = EnumUtil.getMaterial("GOLDEN_HELMET", "GOLD_HELMET");
|
||||
private static final Material GOLDEN_CHESTPLATE = EnumUtil.getMaterial("GOLDEN_CHESTPLATE", "GOLD_CHESTPLATE");
|
||||
@@ -27,10 +36,13 @@ public class SpawnMob {
|
||||
private static final Material GOLDEN_BOOTS = EnumUtil.getMaterial("GOLDEN_BOOTS", "GOLD_BOOTS");
|
||||
private static final Material GOLDEN_SWORD = EnumUtil.getMaterial("GOLDEN_SWORD", "GOLD_SWORD");
|
||||
|
||||
private SpawnMob() {
|
||||
}
|
||||
|
||||
public static String mobList(final User user) {
|
||||
final Set<String> mobList = Mob.getMobList();
|
||||
final Set<String> availableList = new HashSet<String>();
|
||||
for (String mob : mobList) {
|
||||
final Set<String> availableList = new HashSet<>();
|
||||
for (final String mob : mobList) {
|
||||
if (user.isAuthorized("essentials.spawnmob." + mob.toLowerCase(Locale.ENGLISH))) {
|
||||
availableList.add(mob);
|
||||
}
|
||||
@@ -42,24 +54,24 @@ public class SpawnMob {
|
||||
}
|
||||
|
||||
public static List<String> mobParts(final String mobString) {
|
||||
String[] mobParts = mobString.split(",");
|
||||
final String[] mobParts = mobString.split(",");
|
||||
|
||||
List<String> mobs = new ArrayList<String>();
|
||||
final List<String> mobs = new ArrayList<>();
|
||||
|
||||
for (String mobPart : mobParts) {
|
||||
String[] mobDatas = mobPart.split(":");
|
||||
for (final String mobPart : mobParts) {
|
||||
final String[] mobDatas = mobPart.split(":");
|
||||
mobs.add(mobDatas[0]);
|
||||
}
|
||||
return mobs;
|
||||
}
|
||||
|
||||
public static List<String> mobData(final String mobString) {
|
||||
String[] mobParts = mobString.split(",");
|
||||
final String[] mobParts = mobString.split(",");
|
||||
|
||||
List<String> mobData = new ArrayList<String>();
|
||||
final List<String> mobData = new ArrayList<>();
|
||||
|
||||
for (String mobPart : mobParts) {
|
||||
String[] mobDatas = mobPart.split(":");
|
||||
for (final String mobPart : mobParts) {
|
||||
final String[] mobDatas = mobPart.split(":");
|
||||
if (mobDatas.length == 1) {
|
||||
if (mobPart.contains(":")) {
|
||||
mobData.add("");
|
||||
@@ -75,7 +87,7 @@ public class SpawnMob {
|
||||
}
|
||||
|
||||
// This method spawns a mob where the user is looking, owned by user
|
||||
public static void spawnmob(final IEssentials ess, final Server server, final User user, final List<String> parts, final List<String> data, int mobCount) throws Exception {
|
||||
public static void spawnmob(final IEssentials ess, final Server server, final User user, final List<String> parts, final List<String> data, final int mobCount) throws Exception {
|
||||
final Block block = LocationUtil.getTarget(user.getBase()).getBlock();
|
||||
if (block == null) {
|
||||
throw new Exception(tl("unableToSpawnMob"));
|
||||
@@ -84,7 +96,7 @@ public class SpawnMob {
|
||||
}
|
||||
|
||||
// This method spawns a mob at target, owned by target
|
||||
public static void spawnmob(final IEssentials ess, final Server server, final CommandSource sender, final User target, final List<String> parts, final List<String> data, int mobCount) throws Exception {
|
||||
public static void spawnmob(final IEssentials ess, final Server server, final CommandSource sender, final User target, final List<String> parts, final List<String> data, final int mobCount) throws Exception {
|
||||
spawnmob(ess, server, sender, target, target.getLocation(), parts, data, mobCount);
|
||||
}
|
||||
|
||||
@@ -92,8 +104,8 @@ public class SpawnMob {
|
||||
public static void spawnmob(final IEssentials ess, final Server server, final CommandSource sender, final User target, final Location loc, final List<String> parts, final List<String> data, int mobCount) throws Exception {
|
||||
final Location sloc = LocationUtil.getSafeDestination(loc);
|
||||
|
||||
for (int i = 0; i < parts.size(); i++) {
|
||||
Mob mob = Mob.fromName(parts.get(i));
|
||||
for (final String part : parts) {
|
||||
final Mob mob = Mob.fromName(part);
|
||||
checkSpawnable(ess, sender, mob);
|
||||
}
|
||||
|
||||
@@ -112,22 +124,22 @@ public class SpawnMob {
|
||||
sender.sendMessage(tl("mobSpawnLimit"));
|
||||
}
|
||||
|
||||
Mob mob = Mob.fromName(parts.get(0)); // Get the first mob
|
||||
final Mob mob = Mob.fromName(parts.get(0)); // Get the first mob
|
||||
try {
|
||||
for (int i = 0; i < mobCount; i++) {
|
||||
spawnMob(ess, server, sender, target, sloc, parts, data);
|
||||
}
|
||||
sender.sendMessage(mobCount * parts.size() + " " + mob.name.toLowerCase(Locale.ENGLISH) + mob.suffix + " " + tl("spawned"));
|
||||
} catch (MobException e1) {
|
||||
} catch (final MobException e1) {
|
||||
throw new Exception(tl("unableToSpawnMob"), e1);
|
||||
} catch (NumberFormatException e2) {
|
||||
} catch (final NumberFormatException e2) {
|
||||
throw new Exception(tl("numberRequired"), e2);
|
||||
} catch (NullPointerException np) {
|
||||
} catch (final NullPointerException np) {
|
||||
throw new Exception(tl("soloMob"), np);
|
||||
}
|
||||
}
|
||||
|
||||
private static void spawnMob(final IEssentials ess, final Server server, final CommandSource sender, final User target, final Location sloc, List<String> parts, List<String> data) throws Exception {
|
||||
private static void spawnMob(final IEssentials ess, final Server server, final CommandSource sender, final User target, final Location sloc, final List<String> parts, final List<String> data) throws Exception {
|
||||
Mob mob;
|
||||
Entity spawnedMob = null;
|
||||
Entity spawnedMount;
|
||||
@@ -143,10 +155,10 @@ public class SpawnMob {
|
||||
}
|
||||
}
|
||||
|
||||
int next = (i + 1);
|
||||
if (next < parts.size()) //If it's the last mob in the list, don't set the mount
|
||||
{
|
||||
Mob mMob = Mob.fromName(parts.get(next));
|
||||
final int next = i + 1;
|
||||
// If it's the last mob in the list, don't set the mount
|
||||
if (next < parts.size()) {
|
||||
final Mob mMob = Mob.fromName(parts.get(next));
|
||||
spawnedMount = mMob.spawn(sloc.getWorld(), server, sloc);
|
||||
defaultMobData(mMob.getType(), spawnedMount);
|
||||
|
||||
@@ -161,7 +173,7 @@ public class SpawnMob {
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkSpawnable(IEssentials ess, CommandSource sender, Mob mob) throws Exception {
|
||||
private static void checkSpawnable(final IEssentials ess, final CommandSource sender, final Mob mob) throws Exception {
|
||||
if (mob == null || mob.getType() == null) {
|
||||
throw new Exception(tl("invalidMob"));
|
||||
}
|
||||
@@ -235,30 +247,20 @@ public class SpawnMob {
|
||||
final EntityEquipment invent = ((LivingEntity) spawned).getEquipment();
|
||||
InventoryWorkaround.setItemInMainHand(invent, new ItemStack(Material.BOW, 1));
|
||||
InventoryWorkaround.setItemInMainHandDropChance(invent, 0.1f);
|
||||
|
||||
invent.setBoots(new ItemStack(GOLDEN_BOOTS, 1));
|
||||
invent.setBootsDropChance(0.0f);
|
||||
}
|
||||
|
||||
if (type == EntityType.PIG_ZOMBIE) {
|
||||
final PigZombie zombie = ((PigZombie) spawned);
|
||||
if (type == MobCompat.ZOMBIFIED_PIGLIN) {
|
||||
final PigZombie zombie = (PigZombie) spawned;
|
||||
setVillager(zombie, false);
|
||||
|
||||
final EntityEquipment invent = zombie.getEquipment();
|
||||
InventoryWorkaround.setItemInMainHand(invent, new ItemStack(GOLDEN_SWORD, 1));
|
||||
InventoryWorkaround.setItemInMainHandDropChance(invent, 0.1f);
|
||||
|
||||
invent.setBoots(new ItemStack(GOLDEN_BOOTS, 1));
|
||||
invent.setBootsDropChance(0.0f);
|
||||
}
|
||||
|
||||
if (type == EntityType.ZOMBIE) {
|
||||
final Zombie zombie = ((Zombie) spawned);
|
||||
final Zombie zombie = (Zombie) spawned;
|
||||
setVillager(zombie, false);
|
||||
|
||||
final EntityEquipment invent = zombie.getEquipment();
|
||||
invent.setBoots(new ItemStack(GOLDEN_BOOTS, 1));
|
||||
invent.setBootsDropChance(0.0f);
|
||||
}
|
||||
|
||||
if (type == EntityType.HORSE) {
|
||||
@@ -267,10 +269,10 @@ public class SpawnMob {
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private static void setVillager(Zombie zombie, boolean villager) {
|
||||
private static void setVillager(final Zombie zombie, final boolean villager) {
|
||||
try {
|
||||
zombie.setVillager(villager);
|
||||
} catch (Exception ignored) {
|
||||
} catch (final Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,6 @@ import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||
|
||||
|
||||
public class TNTExplodeListener implements Listener, Runnable {
|
||||
private final transient IEssentials ess;
|
||||
private transient boolean enabled = false;
|
||||
|
||||
@@ -7,6 +7,8 @@ import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.ITeleport;
|
||||
import net.ess3.api.IUser;
|
||||
import net.ess3.api.events.UserWarpEvent;
|
||||
import net.ess3.api.events.teleport.PreTeleportEvent;
|
||||
import net.ess3.api.events.teleport.TeleportWarmupEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -19,7 +21,10 @@ import java.util.GregorianCalendar;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated This API is not asynchronous. Use {@link com.earth2me.essentials.AsyncTeleport AsyncTeleport}
|
||||
*/
|
||||
@Deprecated
|
||||
public class Teleport implements ITeleport {
|
||||
private final IUser teleportOwner;
|
||||
private final IEssentials ess;
|
||||
@@ -27,19 +32,15 @@ public class Teleport implements ITeleport {
|
||||
|
||||
private TeleportType tpType;
|
||||
|
||||
public Teleport(IUser user, IEssentials ess) {
|
||||
@Deprecated
|
||||
public Teleport(final IUser user, final IEssentials ess) {
|
||||
this.teleportOwner = user;
|
||||
this.ess = ess;
|
||||
tpType = TeleportType.NORMAL;
|
||||
}
|
||||
|
||||
public enum TeleportType {
|
||||
TPA,
|
||||
BACK,
|
||||
NORMAL
|
||||
}
|
||||
|
||||
public void cooldown(boolean check) throws Exception {
|
||||
@Deprecated
|
||||
public void cooldown(final boolean check) throws Exception {
|
||||
final Calendar time = new GregorianCalendar();
|
||||
if (teleportOwner.getLastTeleportTimestamp() > 0) {
|
||||
// Take the current time, and remove the delay from it.
|
||||
@@ -59,7 +60,7 @@ public class Teleport implements ITeleport {
|
||||
teleportOwner.setLastTeleportTimestamp(time.getTimeInMillis());
|
||||
return;
|
||||
} else if (lastTime > earliestLong
|
||||
&& cooldownApplies()) {
|
||||
&& cooldownApplies()) {
|
||||
time.setTimeInMillis(lastTime);
|
||||
time.add(Calendar.SECOND, (int) cooldown);
|
||||
time.add(Calendar.MILLISECOND, (int) ((cooldown * 1000.0) % 1000.0));
|
||||
@@ -72,27 +73,29 @@ public class Teleport implements ITeleport {
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
private boolean cooldownApplies() {
|
||||
boolean applies = true;
|
||||
String globalBypassPerm = "essentials.teleport.cooldown.bypass";
|
||||
final String globalBypassPerm = "essentials.teleport.cooldown.bypass";
|
||||
switch (tpType) {
|
||||
case NORMAL:
|
||||
applies = !teleportOwner.isAuthorized(globalBypassPerm);
|
||||
break;
|
||||
case BACK:
|
||||
applies = !(teleportOwner.isAuthorized(globalBypassPerm) &&
|
||||
teleportOwner.isAuthorized("essentials.teleport.cooldown.bypass.back"));
|
||||
teleportOwner.isAuthorized("essentials.teleport.cooldown.bypass.back"));
|
||||
break;
|
||||
case TPA:
|
||||
applies = !(teleportOwner.isAuthorized(globalBypassPerm) &&
|
||||
teleportOwner.isAuthorized("essentials.teleport.cooldown.bypass.tpa"));
|
||||
teleportOwner.isAuthorized("essentials.teleport.cooldown.bypass.tpa"));
|
||||
break;
|
||||
}
|
||||
return applies;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
private void warnUser(final IUser user, final double delay) {
|
||||
Calendar c = new GregorianCalendar();
|
||||
final Calendar c = new GregorianCalendar();
|
||||
c.add(Calendar.SECOND, (int) delay);
|
||||
c.add(Calendar.MILLISECOND, (int) ((delay * 1000.0) % 1000.0));
|
||||
user.sendMessage(tl("dontMoveMessage", DateUtil.formatDateDiff(c.getTimeInMillis())));
|
||||
@@ -100,7 +103,8 @@ public class Teleport implements ITeleport {
|
||||
|
||||
//The now function is used when you want to skip tp delay when teleporting someone to a location or player.
|
||||
@Override
|
||||
public void now(Location loc, boolean cooldown, TeleportCause cause) throws Exception {
|
||||
@Deprecated
|
||||
public void now(final Location loc, final boolean cooldown, final TeleportCause cause) throws Exception {
|
||||
if (cooldown) {
|
||||
cooldown(false);
|
||||
}
|
||||
@@ -109,7 +113,8 @@ public class Teleport implements ITeleport {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void now(Player entity, boolean cooldown, TeleportCause cause) throws Exception {
|
||||
@Deprecated
|
||||
public void now(final Player entity, final boolean cooldown, final TeleportCause cause) throws Exception {
|
||||
if (cooldown) {
|
||||
cooldown(false);
|
||||
}
|
||||
@@ -118,11 +123,28 @@ public class Teleport implements ITeleport {
|
||||
teleportOwner.sendMessage(tl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ()));
|
||||
}
|
||||
|
||||
protected void now(IUser teleportee, ITarget target, TeleportCause cause) throws Exception {
|
||||
@Deprecated
|
||||
protected void now(final IUser teleportee, final ITarget target, final TeleportCause cause) throws Exception {
|
||||
cancel(false);
|
||||
teleportee.setLastLocation();
|
||||
Location loc = target.getLocation();
|
||||
|
||||
final PreTeleportEvent event = new PreTeleportEvent(teleportee, cause, target);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (teleportee.isAuthorized("essentials.back.onteleport")) {
|
||||
teleportee.setLastLocation();
|
||||
}
|
||||
|
||||
if (!teleportee.getBase().isEmpty()) {
|
||||
if (!ess.getSettings().isTeleportPassengerDismount()) {
|
||||
throw new Exception(tl("passengerTeleportFail"));
|
||||
}
|
||||
teleportee.getBase().eject();
|
||||
}
|
||||
|
||||
if (LocationUtil.isBlockUnsafeForUser(teleportee, loc.getWorld(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())) {
|
||||
if (ess.getSettings().isTeleportSafetyEnabled()) {
|
||||
if (ess.getSettings().isForceDisableTeleportSafety()) {
|
||||
@@ -149,41 +171,53 @@ public class Teleport implements ITeleport {
|
||||
//This method is nolonger used internally and will be removed.
|
||||
@Deprecated
|
||||
@Override
|
||||
public void teleport(Location loc, Trade chargeFor) throws Exception {
|
||||
public void teleport(final Location loc, final Trade chargeFor) throws Exception {
|
||||
teleport(loc, chargeFor, TeleportCause.PLUGIN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teleport(Location loc, Trade chargeFor, TeleportCause cause) throws Exception {
|
||||
@Deprecated
|
||||
public void teleport(final Location loc, final Trade chargeFor, final TeleportCause cause) throws Exception {
|
||||
teleport(teleportOwner, new LocationTarget(loc), chargeFor, cause);
|
||||
}
|
||||
|
||||
//This is used when teleporting to a player
|
||||
@Override
|
||||
public void teleport(Player entity, Trade chargeFor, TeleportCause cause) throws Exception {
|
||||
ITarget target = new PlayerTarget(entity);
|
||||
@Deprecated
|
||||
public void teleport(final Player entity, final Trade chargeFor, final TeleportCause cause) throws Exception {
|
||||
final ITarget target = new PlayerTarget(entity);
|
||||
teleportOwner.sendMessage(tl("teleportToPlayer", entity.getDisplayName()));
|
||||
teleport(teleportOwner, target, chargeFor, cause);
|
||||
}
|
||||
|
||||
//This is used when teleporting to stored location
|
||||
@Override
|
||||
public void teleportPlayer(IUser teleportee, Location loc, Trade chargeFor, TeleportCause cause) throws Exception {
|
||||
@Deprecated
|
||||
public void teleportPlayer(final IUser teleportee, final Location loc, final Trade chargeFor, final TeleportCause cause) throws Exception {
|
||||
teleport(teleportee, new LocationTarget(loc), chargeFor, cause);
|
||||
}
|
||||
|
||||
//This is used on /tphere
|
||||
@Override
|
||||
public void teleportPlayer(IUser teleportee, Player entity, Trade chargeFor, TeleportCause cause) throws Exception {
|
||||
ITarget target = new PlayerTarget(entity);
|
||||
@Deprecated
|
||||
public void teleportPlayer(final IUser teleportee, final Player entity, final Trade chargeFor, final TeleportCause cause) throws Exception {
|
||||
final ITarget target = new PlayerTarget(entity);
|
||||
teleport(teleportee, target, chargeFor, cause);
|
||||
teleportee.sendMessage(tl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ()));
|
||||
teleportOwner.sendMessage(tl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ()));
|
||||
}
|
||||
|
||||
private void teleport(IUser teleportee, ITarget target, Trade chargeFor, TeleportCause cause) throws Exception {
|
||||
@Deprecated
|
||||
private void teleport(final IUser teleportee, final ITarget target, final Trade chargeFor, final TeleportCause cause) throws Exception {
|
||||
double delay = ess.getSettings().getTeleportDelay();
|
||||
|
||||
final TeleportWarmupEvent event = new TeleportWarmupEvent(teleportee, cause, target, delay);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
delay = event.getDelay();
|
||||
|
||||
Trade cashCharge = chargeFor;
|
||||
|
||||
if (chargeFor != null) {
|
||||
@@ -211,9 +245,17 @@ public class Teleport implements ITeleport {
|
||||
initTimer((long) (delay * 1000.0), teleportee, target, cashCharge, cause, false);
|
||||
}
|
||||
|
||||
private void teleportOther(IUser teleporter, IUser teleportee, ITarget target, Trade chargeFor, TeleportCause cause) throws Exception {
|
||||
@Deprecated
|
||||
private void teleportOther(final IUser teleporter, final IUser teleportee, final ITarget target, final Trade chargeFor, final TeleportCause cause) throws Exception {
|
||||
double delay = ess.getSettings().getTeleportDelay();
|
||||
|
||||
final TeleportWarmupEvent event = new TeleportWarmupEvent(teleporter, teleportee, cause, target, delay);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
delay = event.getDelay();
|
||||
|
||||
Trade cashCharge = chargeFor;
|
||||
|
||||
if (teleporter != null && chargeFor != null) {
|
||||
@@ -228,9 +270,9 @@ public class Teleport implements ITeleport {
|
||||
|
||||
cooldown(true);
|
||||
if (delay <= 0 || teleporter == null
|
||||
|| teleporter.isAuthorized("essentials.teleport.timer.bypass")
|
||||
|| teleportOwner.isAuthorized("essentials.teleport.timer.bypass")
|
||||
|| teleportee.isAuthorized("essentials.teleport.timer.bypass")) {
|
||||
|| teleporter.isAuthorized("essentials.teleport.timer.bypass")
|
||||
|| teleportOwner.isAuthorized("essentials.teleport.timer.bypass")
|
||||
|| teleportee.isAuthorized("essentials.teleport.timer.bypass")) {
|
||||
cooldown(false);
|
||||
now(teleportee, target, cause);
|
||||
if (teleporter != null && cashCharge != null) {
|
||||
@@ -246,8 +288,17 @@ public class Teleport implements ITeleport {
|
||||
|
||||
//The respawn function is a wrapper used to handle tp fallback, on /jail and /home
|
||||
@Override
|
||||
public void respawn(final Trade chargeFor, TeleportCause cause) throws Exception {
|
||||
@Deprecated
|
||||
public void respawn(final Trade chargeFor, final TeleportCause cause) throws Exception {
|
||||
double delay = ess.getSettings().getTeleportDelay();
|
||||
|
||||
final TeleportWarmupEvent event = new TeleportWarmupEvent(teleportOwner, cause, null, delay);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
delay = event.getDelay();
|
||||
|
||||
if (chargeFor != null) {
|
||||
chargeFor.isAffordableFor(teleportOwner);
|
||||
}
|
||||
@@ -266,9 +317,10 @@ public class Teleport implements ITeleport {
|
||||
initTimer((long) (delay * 1000.0), teleportOwner, null, chargeFor, cause, true);
|
||||
}
|
||||
|
||||
void respawnNow(IUser teleportee, TeleportCause cause) throws Exception {
|
||||
@Deprecated
|
||||
void respawnNow(final IUser teleportee, final TeleportCause cause) throws Exception {
|
||||
final Player player = teleportee.getBase();
|
||||
Location bed = player.getBedSpawnLocation();
|
||||
final Location bed = player.getBedSpawnLocation();
|
||||
if (bed != null) {
|
||||
now(teleportee, new LocationTarget(bed), cause);
|
||||
} else {
|
||||
@@ -283,15 +335,16 @@ public class Teleport implements ITeleport {
|
||||
|
||||
//The warp function is a wrapper used to teleportPlayer a player to a /warp
|
||||
@Override
|
||||
public void warp(IUser teleportee, String warp, Trade chargeFor, TeleportCause cause) throws Exception {
|
||||
UserWarpEvent event = new UserWarpEvent(teleportee, warp, chargeFor);
|
||||
@Deprecated
|
||||
public void warp(final IUser teleportee, String warp, final Trade chargeFor, final TeleportCause cause) throws Exception {
|
||||
final UserWarpEvent event = new UserWarpEvent(teleportee, warp, chargeFor);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
|
||||
if(event.isCancelled()) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
warp = event.getWarp();
|
||||
Location loc = ess.getWarps().getWarp(warp);
|
||||
final Location loc = ess.getWarps().getWarp(warp);
|
||||
teleportee.sendMessage(tl("warpingTo", warp, loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
|
||||
if (!teleportee.equals(teleportOwner)) {
|
||||
teleportOwner.sendMessage(tl("warpingTo", warp, loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
|
||||
@@ -301,13 +354,15 @@ public class Teleport implements ITeleport {
|
||||
|
||||
//The back function is a wrapper used to teleportPlayer a player /back to their previous location.
|
||||
@Override
|
||||
public void back(Trade chargeFor) throws Exception {
|
||||
@Deprecated
|
||||
public void back(final Trade chargeFor) throws Exception {
|
||||
back(teleportOwner, chargeFor);
|
||||
}
|
||||
|
||||
//This function is a wrapper over the other back function for cases where another player performs back for them
|
||||
@Override
|
||||
public void back(IUser teleporter, Trade chargeFor) throws Exception {
|
||||
@Deprecated
|
||||
public void back(final IUser teleporter, final Trade chargeFor) throws Exception {
|
||||
tpType = TeleportType.BACK;
|
||||
final Location loc = teleportOwner.getLastLocation();
|
||||
teleportOwner.sendMessage(tl("backUsageMsg", loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
|
||||
@@ -316,23 +371,33 @@ public class Teleport implements ITeleport {
|
||||
|
||||
//This function is used to throw a user back after a jail sentence
|
||||
@Override
|
||||
@Deprecated
|
||||
public void back() throws Exception {
|
||||
now(teleportOwner, new LocationTarget(teleportOwner.getLastLocation()), TeleportCause.COMMAND);
|
||||
}
|
||||
|
||||
public void setTpType(TeleportType tpType) {
|
||||
@Deprecated
|
||||
public void setTpType(final TeleportType tpType) {
|
||||
this.tpType = tpType;
|
||||
}
|
||||
|
||||
//If we need to cancelTimer a pending teleportPlayer call this method
|
||||
private void cancel(boolean notifyUser) {
|
||||
@Deprecated
|
||||
private void cancel(final boolean notifyUser) {
|
||||
if (timedTeleport != null) {
|
||||
timedTeleport.cancelTimer(notifyUser);
|
||||
timedTeleport = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void initTimer(long delay, IUser teleportUser, ITarget target, Trade chargeFor, TeleportCause cause, boolean respawn) {
|
||||
@Deprecated
|
||||
private void initTimer(final long delay, final IUser teleportUser, final ITarget target, final Trade chargeFor, final TeleportCause cause, final boolean respawn) {
|
||||
timedTeleport = new TimedTeleport(teleportOwner, ess, this, delay, teleportUser, target, chargeFor, cause, respawn);
|
||||
}
|
||||
|
||||
public enum TeleportType {
|
||||
TPA,
|
||||
BACK,
|
||||
NORMAL
|
||||
}
|
||||
}
|
||||
@@ -9,17 +9,15 @@ import java.util.UUID;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
@Deprecated
|
||||
public class TimedTeleport implements Runnable {
|
||||
private static final double MOVE_CONSTANT = 0.3;
|
||||
private final IUser teleportOwner;
|
||||
private final IEssentials ess;
|
||||
private final Teleport teleport;
|
||||
private final UUID timer_teleportee;
|
||||
private int timer_task;
|
||||
private final long timer_started; // time this task was initiated
|
||||
private final long timer_delay; // how long to delay the teleportPlayer
|
||||
private double timer_health;
|
||||
// note that I initially stored a clone of the location for reference, but...
|
||||
// when comparing locations, I got incorrect mismatches (rounding errors, looked like)
|
||||
// so, the X/Y/Z values are stored instead and rounded off
|
||||
@@ -31,8 +29,10 @@ public class TimedTeleport implements Runnable {
|
||||
private final boolean timer_canMove;
|
||||
private final Trade timer_chargeFor;
|
||||
private final TeleportCause timer_cause;
|
||||
private int timer_task;
|
||||
private double timer_health;
|
||||
|
||||
TimedTeleport(IUser user, IEssentials ess, Teleport teleport, long delay, IUser teleportUser, ITarget target, Trade chargeFor, TeleportCause cause, boolean respawn) {
|
||||
TimedTeleport(final IUser user, final IEssentials ess, final Teleport teleport, final long delay, final IUser teleportUser, final ITarget target, final Trade chargeFor, final TeleportCause cause, final boolean respawn) {
|
||||
this.teleportOwner = user;
|
||||
this.ess = ess;
|
||||
this.teleport = teleport;
|
||||
@@ -83,12 +83,12 @@ public class TimedTeleport implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
timer_health = teleportUser.getBase().getHealth(); // in case user healed, then later gets injured
|
||||
timer_health = teleportUser.getBase().getHealth(); // in case user healed, then later gets injured
|
||||
final long now = System.currentTimeMillis();
|
||||
if (now > timer_started + timer_delay) {
|
||||
try {
|
||||
teleport.cooldown(false);
|
||||
} catch (Exception ex) {
|
||||
} catch (final Exception ex) {
|
||||
teleportOwner.sendMessage(tl("cooldownWithMessage", ex.getMessage()));
|
||||
if (teleportOwner != teleportUser) {
|
||||
teleportUser.sendMessage(tl("cooldownWithMessage", ex.getMessage()));
|
||||
@@ -98,31 +98,30 @@ public class TimedTeleport implements Runnable {
|
||||
cancelTimer(false);
|
||||
teleportUser.sendMessage(tl("teleportationCommencing"));
|
||||
|
||||
try {
|
||||
if (timer_chargeFor != null) {
|
||||
timer_chargeFor.isAffordableFor(teleportOwner);
|
||||
}
|
||||
if (timer_respawn) {
|
||||
teleport.respawnNow(teleportUser, timer_cause);
|
||||
} else {
|
||||
teleport.now(teleportUser, timer_teleportTarget, timer_cause);
|
||||
}
|
||||
if (timer_chargeFor != null) {
|
||||
timer_chargeFor.charge(teleportOwner);
|
||||
}
|
||||
} catch (Exception ignored) {}
|
||||
if (timer_chargeFor != null) {
|
||||
timer_chargeFor.isAffordableFor(teleportOwner);
|
||||
}
|
||||
if (timer_respawn) {
|
||||
teleport.respawnNow(teleportUser, timer_cause);
|
||||
} else {
|
||||
teleport.now(teleportUser, timer_teleportTarget, timer_cause);
|
||||
}
|
||||
if (timer_chargeFor != null) {
|
||||
timer_chargeFor.charge(teleportOwner);
|
||||
}
|
||||
|
||||
} catch (Exception ex) {
|
||||
} catch (final Exception ex) {
|
||||
ess.showError(teleportOwner.getSource(), ex, "\\ teleport");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ess.scheduleSyncDelayedTask(new DelayedTeleportTask());
|
||||
}
|
||||
|
||||
//If we need to cancelTimer a pending teleportPlayer call this method
|
||||
void cancelTimer(boolean notifyUser) {
|
||||
void cancelTimer(final boolean notifyUser) {
|
||||
if (timer_task == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -18,13 +18,15 @@ import java.text.DateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Trade {
|
||||
private static FileWriter fw = null;
|
||||
private final transient String command;
|
||||
private final transient Trade fallbackTrade;
|
||||
private final transient BigDecimal money;
|
||||
@@ -32,20 +34,6 @@ public class Trade {
|
||||
private final transient Integer exp;
|
||||
private final transient IEssentials ess;
|
||||
|
||||
|
||||
public enum TradeType {
|
||||
MONEY,
|
||||
EXP,
|
||||
ITEM
|
||||
}
|
||||
|
||||
|
||||
public enum OverflowType {
|
||||
ABORT,
|
||||
DROP,
|
||||
RETURN
|
||||
}
|
||||
|
||||
public Trade(final String command, final IEssentials ess) {
|
||||
this(command, null, null, null, null, ess);
|
||||
}
|
||||
@@ -80,190 +68,7 @@ public class Trade {
|
||||
this.ess = ess;
|
||||
}
|
||||
|
||||
public void isAffordableFor(final IUser user) throws ChargeException {
|
||||
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "checking if " + user.getName() + " can afford charge.");
|
||||
}
|
||||
|
||||
if (getMoney() != null && getMoney().signum() > 0 && !user.canAfford(getMoney())) {
|
||||
throw new ChargeException(tl("notEnoughMoney", NumberUtil.displayCurrency(getMoney(), ess)));
|
||||
}
|
||||
|
||||
if (getItemStack() != null && !user.getBase().getInventory().containsAtLeast(itemStack, itemStack.getAmount())) {
|
||||
throw new ChargeException(tl("missingItems", getItemStack().getAmount(), ess.getItemDb().name(getItemStack())));
|
||||
}
|
||||
|
||||
BigDecimal money;
|
||||
if (command != null && !command.isEmpty() && (money = getCommandCost(user)).signum() > 0 && !user.canAfford(money)) {
|
||||
throw new ChargeException(tl("notEnoughMoney", NumberUtil.displayCurrency(money, ess)));
|
||||
}
|
||||
|
||||
if (exp != null && exp > 0 && SetExpFix.getTotalExperience(user.getBase()) < exp) {
|
||||
throw new ChargeException(tl("notEnoughExperience"));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean pay(final IUser user) throws MaxMoneyException {
|
||||
return pay(user, OverflowType.ABORT) == null;
|
||||
}
|
||||
|
||||
public Map<Integer, ItemStack> pay(final IUser user, final OverflowType type) throws MaxMoneyException {
|
||||
if (getMoney() != null && getMoney().signum() > 0) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "paying user " + user.getName() + " via trade " + getMoney().toPlainString());
|
||||
}
|
||||
user.giveMoney(getMoney());
|
||||
}
|
||||
if (getItemStack() != null) {
|
||||
// This stores the would be overflow
|
||||
Map<Integer, ItemStack> overFlow = InventoryWorkaround.addAllItems(user.getBase().getInventory(), getItemStack());
|
||||
|
||||
if (overFlow != null) {
|
||||
switch (type) {
|
||||
case ABORT:
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "abort paying " + user.getName() + " itemstack " + getItemStack().toString() + " due to lack of inventory space ");
|
||||
}
|
||||
|
||||
return overFlow;
|
||||
|
||||
case RETURN:
|
||||
// Pay the user the items, and return overflow
|
||||
final Map<Integer, ItemStack> returnStack = InventoryWorkaround.addItems(user.getBase().getInventory(), getItemStack());
|
||||
user.getBase().updateInventory();
|
||||
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "paying " + user.getName() + " partial itemstack " + getItemStack().toString() + " with overflow " + returnStack.get(0).toString());
|
||||
}
|
||||
|
||||
return returnStack;
|
||||
|
||||
case DROP:
|
||||
// Pay the users the items directly, and drop the rest, will always return no overflow.
|
||||
final Map<Integer, ItemStack> leftOver = InventoryWorkaround.addItems(user.getBase().getInventory(), getItemStack());
|
||||
final Location loc = user.getBase().getLocation();
|
||||
for (ItemStack loStack : leftOver.values()) {
|
||||
final int maxStackSize = loStack.getType().getMaxStackSize();
|
||||
final int stacks = loStack.getAmount() / maxStackSize;
|
||||
final int leftover = loStack.getAmount() % maxStackSize;
|
||||
final Item[] itemStacks = new Item[stacks + (leftover > 0 ? 1 : 0)];
|
||||
for (int i = 0; i < stacks; i++) {
|
||||
final ItemStack stack = loStack.clone();
|
||||
stack.setAmount(maxStackSize);
|
||||
itemStacks[i] = loc.getWorld().dropItem(loc, stack);
|
||||
}
|
||||
if (leftover > 0) {
|
||||
final ItemStack stack = loStack.clone();
|
||||
stack.setAmount(leftover);
|
||||
itemStacks[stacks] = loc.getWorld().dropItem(loc, stack);
|
||||
}
|
||||
}
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "paying " + user.getName() + " partial itemstack " + getItemStack().toString() + " and dropping overflow " + leftOver.get(0).toString());
|
||||
}
|
||||
}
|
||||
} else if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "paying " + user.getName() + " itemstack " + getItemStack().toString());
|
||||
}
|
||||
user.getBase().updateInventory();
|
||||
}
|
||||
if (getExperience() != null) {
|
||||
SetExpFix.setTotalExperience(user.getBase(), SetExpFix.getTotalExperience(user.getBase()) + getExperience());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void charge(final IUser user) throws ChargeException {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "attempting to charge user " + user.getName());
|
||||
}
|
||||
if (getMoney() != null) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "charging user " + user.getName() + " money " + getMoney().toPlainString());
|
||||
}
|
||||
if (!user.canAfford(getMoney()) && getMoney().signum() > 0) {
|
||||
throw new ChargeException(tl("notEnoughMoney", NumberUtil.displayCurrency(getMoney(), ess)));
|
||||
}
|
||||
user.takeMoney(getMoney());
|
||||
}
|
||||
if (getItemStack() != null) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "charging user " + user.getName() + " itemstack " + getItemStack().toString());
|
||||
}
|
||||
if (!user.getBase().getInventory().containsAtLeast(getItemStack(), getItemStack().getAmount())) {
|
||||
throw new ChargeException(tl("missingItems", getItemStack().getAmount(), getItemStack().getType().toString().toLowerCase(Locale.ENGLISH).replace("_", " ")));
|
||||
}
|
||||
user.getBase().getInventory().removeItem(getItemStack());
|
||||
user.getBase().updateInventory();
|
||||
}
|
||||
if (command != null) {
|
||||
final BigDecimal cost = getCommandCost(user);
|
||||
if (!user.canAfford(cost) && cost.signum() > 0) {
|
||||
throw new ChargeException(tl("notEnoughMoney", NumberUtil.displayCurrency(cost, ess)));
|
||||
}
|
||||
user.takeMoney(cost);
|
||||
}
|
||||
if (getExperience() != null) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "charging user " + user.getName() + " exp " + getExperience());
|
||||
}
|
||||
final int experience = SetExpFix.getTotalExperience(user.getBase());
|
||||
if (experience < getExperience() && getExperience() > 0) {
|
||||
throw new ChargeException(tl("notEnoughExperience"));
|
||||
}
|
||||
SetExpFix.setTotalExperience(user.getBase(), experience - getExperience());
|
||||
}
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "charge user " + user.getName() + " completed");
|
||||
}
|
||||
}
|
||||
|
||||
public BigDecimal getMoney() {
|
||||
return money;
|
||||
}
|
||||
|
||||
public ItemStack getItemStack() {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
public Integer getExperience() {
|
||||
return exp;
|
||||
}
|
||||
|
||||
public TradeType getType() {
|
||||
if (getExperience() != null) {
|
||||
return TradeType.EXP;
|
||||
}
|
||||
|
||||
if (getItemStack() != null) {
|
||||
return TradeType.ITEM;
|
||||
}
|
||||
|
||||
return TradeType.MONEY;
|
||||
}
|
||||
|
||||
public BigDecimal getCommandCost(final IUser user) {
|
||||
BigDecimal cost = BigDecimal.ZERO;
|
||||
if (command != null && !command.isEmpty()) {
|
||||
cost = ess.getSettings().getCommandCost(command.charAt(0) == '/' ? command.substring(1) : command);
|
||||
if (cost.signum() == 0 && fallbackTrade != null) {
|
||||
cost = fallbackTrade.getCommandCost(user);
|
||||
}
|
||||
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "calculated command (" + command + ") cost for " + user.getName() + " as " + cost);
|
||||
}
|
||||
}
|
||||
if (cost.signum() != 0 && (user.isAuthorized("essentials.nocommandcost.all") || user.isAuthorized("essentials.nocommandcost." + command))) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
return cost;
|
||||
}
|
||||
|
||||
private static FileWriter fw = null;
|
||||
|
||||
public static void log(String type, String subtype, String event, String sender, Trade charge, String receiver, Trade pay, Location loc, IEssentials ess) {
|
||||
public static void log(final String type, final String subtype, final String event, final String sender, final Trade charge, final String receiver, final Trade pay, final Location loc, final IEssentials ess) {
|
||||
//isEcoLogUpdateEnabled() - This refers to log entries with no location, ie API updates #EasterEgg
|
||||
//isEcoLogEnabled() - This refers to log entries with with location, ie /pay /sell and eco signs.
|
||||
|
||||
@@ -273,11 +78,11 @@ public class Trade {
|
||||
if (fw == null) {
|
||||
try {
|
||||
fw = new FileWriter(new File(ess.getDataFolder(), "trade.log"), true);
|
||||
} catch (IOException ex) {
|
||||
} catch (final IOException ex) {
|
||||
Logger.getLogger("Essentials").log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append(type).append(",").append(subtype).append(",").append(event).append(",\"");
|
||||
sb.append(DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date()));
|
||||
sb.append("\",\"");
|
||||
@@ -341,7 +146,7 @@ public class Trade {
|
||||
try {
|
||||
fw.write(sb.toString());
|
||||
fw.flush();
|
||||
} catch (IOException ex) {
|
||||
} catch (final IOException ex) {
|
||||
Logger.getLogger("Essentials").log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
@@ -350,10 +155,237 @@ public class Trade {
|
||||
if (fw != null) {
|
||||
try {
|
||||
fw.close();
|
||||
} catch (IOException ex) {
|
||||
} catch (final IOException ex) {
|
||||
Logger.getLogger("Essentials").log(Level.SEVERE, null, ex);
|
||||
}
|
||||
fw = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void isAffordableFor(final IUser user) throws ChargeException {
|
||||
final CompletableFuture<Boolean> future = new CompletableFuture<>();
|
||||
isAffordableFor(user, future);
|
||||
if (future.isCompletedExceptionally()) {
|
||||
try {
|
||||
future.get();
|
||||
} catch (final InterruptedException e) { //If this happens, we have bigger problems...
|
||||
e.printStackTrace();
|
||||
} catch (final ExecutionException e) {
|
||||
throw (ChargeException) e.getCause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void isAffordableFor(final IUser user, final CompletableFuture<Boolean> future) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "checking if " + user.getName() + " can afford charge.");
|
||||
}
|
||||
|
||||
if (getMoney() != null && getMoney().signum() > 0 && !user.canAfford(getMoney())) {
|
||||
future.completeExceptionally(new ChargeException(tl("notEnoughMoney", NumberUtil.displayCurrency(getMoney(), ess))));
|
||||
return;
|
||||
}
|
||||
|
||||
if (getItemStack() != null && !user.getBase().getInventory().containsAtLeast(itemStack, itemStack.getAmount())) {
|
||||
future.completeExceptionally(new ChargeException(tl("missingItems", getItemStack().getAmount(), ess.getItemDb().name(getItemStack()))));
|
||||
return;
|
||||
}
|
||||
|
||||
final BigDecimal money;
|
||||
if (command != null && !command.isEmpty() && (money = getCommandCost(user)).signum() > 0 && !user.canAfford(money)) {
|
||||
future.completeExceptionally(new ChargeException(tl("notEnoughMoney", NumberUtil.displayCurrency(money, ess))));
|
||||
return;
|
||||
}
|
||||
|
||||
if (exp != null && exp > 0 && SetExpFix.getTotalExperience(user.getBase()) < exp) {
|
||||
future.completeExceptionally(new ChargeException(tl("notEnoughExperience")));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean pay(final IUser user) throws MaxMoneyException {
|
||||
return pay(user, OverflowType.ABORT) == null;
|
||||
}
|
||||
|
||||
public Map<Integer, ItemStack> pay(final IUser user, final OverflowType type) throws MaxMoneyException {
|
||||
if (getMoney() != null && getMoney().signum() > 0) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "paying user " + user.getName() + " via trade " + getMoney().toPlainString());
|
||||
}
|
||||
user.giveMoney(getMoney());
|
||||
}
|
||||
if (getItemStack() != null) {
|
||||
// This stores the would be overflow
|
||||
final Map<Integer, ItemStack> overFlow = InventoryWorkaround.addAllItems(user.getBase().getInventory(), getItemStack());
|
||||
|
||||
if (overFlow != null) {
|
||||
switch (type) {
|
||||
case ABORT:
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "abort paying " + user.getName() + " itemstack " + getItemStack().toString() + " due to lack of inventory space ");
|
||||
}
|
||||
|
||||
return overFlow;
|
||||
|
||||
case RETURN:
|
||||
// Pay the user the items, and return overflow
|
||||
final Map<Integer, ItemStack> returnStack = InventoryWorkaround.addItems(user.getBase().getInventory(), getItemStack());
|
||||
user.getBase().updateInventory();
|
||||
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "paying " + user.getName() + " partial itemstack " + getItemStack().toString() + " with overflow " + returnStack.get(0).toString());
|
||||
}
|
||||
|
||||
return returnStack;
|
||||
case DROP:
|
||||
// Pay the users the items directly, and drop the rest, will always return no overflow.
|
||||
final Map<Integer, ItemStack> leftOver = InventoryWorkaround.addItems(user.getBase().getInventory(), getItemStack());
|
||||
final Location loc = user.getBase().getLocation();
|
||||
for (final ItemStack loStack : leftOver.values()) {
|
||||
final int maxStackSize = loStack.getType().getMaxStackSize();
|
||||
final int stacks = loStack.getAmount() / maxStackSize;
|
||||
final int leftover = loStack.getAmount() % maxStackSize;
|
||||
final Item[] itemStacks = new Item[stacks + (leftover > 0 ? 1 : 0)];
|
||||
for (int i = 0; i < stacks; i++) {
|
||||
final ItemStack stack = loStack.clone();
|
||||
stack.setAmount(maxStackSize);
|
||||
itemStacks[i] = loc.getWorld().dropItem(loc, stack);
|
||||
}
|
||||
if (leftover > 0) {
|
||||
final ItemStack stack = loStack.clone();
|
||||
stack.setAmount(leftover);
|
||||
itemStacks[stacks] = loc.getWorld().dropItem(loc, stack);
|
||||
}
|
||||
}
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "paying " + user.getName() + " partial itemstack " + getItemStack().toString() + " and dropping overflow " + leftOver.get(0).toString());
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "paying " + user.getName() + " itemstack " + getItemStack().toString());
|
||||
}
|
||||
user.getBase().updateInventory();
|
||||
}
|
||||
if (getExperience() != null) {
|
||||
SetExpFix.setTotalExperience(user.getBase(), SetExpFix.getTotalExperience(user.getBase()) + getExperience());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void charge(final IUser user) throws ChargeException {
|
||||
final CompletableFuture<Boolean> future = new CompletableFuture<>();
|
||||
charge(user, future);
|
||||
if (future.isCompletedExceptionally()) {
|
||||
try {
|
||||
future.get();
|
||||
} catch (final InterruptedException e) { //If this happens, we have bigger problems...
|
||||
e.printStackTrace();
|
||||
} catch (final ExecutionException e) {
|
||||
throw (ChargeException) e.getCause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void charge(final IUser user, final CompletableFuture<Boolean> future) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "attempting to charge user " + user.getName());
|
||||
}
|
||||
if (getMoney() != null) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "charging user " + user.getName() + " money " + getMoney().toPlainString());
|
||||
}
|
||||
if (!user.canAfford(getMoney()) && getMoney().signum() > 0) {
|
||||
future.completeExceptionally(new ChargeException(tl("notEnoughMoney", NumberUtil.displayCurrency(getMoney(), ess))));
|
||||
return;
|
||||
}
|
||||
user.takeMoney(getMoney());
|
||||
}
|
||||
if (getItemStack() != null) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "charging user " + user.getName() + " itemstack " + getItemStack().toString());
|
||||
}
|
||||
if (!user.getBase().getInventory().containsAtLeast(getItemStack(), getItemStack().getAmount())) {
|
||||
future.completeExceptionally(new ChargeException(tl("missingItems", getItemStack().getAmount(), getItemStack().getType().toString().toLowerCase(Locale.ENGLISH).replace("_", " "))));
|
||||
return;
|
||||
}
|
||||
user.getBase().getInventory().removeItem(getItemStack());
|
||||
user.getBase().updateInventory();
|
||||
}
|
||||
if (command != null) {
|
||||
final BigDecimal cost = getCommandCost(user);
|
||||
if (!user.canAfford(cost) && cost.signum() > 0) {
|
||||
future.completeExceptionally(new ChargeException(tl("notEnoughMoney", NumberUtil.displayCurrency(cost, ess))));
|
||||
return;
|
||||
}
|
||||
user.takeMoney(cost);
|
||||
}
|
||||
if (getExperience() != null) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "charging user " + user.getName() + " exp " + getExperience());
|
||||
}
|
||||
final int experience = SetExpFix.getTotalExperience(user.getBase());
|
||||
if (experience < getExperience() && getExperience() > 0) {
|
||||
future.completeExceptionally(new ChargeException(tl("notEnoughExperience")));
|
||||
return;
|
||||
}
|
||||
SetExpFix.setTotalExperience(user.getBase(), experience - getExperience());
|
||||
}
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "charge user " + user.getName() + " completed");
|
||||
}
|
||||
}
|
||||
|
||||
public BigDecimal getMoney() {
|
||||
return money;
|
||||
}
|
||||
|
||||
public ItemStack getItemStack() {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
public Integer getExperience() {
|
||||
return exp;
|
||||
}
|
||||
|
||||
public TradeType getType() {
|
||||
if (getExperience() != null) {
|
||||
return TradeType.EXP;
|
||||
}
|
||||
|
||||
if (getItemStack() != null) {
|
||||
return TradeType.ITEM;
|
||||
}
|
||||
|
||||
return TradeType.MONEY;
|
||||
}
|
||||
|
||||
public BigDecimal getCommandCost(final IUser user) {
|
||||
BigDecimal cost = BigDecimal.ZERO;
|
||||
if (command != null && !command.isEmpty()) {
|
||||
cost = ess.getSettings().getCommandCost(command.charAt(0) == '/' ? command.substring(1) : command);
|
||||
if (cost.signum() == 0 && fallbackTrade != null) {
|
||||
cost = fallbackTrade.getCommandCost(user);
|
||||
}
|
||||
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "calculated command (" + command + ") cost for " + user.getName() + " as " + cost);
|
||||
}
|
||||
}
|
||||
if (cost.signum() != 0 && (user.isAuthorized("essentials.nocommandcost.all") || user.isAuthorized("essentials.nocommandcost." + command))) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
return cost;
|
||||
}
|
||||
|
||||
public enum TradeType {
|
||||
MONEY,
|
||||
EXP,
|
||||
ITEM
|
||||
}
|
||||
|
||||
public enum OverflowType {
|
||||
ABORT,
|
||||
DROP,
|
||||
RETURN
|
||||
}
|
||||
}
|
||||
@@ -3,40 +3,42 @@ package com.earth2me.essentials;
|
||||
import com.google.common.io.Files;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.ConcurrentSkipListMap;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
public class UUIDMap {
|
||||
private final transient net.ess3.api.IEssentials ess;
|
||||
private File userList;
|
||||
private final transient Pattern splitPattern = Pattern.compile(",");
|
||||
|
||||
private static boolean pendingWrite;
|
||||
private static final ScheduledExecutorService writeScheduler = Executors.newScheduledThreadPool(1);
|
||||
private final Runnable writeTaskRunnable;
|
||||
|
||||
private static boolean pendingWrite;
|
||||
private static boolean loading = false;
|
||||
private final transient net.ess3.api.IEssentials ess;
|
||||
private final File userList;
|
||||
private final transient Pattern splitPattern = Pattern.compile(",");
|
||||
private final Runnable writeTaskRunnable;
|
||||
|
||||
public UUIDMap(final net.ess3.api.IEssentials ess) {
|
||||
this.ess = ess;
|
||||
userList = new File(ess.getDataFolder(), "usermap.csv");
|
||||
pendingWrite = false;
|
||||
writeTaskRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (pendingWrite) {
|
||||
try {
|
||||
new WriteRunner(ess.getDataFolder(), userList, ess.getUserMap().getNames()).run();
|
||||
} catch (Throwable t) { // bad code to prevent task from being suppressed
|
||||
t.printStackTrace();
|
||||
}
|
||||
writeTaskRunnable = () -> {
|
||||
if (pendingWrite) {
|
||||
try {
|
||||
new WriteRunner(ess.getDataFolder(), userList, ess.getUserMap().getNames()).run();
|
||||
} catch (final Throwable t) { // bad code to prevent task from being suppressed
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -61,7 +63,7 @@ public class UUIDMap {
|
||||
history.clear();
|
||||
loading = true;
|
||||
|
||||
try (BufferedReader reader = new BufferedReader(new FileReader(userList))) {
|
||||
try (final BufferedReader reader = new BufferedReader(new FileReader(userList))) {
|
||||
while (true) {
|
||||
final String line = reader.readLine();
|
||||
if (line == null) {
|
||||
@@ -87,7 +89,7 @@ public class UUIDMap {
|
||||
}
|
||||
}
|
||||
loading = false;
|
||||
} catch (IOException ex) {
|
||||
} catch (final IOException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
@@ -109,7 +111,7 @@ public class UUIDMap {
|
||||
writeScheduler.shutdown();
|
||||
}
|
||||
|
||||
private static class WriteRunner implements Runnable {
|
||||
private static final class WriteRunner implements Runnable {
|
||||
private final File location;
|
||||
private final File endFile;
|
||||
private final Map<String, UUID> names;
|
||||
@@ -132,19 +134,19 @@ public class UUIDMap {
|
||||
configFile = File.createTempFile("usermap", ".tmp.csv", location);
|
||||
|
||||
final BufferedWriter bWriter = new BufferedWriter(new FileWriter(configFile));
|
||||
for (Map.Entry<String, UUID> entry : names.entrySet()) {
|
||||
for (final Map.Entry<String, UUID> entry : names.entrySet()) {
|
||||
bWriter.write(entry.getKey() + "," + entry.getValue().toString());
|
||||
bWriter.newLine();
|
||||
}
|
||||
|
||||
bWriter.close();
|
||||
Files.move(configFile, endFile);
|
||||
} catch (IOException ex) {
|
||||
} catch (final IOException ex) {
|
||||
try {
|
||||
if (configFile != null && configFile.exists()) {
|
||||
Files.move(configFile, new File(endFile.getParentFile(), "usermap.bak.csv"));
|
||||
}
|
||||
} catch (Exception ex2) {
|
||||
} catch (final Exception ex2) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, ex2.getMessage(), ex2);
|
||||
}
|
||||
Bukkit.getLogger().log(Level.WARNING, ex.getMessage(), ex);
|
||||
|
||||
@@ -15,11 +15,9 @@ import net.ess3.api.events.AfkStatusChangeEvent;
|
||||
import net.ess3.api.events.JailStatusChangeEvent;
|
||||
import net.ess3.api.events.MuteStatusChangeEvent;
|
||||
import net.ess3.api.events.UserBalanceUpdateEvent;
|
||||
import net.ess3.nms.refl.ReflUtil;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@@ -28,21 +26,29 @@ import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class User extends UserData implements Comparable<User>, IMessageRecipient, net.ess3.api.IUser {
|
||||
private static final Logger logger = Logger.getLogger("Essentials");
|
||||
private IMessageRecipient messageRecipient;
|
||||
private final IMessageRecipient messageRecipient;
|
||||
private transient final AsyncTeleport teleport;
|
||||
private transient final Teleport legacyTeleport;
|
||||
private final Map<User, BigDecimal> confirmingPayments = new WeakHashMap<>();
|
||||
private transient UUID teleportRequester;
|
||||
private transient boolean teleportRequestHere;
|
||||
private transient Location teleportLocation;
|
||||
private transient boolean vanished;
|
||||
private transient final Teleport teleport;
|
||||
private transient long teleportRequestTime;
|
||||
private transient long lastOnlineActivity;
|
||||
private transient long lastThrottledAction;
|
||||
@@ -57,13 +63,15 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
private boolean ignoreMsg = false;
|
||||
private String afkMessage;
|
||||
private long afkSince;
|
||||
private Map<User, BigDecimal> confirmingPayments = new WeakHashMap<>();
|
||||
private String confirmingClearCommand;
|
||||
private long lastNotifiedAboutMailsMs;
|
||||
private String lastHomeConfirmation;
|
||||
private long lastHomeConfirmationTimestamp;
|
||||
|
||||
public User(final Player base, final IEssentials ess) {
|
||||
super(base, ess);
|
||||
teleport = new Teleport(this, ess);
|
||||
teleport = new AsyncTeleport(this, ess);
|
||||
legacyTeleport = new Teleport(this, ess);
|
||||
if (isAfk()) {
|
||||
afkPosition = this.getLocation();
|
||||
}
|
||||
@@ -110,7 +118,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
|
||||
try {
|
||||
return ess.getPermissionsHandler().hasPermission(base, node);
|
||||
} catch (Exception ex) {
|
||||
} catch (final Exception ex) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.SEVERE, "Permission System Error: " + ess.getPermissionsHandler().getName() + " returned: " + ex.getMessage(), ex);
|
||||
} else {
|
||||
@@ -128,7 +136,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
|
||||
try {
|
||||
return ess.getPermissionsHandler().isPermissionSet(base, node);
|
||||
} catch (Exception ex) {
|
||||
} catch (final Exception ex) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.SEVERE, "Permission System Error: " + ess.getPermissionsHandler().getName() + " returned: " + ex.getMessage(), ex);
|
||||
} else {
|
||||
@@ -162,10 +170,14 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
|
||||
@Override
|
||||
public void giveMoney(final BigDecimal value, final CommandSource initiator) throws MaxMoneyException {
|
||||
giveMoney(value, initiator, UserBalanceUpdateEvent.Cause.UNKNOWN);
|
||||
}
|
||||
|
||||
public void giveMoney(final BigDecimal value, final CommandSource initiator, final UserBalanceUpdateEvent.Cause cause) throws MaxMoneyException {
|
||||
if (value.signum() == 0) {
|
||||
return;
|
||||
}
|
||||
setMoney(getMoney().add(value));
|
||||
setMoney(getMoney().add(value), cause);
|
||||
sendMessage(tl("addedToAccount", NumberUtil.displayCurrency(value, ess)));
|
||||
if (initiator != null) {
|
||||
initiator.sendMessage(tl("addedToOthersAccount", NumberUtil.displayCurrency(value, ess), this.getDisplayName(), NumberUtil.displayCurrency(getMoney(), ess)));
|
||||
@@ -174,13 +186,17 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
|
||||
@Override
|
||||
public void payUser(final User reciever, final BigDecimal value) throws Exception {
|
||||
payUser(reciever, value, UserBalanceUpdateEvent.Cause.UNKNOWN);
|
||||
}
|
||||
|
||||
public void payUser(final User reciever, final BigDecimal value, final UserBalanceUpdateEvent.Cause cause) throws Exception {
|
||||
if (value.compareTo(BigDecimal.ZERO) < 1) {
|
||||
throw new Exception(tl("payMustBePositive"));
|
||||
}
|
||||
|
||||
if (canAfford(value)) {
|
||||
setMoney(getMoney().subtract(value));
|
||||
reciever.setMoney(reciever.getMoney().add(value));
|
||||
setMoney(getMoney().subtract(value), cause);
|
||||
reciever.setMoney(reciever.getMoney().add(value), cause);
|
||||
sendMessage(tl("moneySentTo", NumberUtil.displayCurrency(value, ess), reciever.getDisplayName()));
|
||||
reciever.sendMessage(tl("moneyRecievedFrom", NumberUtil.displayCurrency(value, ess), getDisplayName()));
|
||||
} else {
|
||||
@@ -195,12 +211,16 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
|
||||
@Override
|
||||
public void takeMoney(final BigDecimal value, final CommandSource initiator) {
|
||||
takeMoney(value, initiator, UserBalanceUpdateEvent.Cause.UNKNOWN);
|
||||
}
|
||||
|
||||
public void takeMoney(final BigDecimal value, final CommandSource initiator, final UserBalanceUpdateEvent.Cause cause) {
|
||||
if (value.signum() == 0) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
setMoney(getMoney().subtract(value));
|
||||
} catch (MaxMoneyException ex) {
|
||||
setMoney(getMoney().subtract(value), cause);
|
||||
} catch (final MaxMoneyException ex) {
|
||||
ess.getLogger().log(Level.WARNING, "Invalid call to takeMoney, total balance can't be more than the max-money limit.", ex);
|
||||
}
|
||||
sendMessage(tl("takenFromAccount", NumberUtil.displayCurrency(value, ess)));
|
||||
@@ -220,18 +240,13 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
}
|
||||
final BigDecimal remainingBalance = getMoney().subtract(cost);
|
||||
if (!permcheck || isAuthorized("essentials.eco.loan")) {
|
||||
return (remainingBalance.compareTo(ess.getSettings().getMinMoney()) >= 0);
|
||||
return remainingBalance.compareTo(ess.getSettings().getMinMoney()) >= 0;
|
||||
}
|
||||
return (remainingBalance.signum() >= 0);
|
||||
return remainingBalance.signum() >= 0;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
ess.runTaskAsynchronously(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
_dispose();
|
||||
}
|
||||
});
|
||||
ess.runTaskAsynchronously(this::_dispose);
|
||||
}
|
||||
|
||||
private void _dispose() {
|
||||
@@ -246,7 +261,8 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
if (ess.getSettings().permissionBasedItemSpawn()) {
|
||||
final String name = material.toString().toLowerCase(Locale.ENGLISH).replace("_", "");
|
||||
|
||||
if (isAuthorized("essentials.itemspawn.item-all") || isAuthorized("essentials.itemspawn.item-" + name)) return true;
|
||||
if (isAuthorized("essentials.itemspawn.item-all") || isAuthorized("essentials.itemspawn.item-" + name))
|
||||
return true;
|
||||
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_13_0_R01)) {
|
||||
final int id = material.getId();
|
||||
@@ -282,7 +298,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
@Override
|
||||
public boolean hasOutstandingTeleportRequest() {
|
||||
if (getTeleportRequest() != null) { // Player has outstanding teleport request.
|
||||
long timeout = ess.getSettings().getTpaAcceptCancellation();
|
||||
final long timeout = ess.getSettings().getTpaAcceptCancellation();
|
||||
if (timeout != 0) {
|
||||
if ((System.currentTimeMillis() - getTeleportRequestTime()) / 1000 <= timeout) { // Player has outstanding request
|
||||
return true;
|
||||
@@ -309,13 +325,27 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
return teleportLocation;
|
||||
}
|
||||
|
||||
public String getNick(final boolean longnick) {
|
||||
return getNick(longnick, true, true);
|
||||
public String getNick() {
|
||||
return getNick(true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed for backwards compatibility.
|
||||
*/
|
||||
public String getNick(final boolean longnick) {
|
||||
return getNick(true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed for backwards compatibility.
|
||||
*/
|
||||
public String getNick(final boolean longnick, final boolean withPrefix, final boolean withSuffix) {
|
||||
return getNick(withPrefix, withSuffix);
|
||||
}
|
||||
|
||||
public String getNick(final boolean withPrefix, final boolean withSuffix) {
|
||||
final StringBuilder prefix = new StringBuilder();
|
||||
String nickname;
|
||||
final String nickname;
|
||||
String suffix = "";
|
||||
final String nick = getNickname();
|
||||
if (ess.getSettings().isCommandDisabled("nick") || nick == null || nick.isEmpty() || nick.equals(getName())) {
|
||||
@@ -329,39 +359,38 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
|
||||
if (this.getBase().isOp()) {
|
||||
try {
|
||||
final ChatColor opPrefix = ess.getSettings().getOperatorColor();
|
||||
if (opPrefix != null && opPrefix.toString().length() > 0) {
|
||||
prefix.insert(0, opPrefix.toString());
|
||||
final String opPrefix = ess.getSettings().getOperatorColor();
|
||||
if (opPrefix != null && !opPrefix.isEmpty()) {
|
||||
prefix.insert(0, opPrefix);
|
||||
suffix = "§r";
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ess.getSettings().addPrefixSuffix()) {
|
||||
//These two extra toggles are not documented, because they are mostly redundant #EasterEgg
|
||||
if (withPrefix || !ess.getSettings().disablePrefix()) {
|
||||
final String ptext = ess.getPermissionsHandler().getPrefix(base).replace('&', '§');
|
||||
final String ptext = FormatUtil.replaceFormat(ess.getPermissionsHandler().getPrefix(base));
|
||||
prefix.insert(0, ptext);
|
||||
suffix = "§r";
|
||||
}
|
||||
if (withSuffix || !ess.getSettings().disableSuffix()) {
|
||||
final String stext = ess.getPermissionsHandler().getSuffix(base).replace('&', '§');
|
||||
final String stext = FormatUtil.replaceFormat(ess.getPermissionsHandler().getSuffix(base));
|
||||
suffix = stext + "§r";
|
||||
suffix = suffix.replace("§f§f", "§f").replace("§f§r", "§r").replace("§r§r", "§r");
|
||||
// :YEP: WHAT ARE THEY DOING?
|
||||
// :YEP: STILL. LEGACY CODE.
|
||||
// :YEP: BUT WHY?
|
||||
// :YEP: I CAN'T BELIEVE THIS!
|
||||
// Code from 1542 BC #EasterEgg
|
||||
suffix = suffix.replace("§f§r", "§r").replace("§r§r", "§r");
|
||||
}
|
||||
}
|
||||
final String strPrefix = prefix.toString();
|
||||
String output = strPrefix + nickname + suffix;
|
||||
if (!longnick && output.length() > 16) {
|
||||
output = strPrefix + nickname;
|
||||
}
|
||||
if (!longnick && output.length() > 16) {
|
||||
output = FormatUtil.lastCode(strPrefix) + nickname;
|
||||
}
|
||||
if (!longnick && output.length() > 16) {
|
||||
output = FormatUtil.lastCode(strPrefix) + nickname.substring(0, 14);
|
||||
}
|
||||
if (output.charAt(output.length() - 1) == '§') {
|
||||
output = output.substring(0, output.length() - 1);
|
||||
}
|
||||
@@ -374,13 +403,10 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
if (isAfk()) {
|
||||
updateAfkListName();
|
||||
} else if (ess.getSettings().changePlayerListName()) {
|
||||
// 1.8 enabled player list-names longer than 16 characters.
|
||||
// If the server is on 1.8 or higher, provide that functionality. Otherwise, keep prior functionality.
|
||||
boolean higherOrEqualTo1_8 = ReflUtil.getNmsVersionObject().isHigherThanOrEqualTo(ReflUtil.V1_8_R1);
|
||||
String name = getNick(higherOrEqualTo1_8, ess.getSettings().isAddingPrefixInPlayerlist(), ess.getSettings().isAddingSuffixInPlayerlist());
|
||||
final String name = getNick(ess.getSettings().isAddingPrefixInPlayerlist(), ess.getSettings().isAddingSuffixInPlayerlist());
|
||||
try {
|
||||
this.getBase().setPlayerListName(name);
|
||||
} catch (IllegalArgumentException e) {
|
||||
} catch (final IllegalArgumentException e) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
logger.log(Level.INFO, "Playerlist for " + name + " was not updated. Name clashed with another online player.");
|
||||
}
|
||||
@@ -389,15 +415,25 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return super.getBase().getDisplayName() == null || (ess.getSettings().hideDisplayNameInVanish() && isHidden()) ? super.getBase().getName() : super.getBase().getDisplayName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Teleport getTeleport() {
|
||||
public AsyncTeleport getAsyncTeleport() {
|
||||
return teleport;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated This API is not asynchronous. Use {@link User#getAsyncTeleport()}
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public Teleport getTeleport() {
|
||||
return legacyTeleport;
|
||||
}
|
||||
|
||||
public long getLastOnlineActivity() {
|
||||
return lastOnlineActivity;
|
||||
}
|
||||
@@ -417,6 +453,11 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMoney(final BigDecimal value) throws MaxMoneyException {
|
||||
setMoney(value, UserBalanceUpdateEvent.Cause.UNKNOWN);
|
||||
}
|
||||
|
||||
private BigDecimal _getMoney() {
|
||||
if (ess.getSettings().isEcoDisabled()) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
@@ -432,14 +473,13 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
}
|
||||
final Method.MethodAccount account = Methods.getMethod().getAccount(this.getName());
|
||||
return BigDecimal.valueOf(account.balance());
|
||||
} catch (Exception ex) {
|
||||
} catch (final Exception ignored) {
|
||||
}
|
||||
}
|
||||
return super.getMoney();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMoney(final BigDecimal value) throws MaxMoneyException {
|
||||
public void setMoney(final BigDecimal value, final UserBalanceUpdateEvent.Cause cause) throws MaxMoneyException {
|
||||
if (ess.getSettings().isEcoDisabled()) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().info("Internal economy functions disabled, aborting balance change.");
|
||||
@@ -447,11 +487,11 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
return;
|
||||
}
|
||||
final BigDecimal oldBalance = _getMoney();
|
||||
|
||||
UserBalanceUpdateEvent updateEvent = new UserBalanceUpdateEvent(this.getBase(), oldBalance, value);
|
||||
|
||||
final UserBalanceUpdateEvent updateEvent = new UserBalanceUpdateEvent(this.getBase(), oldBalance, value, cause);
|
||||
ess.getServer().getPluginManager().callEvent(updateEvent);
|
||||
BigDecimal newBalance = updateEvent.getNewBalance();
|
||||
|
||||
final BigDecimal newBalance = updateEvent.getNewBalance();
|
||||
|
||||
if (Methods.hasMethod()) {
|
||||
try {
|
||||
final Method method = Methods.getMethod();
|
||||
@@ -460,7 +500,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
}
|
||||
final Method.MethodAccount account = Methods.getMethod().getAccount(this.getName());
|
||||
account.set(newBalance.doubleValue());
|
||||
} catch (Exception ex) {
|
||||
} catch (final Exception ignored) {
|
||||
}
|
||||
}
|
||||
super.setMoney(newBalance, true);
|
||||
@@ -471,10 +511,10 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
if (ess.getSettings().isEcoDisabled()) {
|
||||
return;
|
||||
}
|
||||
if (Methods.hasMethod() && super.getMoney() != value) {
|
||||
if (Methods.hasMethod() && !super.getMoney().equals(value)) {
|
||||
try {
|
||||
super.setMoney(value, false);
|
||||
} catch (MaxMoneyException ex) {
|
||||
} catch (final MaxMoneyException ex) {
|
||||
// We don't want to throw any errors here, just updating a cache
|
||||
}
|
||||
}
|
||||
@@ -482,7 +522,12 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
|
||||
@Override
|
||||
public void setAfk(final boolean set) {
|
||||
final AfkStatusChangeEvent afkEvent = new AfkStatusChangeEvent(this, set);
|
||||
setAfk(set, AfkStatusChangeEvent.Cause.UNKNOWN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAfk(final boolean set, final AfkStatusChangeEvent.Cause cause) {
|
||||
final AfkStatusChangeEvent afkEvent = new AfkStatusChangeEvent(this, set, cause);
|
||||
ess.getServer().getPluginManager().callEvent(afkEvent);
|
||||
if (afkEvent.isCancelled()) {
|
||||
return;
|
||||
@@ -500,40 +545,51 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
_setAfk(set);
|
||||
updateAfkListName();
|
||||
}
|
||||
|
||||
|
||||
private void updateAfkListName() {
|
||||
if (ess.getSettings().isAfkListName()) {
|
||||
if(isAfk()) {
|
||||
String afkName = ess.getSettings().getAfkListName().replace("{PLAYER}", getDisplayName()).replace("{USERNAME}", getName());
|
||||
if (isAfk()) {
|
||||
final String afkName = ess.getSettings().getAfkListName().replace("{PLAYER}", getDisplayName()).replace("{USERNAME}", getName());
|
||||
getBase().setPlayerListName(afkName);
|
||||
} else {
|
||||
getBase().setPlayerListName(null);
|
||||
setDisplayNick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean toggleAfk() {
|
||||
setAfk(!isAfk());
|
||||
return toggleAfk(AfkStatusChangeEvent.Cause.UNKNOWN);
|
||||
}
|
||||
|
||||
public boolean toggleAfk(final AfkStatusChangeEvent.Cause cause) {
|
||||
setAfk(!isAfk(), cause);
|
||||
return isAfk();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHiddenFrom(Player player) {
|
||||
return !player.canSee(getBase());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHidden() {
|
||||
return hidden;
|
||||
}
|
||||
|
||||
public boolean isHidden(final Player player) {
|
||||
return hidden || !player.canSee(getBase());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHidden(final boolean hidden) {
|
||||
this.hidden = hidden;
|
||||
if (hidden == true) {
|
||||
if (hidden) {
|
||||
setLastLogout(getLastOnlineActivity());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isHidden(final Player player) {
|
||||
return hidden || !player.canSee(getBase());
|
||||
}
|
||||
|
||||
//Returns true if status expired during this check
|
||||
public boolean checkJailTimeout(final long currentTime) {
|
||||
if (getJailTimeout() > 0 && getJailTimeout() < currentTime && isJailed()) {
|
||||
@@ -546,14 +602,12 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
sendMessage(tl("haveBeenReleased"));
|
||||
setJail(null);
|
||||
if (ess.getSettings().isTeleportBackWhenFreedFromJail()) {
|
||||
try {
|
||||
getTeleport().back();
|
||||
} catch (Exception ex) {
|
||||
try {
|
||||
getTeleport().respawn(null, TeleportCause.PLUGIN);
|
||||
} catch (Exception ex1) {
|
||||
}
|
||||
}
|
||||
final CompletableFuture<Boolean> future = new CompletableFuture<>();
|
||||
getAsyncTeleport().back(future);
|
||||
future.exceptionally(e -> {
|
||||
getAsyncTeleport().respawn(null, TeleportCause.PLUGIN, new CompletableFuture<>());
|
||||
return false;
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -564,9 +618,9 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
//Returns true if status expired during this check
|
||||
public boolean checkMuteTimeout(final long currentTime) {
|
||||
if (getMuteTimeout() > 0 && getMuteTimeout() < currentTime && isMuted()) {
|
||||
final MuteStatusChangeEvent event = new MuteStatusChangeEvent(this, null, false);
|
||||
final MuteStatusChangeEvent event = new MuteStatusChangeEvent(this, null, false, getMuteTimeout(), getMuteReason());
|
||||
ess.getServer().getPluginManager().callEvent(event);
|
||||
|
||||
|
||||
if (!event.isCancelled()) {
|
||||
setMuteTimeout(0);
|
||||
sendMessage(tl("canTalkAgain"));
|
||||
@@ -578,14 +632,24 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
return false;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void updateActivity(final boolean broadcast) {
|
||||
updateActivity(broadcast, AfkStatusChangeEvent.Cause.UNKNOWN);
|
||||
}
|
||||
|
||||
public void updateActivity(final boolean broadcast, final AfkStatusChangeEvent.Cause cause) {
|
||||
if (isAfk()) {
|
||||
setAfk(false);
|
||||
setAfk(false, cause);
|
||||
if (broadcast && !isHidden()) {
|
||||
setDisplayNick();
|
||||
final String msg = tl("userIsNotAway", getDisplayName());
|
||||
if (!msg.isEmpty()) {
|
||||
ess.broadcastMessage(this, msg);
|
||||
final String selfmsg = tl("userIsNotAwaySelf", getDisplayName());
|
||||
if (!msg.isEmpty() && ess.getSettings().broadcastAfkMessage()) {
|
||||
// exclude user from receiving general AFK announcement in favor of personal message
|
||||
ess.broadcastMessage(this, msg, u -> u == this);
|
||||
}
|
||||
if (!selfmsg.isEmpty()) {
|
||||
this.sendMessage(selfmsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -593,14 +657,14 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
}
|
||||
|
||||
public void updateActivityOnMove(final boolean broadcast) {
|
||||
if(ess.getSettings().cancelAfkOnMove()) {
|
||||
updateActivity(broadcast);
|
||||
if (ess.getSettings().cancelAfkOnMove()) {
|
||||
updateActivity(broadcast, AfkStatusChangeEvent.Cause.MOVE);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateActivityOnInteract(final boolean broadcast) {
|
||||
if(ess.getSettings().cancelAfkOnInteract()) {
|
||||
updateActivity(broadcast);
|
||||
if (ess.getSettings().cancelAfkOnInteract()) {
|
||||
updateActivity(broadcast, AfkStatusChangeEvent.Cause.INTERACT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -619,8 +683,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
lastActivity = 0;
|
||||
this.getBase().kickPlayer(kickReason);
|
||||
|
||||
|
||||
for (User user : ess.getOnlineUsers()) {
|
||||
for (final User user : ess.getOnlineUsers()) {
|
||||
if (user.isAuthorized("essentials.kick.notify")) {
|
||||
user.sendMessage(tl("playerKicked", Console.NAME, getName(), kickReason));
|
||||
}
|
||||
@@ -628,12 +691,17 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
}
|
||||
final long autoafk = ess.getSettings().getAutoAfk();
|
||||
if (!isAfk() && autoafk > 0 && lastActivity + autoafk * 1000 < System.currentTimeMillis() && isAuthorized("essentials.afk.auto")) {
|
||||
setAfk(true);
|
||||
setAfk(true, AfkStatusChangeEvent.Cause.ACTIVITY);
|
||||
if (!isHidden()) {
|
||||
setDisplayNick();
|
||||
final String msg = tl("userIsAway", getDisplayName());
|
||||
if (!msg.isEmpty()) {
|
||||
ess.broadcastMessage(this, msg);
|
||||
final String selfmsg = tl("userIsAwaySelf", getDisplayName());
|
||||
if (!msg.isEmpty() && ess.getSettings().broadcastAfkMessage()) {
|
||||
// exclude user from receiving general AFK announcement in favor of personal message
|
||||
ess.broadcastMessage(this, msg, u -> u == this);
|
||||
}
|
||||
if (!selfmsg.isEmpty()) {
|
||||
this.sendMessage(selfmsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -655,9 +723,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
}
|
||||
if (isAfk()) {
|
||||
// Protect AFK players by representing them in a god mode state to render them invulnerable to damage.
|
||||
if (ess.getSettings().getFreezeAfkPlayers()) {
|
||||
return true;
|
||||
}
|
||||
return ess.getSettings().getFreezeAfkPlayers();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -742,7 +808,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIgnoreMsg(boolean ignoreMsg) {
|
||||
public void setIgnoreMsg(final boolean ignoreMsg) {
|
||||
this.ignoreMsg = ignoreMsg;
|
||||
}
|
||||
|
||||
@@ -755,7 +821,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
public void setVanished(final boolean set) {
|
||||
vanished = set;
|
||||
if (set) {
|
||||
for (User user : ess.getOnlineUsers()) {
|
||||
for (final User user : ess.getOnlineUsers()) {
|
||||
if (!user.isAuthorized("essentials.vanish.see")) {
|
||||
user.getBase().hidePlayer(getBase());
|
||||
}
|
||||
@@ -766,7 +832,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
this.getBase().addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, Integer.MAX_VALUE, 1, false));
|
||||
}
|
||||
} else {
|
||||
for (Player p : ess.getOnlinePlayers()) {
|
||||
for (final Player p : ess.getOnlinePlayers()) {
|
||||
p.showPlayer(getBase());
|
||||
}
|
||||
setHidden(false);
|
||||
@@ -787,7 +853,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
|
||||
public boolean isSignThrottled() {
|
||||
final long minTime = lastThrottledAction + (1000 / ess.getSettings().getSignUsePerSecond());
|
||||
return (System.currentTimeMillis() < minTime);
|
||||
return System.currentTimeMillis() < minTime;
|
||||
}
|
||||
|
||||
public void updateThrottle() {
|
||||
@@ -798,7 +864,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
return rightClickJump;
|
||||
}
|
||||
|
||||
public void setRightClickJump(boolean rightClickJump) {
|
||||
public void setRightClickJump(final boolean rightClickJump) {
|
||||
this.rightClickJump = rightClickJump;
|
||||
}
|
||||
|
||||
@@ -811,12 +877,12 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
return recipeSee;
|
||||
}
|
||||
|
||||
public void setRecipeSee(boolean recipeSee) {
|
||||
public void setRecipeSee(final boolean recipeSee) {
|
||||
this.recipeSee = recipeSee;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(String message) {
|
||||
public void sendMessage(final String message) {
|
||||
if (!message.isEmpty()) {
|
||||
base.sendMessage(message);
|
||||
}
|
||||
@@ -850,24 +916,29 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
public String getName() {
|
||||
return this.getBase().getName();
|
||||
}
|
||||
|
||||
@Override public boolean isReachable() {
|
||||
|
||||
@Override
|
||||
public boolean isReachable() {
|
||||
return getBase().isOnline();
|
||||
}
|
||||
|
||||
@Override public MessageResponse sendMessage(IMessageRecipient recipient, String message) {
|
||||
@Override
|
||||
public MessageResponse sendMessage(final IMessageRecipient recipient, final String message) {
|
||||
return this.messageRecipient.sendMessage(recipient, message);
|
||||
}
|
||||
|
||||
@Override public MessageResponse onReceiveMessage(IMessageRecipient sender, String message) {
|
||||
@Override
|
||||
public MessageResponse onReceiveMessage(final IMessageRecipient sender, final String message) {
|
||||
return this.messageRecipient.onReceiveMessage(sender, message);
|
||||
}
|
||||
|
||||
@Override public IMessageRecipient getReplyRecipient() {
|
||||
@Override
|
||||
public IMessageRecipient getReplyRecipient() {
|
||||
return this.messageRecipient.getReplyRecipient();
|
||||
}
|
||||
|
||||
@Override public void setReplyRecipient(IMessageRecipient recipient) {
|
||||
@Override
|
||||
public void setReplyRecipient(final IMessageRecipient recipient) {
|
||||
this.messageRecipient.setReplyRecipient(recipient);
|
||||
}
|
||||
|
||||
@@ -877,7 +948,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAfkMessage(String message) {
|
||||
public void setAfkMessage(final String message) {
|
||||
if (isAfk()) {
|
||||
this.afkMessage = message;
|
||||
}
|
||||
@@ -896,8 +967,8 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
public String getConfirmingClearCommand() {
|
||||
return confirmingClearCommand;
|
||||
}
|
||||
|
||||
public void setConfirmingClearCommand(String command) {
|
||||
|
||||
public void setConfirmingClearCommand(final String command) {
|
||||
this.confirmingClearCommand = command;
|
||||
}
|
||||
|
||||
@@ -908,19 +979,44 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_9_R01)) {
|
||||
return getBase().getInventory().getItemInHand();
|
||||
} else {
|
||||
PlayerInventory inventory = getBase().getInventory();
|
||||
final PlayerInventory inventory = getBase().getInventory();
|
||||
return inventory.getItemInMainHand() != null ? inventory.getItemInMainHand() : inventory.getItemInOffHand();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void notifyOfMail() {
|
||||
List<String> mails = getMails();
|
||||
final List<String> mails = getMails();
|
||||
if (mails != null && !mails.isEmpty()) {
|
||||
int notifyPlayerOfMailCooldown = ess.getSettings().getNotifyPlayerOfMailCooldown() * 1000;
|
||||
final int notifyPlayerOfMailCooldown = ess.getSettings().getNotifyPlayerOfMailCooldown() * 1000;
|
||||
if (System.currentTimeMillis() - lastNotifiedAboutMailsMs >= notifyPlayerOfMailCooldown) {
|
||||
sendMessage(tl("youHaveNewMail", mails.size()));
|
||||
lastNotifiedAboutMailsMs = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getLastHomeConfirmation() {
|
||||
return lastHomeConfirmation;
|
||||
}
|
||||
|
||||
public void setLastHomeConfirmation(final String lastHomeConfirmation) {
|
||||
this.lastHomeConfirmation = lastHomeConfirmation;
|
||||
}
|
||||
|
||||
public long getLastHomeConfirmationTimestamp() {
|
||||
return lastHomeConfirmationTimestamp;
|
||||
}
|
||||
|
||||
public void setLastHomeConfirmationTimestamp() {
|
||||
this.lastHomeConfirmationTimestamp = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getTargetBlock(int maxDistance) {
|
||||
final Block block;
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_13_2_R01) || (block = base.getTargetBlockExact(maxDistance)) == null) {
|
||||
return base.getTargetBlock(null, maxDistance);
|
||||
}
|
||||
return block;
|
||||
}
|
||||
}
|
||||
@@ -14,22 +14,67 @@ import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.io.File;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public abstract class UserData extends PlayerExtension implements IConf {
|
||||
protected final transient IEssentials ess;
|
||||
private final EssentialsUserConf config;
|
||||
private final File folder;
|
||||
private BigDecimal money;
|
||||
private Map<String, Object> homes;
|
||||
private String nickname;
|
||||
private Set<Material> unlimited;
|
||||
private Map<String, Object> powertools;
|
||||
private Location lastLocation;
|
||||
private Location logoutLocation;
|
||||
private long lastTeleportTimestamp;
|
||||
private long lastHealTimestamp;
|
||||
private String jail;
|
||||
private List<String> mails;
|
||||
private boolean teleportEnabled;
|
||||
private boolean autoTeleportEnabled;
|
||||
private List<UUID> ignoredPlayers;
|
||||
private boolean godmode;
|
||||
private boolean muted;
|
||||
private String muteReason;
|
||||
private long muteTimeout;
|
||||
private boolean jailed;
|
||||
private long jailTimeout;
|
||||
private long lastLogin;
|
||||
private long lastLogout;
|
||||
private String lastLoginAddress;
|
||||
private boolean afk;
|
||||
private boolean newplayer;
|
||||
private String geolocation;
|
||||
private boolean isSocialSpyEnabled;
|
||||
private boolean isNPC;
|
||||
private String lastAccountName = null;
|
||||
private boolean arePowerToolsEnabled;
|
||||
private Map<String, Long> kitTimestamps;
|
||||
// Pattern, Date. Pattern for less pattern creations
|
||||
private Map<Pattern, Long> commandCooldowns;
|
||||
private boolean acceptingPay = true; // players accept pay by default
|
||||
private Boolean confirmPay;
|
||||
private Boolean confirmClear;
|
||||
private boolean lastMessageReplyRecipient;
|
||||
|
||||
protected UserData(Player base, IEssentials ess) {
|
||||
protected UserData(final Player base, final IEssentials ess) {
|
||||
super(base);
|
||||
this.ess = ess;
|
||||
folder = new File(ess.getDataFolder(), "userdata");
|
||||
final File folder = new File(ess.getDataFolder(), "userdata");
|
||||
if (!folder.exists()) {
|
||||
folder.mkdirs();
|
||||
}
|
||||
@@ -37,7 +82,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
String filename;
|
||||
try {
|
||||
filename = base.getUniqueId().toString();
|
||||
} catch (Throwable ex) {
|
||||
} catch (final Throwable ex) {
|
||||
ess.getLogger().warning("Falling back to old username system for " + base.getName());
|
||||
filename = base.getName();
|
||||
}
|
||||
@@ -97,12 +142,10 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
lastMessageReplyRecipient = _getLastMessageReplyRecipient();
|
||||
}
|
||||
|
||||
private BigDecimal money;
|
||||
|
||||
private BigDecimal _getMoney() {
|
||||
BigDecimal result = ess.getSettings().getStartingBalance();
|
||||
BigDecimal maxMoney = ess.getSettings().getMaxMoney();
|
||||
BigDecimal minMoney = ess.getSettings().getMinMoney();
|
||||
final BigDecimal maxMoney = ess.getSettings().getMaxMoney();
|
||||
final BigDecimal minMoney = ess.getSettings().getMinMoney();
|
||||
|
||||
// NPC banks are not actual player banks, as such they do not have player starting balance.
|
||||
if (isNPC()) {
|
||||
@@ -125,9 +168,9 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return money;
|
||||
}
|
||||
|
||||
public void setMoney(BigDecimal value, boolean throwError) throws MaxMoneyException {
|
||||
BigDecimal maxMoney = ess.getSettings().getMaxMoney();
|
||||
BigDecimal minMoney = ess.getSettings().getMinMoney();
|
||||
public void setMoney(final BigDecimal value, final boolean throwError) throws MaxMoneyException {
|
||||
final BigDecimal maxMoney = ess.getSettings().getMaxMoney();
|
||||
final BigDecimal minMoney = ess.getSettings().getMinMoney();
|
||||
if (value.compareTo(maxMoney) > 0) {
|
||||
if (throwError) {
|
||||
throw new MaxMoneyException();
|
||||
@@ -143,28 +186,25 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
stopTransaction();
|
||||
}
|
||||
|
||||
private Map<String, Object> homes;
|
||||
|
||||
private Map<String, Object> _getHomes() {
|
||||
if (config.isConfigurationSection("homes")) {
|
||||
return config.getConfigurationSection("homes").getValues(false);
|
||||
}
|
||||
return new HashMap<String, Object>();
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
private String getHomeName(String search) {
|
||||
if (NumberUtil.isInt(search)) {
|
||||
try {
|
||||
search = getHomes().get(Integer.parseInt(search) - 1);
|
||||
} catch (NumberFormatException e) {
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
} catch (final NumberFormatException | IndexOutOfBoundsException ignored) {
|
||||
}
|
||||
}
|
||||
return search;
|
||||
}
|
||||
|
||||
public Location getHome(String name) throws Exception {
|
||||
String search = getHomeName(name);
|
||||
public Location getHome(final String name) throws Exception {
|
||||
final String search = getHomeName(name);
|
||||
return config.getLocation("homes." + search, this.getBase().getServer());
|
||||
}
|
||||
|
||||
@@ -174,7 +214,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return null;
|
||||
}
|
||||
Location loc;
|
||||
for (String home : getHomes()) {
|
||||
for (final String home : getHomes()) {
|
||||
loc = config.getLocation("homes." + home, this.getBase().getServer());
|
||||
if (world.getWorld() == loc.getWorld()) {
|
||||
return loc;
|
||||
@@ -183,16 +223,16 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
}
|
||||
loc = config.getLocation("homes." + getHomes().get(0), this.getBase().getServer());
|
||||
return loc;
|
||||
} catch (InvalidWorldException ex) {
|
||||
} catch (final InvalidWorldException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getHomes() {
|
||||
return new ArrayList<String>(homes.keySet());
|
||||
return new ArrayList<>(homes.keySet());
|
||||
}
|
||||
|
||||
public void setHome(String name, Location loc) {
|
||||
public void setHome(String name, final Location loc) {
|
||||
//Invalid names will corrupt the yaml
|
||||
name = StringUtil.safeString(name);
|
||||
homes.put(name, loc);
|
||||
@@ -200,7 +240,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
config.save();
|
||||
}
|
||||
|
||||
public void delHome(String name) throws Exception {
|
||||
public void delHome(final String name) throws Exception {
|
||||
String search = getHomeName(name);
|
||||
if (!homes.containsKey(search)) {
|
||||
search = StringUtil.safeString(search);
|
||||
@@ -218,7 +258,9 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return config.hasProperty("home");
|
||||
}
|
||||
|
||||
private String nickname;
|
||||
public boolean hasHome(final String name) {
|
||||
return config.hasProperty("homes." + name);
|
||||
}
|
||||
|
||||
public String _getNickname() {
|
||||
return config.getString("nickname");
|
||||
@@ -228,20 +270,18 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return nickname;
|
||||
}
|
||||
|
||||
public void setNickname(String nick) {
|
||||
public void setNickname(final String nick) {
|
||||
nickname = nick;
|
||||
config.setProperty("nickname", nick);
|
||||
config.save();
|
||||
}
|
||||
|
||||
private List<Material> unlimited;
|
||||
|
||||
private List<Material> _getUnlimited() {
|
||||
List<Material> retlist = new ArrayList<>();
|
||||
List<String> configList = config.getStringList("unlimited");
|
||||
for(String s : configList) {
|
||||
Material mat = Material.matchMaterial(s);
|
||||
if(mat != null) {
|
||||
private Set<Material> _getUnlimited() {
|
||||
final Set<Material> retlist = new HashSet<>();
|
||||
final List<String> configList = config.getStringList("unlimited");
|
||||
for (final String s : configList) {
|
||||
final Material mat = Material.matchMaterial(s);
|
||||
if (mat != null) {
|
||||
retlist.add(mat);
|
||||
}
|
||||
}
|
||||
@@ -249,26 +289,31 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return retlist;
|
||||
}
|
||||
|
||||
public List<Material> getUnlimited() {
|
||||
public Set<Material> getUnlimited() {
|
||||
return unlimited;
|
||||
}
|
||||
|
||||
public boolean hasUnlimited(ItemStack stack) {
|
||||
public boolean hasUnlimited(final ItemStack stack) {
|
||||
return unlimited.contains(stack.getType());
|
||||
}
|
||||
|
||||
public void setUnlimited(ItemStack stack, boolean state) {
|
||||
if (unlimited.contains(stack.getType())) {
|
||||
unlimited.remove(stack.getType());
|
||||
}
|
||||
public void setUnlimited(final ItemStack stack, final boolean state) {
|
||||
final boolean wasUpdated;
|
||||
if (state) {
|
||||
unlimited.add(stack.getType());
|
||||
wasUpdated = unlimited.add(stack.getType());
|
||||
} else {
|
||||
wasUpdated = unlimited.remove(stack.getType());
|
||||
}
|
||||
|
||||
if (wasUpdated) {
|
||||
applyUnlimited();
|
||||
}
|
||||
config.setProperty("unlimited", unlimited);
|
||||
config.save();
|
||||
}
|
||||
|
||||
private Map<String, Object> powertools;
|
||||
private void applyUnlimited() {
|
||||
config.setProperty("unlimited", unlimited.stream().map(Enum::name).collect(Collectors.toList()));
|
||||
config.save();
|
||||
}
|
||||
|
||||
private Map<String, Object> _getPowertools() {
|
||||
if (config.isConfigurationSection("powertools")) {
|
||||
@@ -284,16 +329,16 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<String> getPowertool(ItemStack stack) {
|
||||
public List<String> getPowertool(final ItemStack stack) {
|
||||
return (List<String>) powertools.get(stack.getType().name().toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<String> getPowertool(Material material) {
|
||||
public List<String> getPowertool(final Material material) {
|
||||
return (List<String>) powertools.get(material.name().toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
|
||||
public void setPowertool(ItemStack stack, List<String> commandList) {
|
||||
public void setPowertool(final ItemStack stack, final List<String> commandList) {
|
||||
if (commandList == null || commandList.isEmpty()) {
|
||||
powertools.remove(stack.getType().name().toLowerCase(Locale.ENGLISH));
|
||||
} else {
|
||||
@@ -307,12 +352,10 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return !powertools.isEmpty();
|
||||
}
|
||||
|
||||
private Location lastLocation;
|
||||
|
||||
private Location _getLastLocation() {
|
||||
try {
|
||||
return config.getLocation("lastlocation", this.getBase().getServer());
|
||||
} catch (InvalidWorldException e) {
|
||||
} catch (final InvalidWorldException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -321,7 +364,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return lastLocation;
|
||||
}
|
||||
|
||||
public void setLastLocation(Location loc) {
|
||||
public void setLastLocation(final Location loc) {
|
||||
if (loc == null || loc.getWorld() == null) {
|
||||
return;
|
||||
}
|
||||
@@ -330,12 +373,10 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
config.save();
|
||||
}
|
||||
|
||||
private Location logoutLocation;
|
||||
|
||||
private Location _getLogoutLocation() {
|
||||
try {
|
||||
return config.getLocation("logoutlocation", this.getBase().getServer());
|
||||
} catch (InvalidWorldException e) {
|
||||
} catch (final InvalidWorldException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -344,7 +385,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return logoutLocation;
|
||||
}
|
||||
|
||||
public void setLogoutLocation(Location loc) {
|
||||
public void setLogoutLocation(final Location loc) {
|
||||
if (loc == null || loc.getWorld() == null) {
|
||||
return;
|
||||
}
|
||||
@@ -353,8 +394,6 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
config.save();
|
||||
}
|
||||
|
||||
private long lastTeleportTimestamp;
|
||||
|
||||
private long _getLastTeleportTimestamp() {
|
||||
return config.getLong("timestamps.lastteleport", 0);
|
||||
}
|
||||
@@ -363,14 +402,12 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return lastTeleportTimestamp;
|
||||
}
|
||||
|
||||
public void setLastTeleportTimestamp(long time) {
|
||||
public void setLastTeleportTimestamp(final long time) {
|
||||
lastTeleportTimestamp = time;
|
||||
config.setProperty("timestamps.lastteleport", time);
|
||||
config.save();
|
||||
}
|
||||
|
||||
private long lastHealTimestamp;
|
||||
|
||||
private long _getLastHealTimestamp() {
|
||||
return config.getLong("timestamps.lastheal", 0);
|
||||
}
|
||||
@@ -379,14 +416,12 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return lastHealTimestamp;
|
||||
}
|
||||
|
||||
public void setLastHealTimestamp(long time) {
|
||||
public void setLastHealTimestamp(final long time) {
|
||||
lastHealTimestamp = time;
|
||||
config.setProperty("timestamps.lastheal", time);
|
||||
config.save();
|
||||
}
|
||||
|
||||
private String jail;
|
||||
|
||||
private String _getJail() {
|
||||
return config.getString("jail");
|
||||
}
|
||||
@@ -395,7 +430,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return jail;
|
||||
}
|
||||
|
||||
public void setJail(String jail) {
|
||||
public void setJail(final String jail) {
|
||||
if (jail == null || jail.isEmpty()) {
|
||||
this.jail = null;
|
||||
config.removeProperty("jail");
|
||||
@@ -406,8 +441,6 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
config.save();
|
||||
}
|
||||
|
||||
private List<String> mails;
|
||||
|
||||
private List<String> _getMails() {
|
||||
return config.getStringList("mail");
|
||||
}
|
||||
@@ -427,13 +460,11 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
config.save();
|
||||
}
|
||||
|
||||
public void addMail(String mail) {
|
||||
public void addMail(final String mail) {
|
||||
mails.add(mail);
|
||||
setMails(mails);
|
||||
}
|
||||
|
||||
private boolean teleportEnabled;
|
||||
|
||||
private boolean _getTeleportEnabled() {
|
||||
return config.getBoolean("teleportenabled", true);
|
||||
}
|
||||
@@ -442,14 +473,12 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return teleportEnabled;
|
||||
}
|
||||
|
||||
public void setTeleportEnabled(boolean set) {
|
||||
public void setTeleportEnabled(final boolean set) {
|
||||
teleportEnabled = set;
|
||||
config.setProperty("teleportenabled", set);
|
||||
config.save();
|
||||
}
|
||||
|
||||
private boolean autoTeleportEnabled;
|
||||
|
||||
private boolean _getAutoTeleportEnabled() {
|
||||
return config.getBoolean("teleportauto", false);
|
||||
}
|
||||
@@ -458,25 +487,47 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return autoTeleportEnabled;
|
||||
}
|
||||
|
||||
public void setAutoTeleportEnabled(boolean set) {
|
||||
public void setAutoTeleportEnabled(final boolean set) {
|
||||
autoTeleportEnabled = set;
|
||||
config.setProperty("teleportauto", set);
|
||||
config.save();
|
||||
}
|
||||
|
||||
private List<String> ignoredPlayers;
|
||||
|
||||
public List<String> _getIgnoredPlayers() {
|
||||
return Collections.synchronizedList(config.getStringList("ignore"));
|
||||
public List<UUID> _getIgnoredPlayers() {
|
||||
final List<UUID> players = new ArrayList<>();
|
||||
for (final String uuid : config.getStringList("ignore")) {
|
||||
try {
|
||||
players.add(UUID.fromString(uuid));
|
||||
} catch (final IllegalArgumentException ignored) {
|
||||
}
|
||||
}
|
||||
return Collections.synchronizedList(players);
|
||||
}
|
||||
|
||||
public void setIgnoredPlayers(List<String> players) {
|
||||
@Deprecated
|
||||
public void setIgnoredPlayers(final List<String> players) {
|
||||
final List<UUID> uuids = new ArrayList<>();
|
||||
for (final String player : players) {
|
||||
final User user = ess.getOfflineUser(player);
|
||||
if (user == null) {
|
||||
return;
|
||||
}
|
||||
uuids.add(user.getBase().getUniqueId());
|
||||
}
|
||||
setIgnoredPlayerUUIDs(uuids);
|
||||
}
|
||||
|
||||
public void setIgnoredPlayerUUIDs(final List<UUID> players) {
|
||||
if (players == null || players.isEmpty()) {
|
||||
ignoredPlayers = Collections.synchronizedList(new ArrayList<String>());
|
||||
ignoredPlayers = Collections.synchronizedList(new ArrayList<>());
|
||||
config.removeProperty("ignore");
|
||||
} else {
|
||||
ignoredPlayers = players;
|
||||
config.setProperty("ignore", players);
|
||||
final List<String> uuids = new ArrayList<>();
|
||||
for (final UUID uuid : players) {
|
||||
uuids.add(uuid.toString());
|
||||
}
|
||||
config.setProperty("ignore", uuids);
|
||||
}
|
||||
config.save();
|
||||
}
|
||||
@@ -490,22 +541,22 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return isIgnoredPlayer(user);
|
||||
}
|
||||
|
||||
public boolean isIgnoredPlayer(IUser user) {
|
||||
return (ignoredPlayers.contains(user.getName().toLowerCase(Locale.ENGLISH)) && !user.isIgnoreExempt());
|
||||
public boolean isIgnoredPlayer(final IUser user) {
|
||||
return ignoredPlayers.contains(user.getBase().getUniqueId()) && !user.isIgnoreExempt();
|
||||
}
|
||||
|
||||
public void setIgnoredPlayer(IUser user, boolean set) {
|
||||
final String entry = user.getName().toLowerCase(Locale.ENGLISH);
|
||||
public void setIgnoredPlayer(final IUser user, final boolean set) {
|
||||
final UUID uuid = user.getBase().getUniqueId();
|
||||
if (set) {
|
||||
if (!ignoredPlayers.contains(entry)) ignoredPlayers.add(entry);
|
||||
if (!ignoredPlayers.contains(uuid)) {
|
||||
ignoredPlayers.add(uuid);
|
||||
}
|
||||
} else {
|
||||
ignoredPlayers.remove(entry);
|
||||
ignoredPlayers.remove(uuid);
|
||||
}
|
||||
setIgnoredPlayers(ignoredPlayers);
|
||||
setIgnoredPlayerUUIDs(ignoredPlayers);
|
||||
}
|
||||
|
||||
private boolean godmode;
|
||||
|
||||
private boolean _getGodModeEnabled() {
|
||||
return config.getBoolean("godmode", false);
|
||||
}
|
||||
@@ -514,15 +565,12 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return godmode;
|
||||
}
|
||||
|
||||
public void setGodModeEnabled(boolean set) {
|
||||
public void setGodModeEnabled(final boolean set) {
|
||||
godmode = set;
|
||||
config.setProperty("godmode", set);
|
||||
config.save();
|
||||
}
|
||||
|
||||
private boolean muted;
|
||||
private String muteReason;
|
||||
|
||||
public boolean _getMuted() {
|
||||
return config.getBoolean("muted", false);
|
||||
}
|
||||
@@ -535,7 +583,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return muted;
|
||||
}
|
||||
|
||||
public void setMuted(boolean set) {
|
||||
public void setMuted(final boolean set) {
|
||||
muted = set;
|
||||
config.setProperty("muted", set);
|
||||
config.save();
|
||||
@@ -549,7 +597,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return muteReason;
|
||||
}
|
||||
|
||||
public void setMuteReason(String reason) {
|
||||
public void setMuteReason(final String reason) {
|
||||
if (reason == null) {
|
||||
config.removeProperty("muteReason");
|
||||
muteReason = null;
|
||||
@@ -560,12 +608,10 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
config.save();
|
||||
}
|
||||
|
||||
public boolean hasMuteReason(){
|
||||
public boolean hasMuteReason() {
|
||||
return muteReason != null;
|
||||
}
|
||||
|
||||
private long muteTimeout;
|
||||
|
||||
private long _getMuteTimeout() {
|
||||
return config.getLong("timestamps.mute", 0);
|
||||
}
|
||||
@@ -574,14 +620,12 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return muteTimeout;
|
||||
}
|
||||
|
||||
public void setMuteTimeout(long time) {
|
||||
public void setMuteTimeout(final long time) {
|
||||
muteTimeout = time;
|
||||
config.setProperty("timestamps.mute", time);
|
||||
config.save();
|
||||
}
|
||||
|
||||
private boolean jailed;
|
||||
|
||||
private boolean _getJailed() {
|
||||
return config.getBoolean("jailed", false);
|
||||
}
|
||||
@@ -590,20 +634,18 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return jailed;
|
||||
}
|
||||
|
||||
public void setJailed(boolean set) {
|
||||
public void setJailed(final boolean set) {
|
||||
jailed = set;
|
||||
config.setProperty("jailed", set);
|
||||
config.save();
|
||||
}
|
||||
|
||||
public boolean toggleJailed() {
|
||||
boolean ret = !isJailed();
|
||||
final boolean ret = !isJailed();
|
||||
setJailed(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
private long jailTimeout;
|
||||
|
||||
private long _getJailTimeout() {
|
||||
return config.getLong("timestamps.jail", 0);
|
||||
}
|
||||
@@ -612,14 +654,12 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return jailTimeout;
|
||||
}
|
||||
|
||||
public void setJailTimeout(long time) {
|
||||
public void setJailTimeout(final long time) {
|
||||
jailTimeout = time;
|
||||
config.setProperty("timestamps.jail", time);
|
||||
config.save();
|
||||
}
|
||||
|
||||
private long lastLogin;
|
||||
|
||||
private long _getLastLogin() {
|
||||
return config.getLong("timestamps.login", 0);
|
||||
}
|
||||
@@ -628,12 +668,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return lastLogin;
|
||||
}
|
||||
|
||||
private void _setLastLogin(long time) {
|
||||
lastLogin = time;
|
||||
config.setProperty("timestamps.login", time);
|
||||
}
|
||||
|
||||
public void setLastLogin(long time) {
|
||||
public void setLastLogin(final long time) {
|
||||
_setLastLogin(time);
|
||||
if (base.getAddress() != null && base.getAddress().getAddress() != null) {
|
||||
_setLastLoginAddress(base.getAddress().getAddress().getHostAddress());
|
||||
@@ -641,7 +676,10 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
config.save();
|
||||
}
|
||||
|
||||
private long lastLogout;
|
||||
private void _setLastLogin(final long time) {
|
||||
lastLogin = time;
|
||||
config.setProperty("timestamps.login", time);
|
||||
}
|
||||
|
||||
private long _getLastLogout() {
|
||||
return config.getLong("timestamps.logout", 0);
|
||||
@@ -651,14 +689,12 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return lastLogout;
|
||||
}
|
||||
|
||||
public void setLastLogout(long time) {
|
||||
public void setLastLogout(final long time) {
|
||||
lastLogout = time;
|
||||
config.setProperty("timestamps.logout", time);
|
||||
config.save();
|
||||
}
|
||||
|
||||
private String lastLoginAddress;
|
||||
|
||||
private String _getLastLoginAddress() {
|
||||
return config.getString("ipAddress", "");
|
||||
}
|
||||
@@ -667,13 +703,11 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return lastLoginAddress;
|
||||
}
|
||||
|
||||
private void _setLastLoginAddress(String address) {
|
||||
private void _setLastLoginAddress(final String address) {
|
||||
lastLoginAddress = address;
|
||||
config.setProperty("ipAddress", address);
|
||||
}
|
||||
|
||||
private boolean afk;
|
||||
|
||||
private boolean _getAfk() {
|
||||
return config.getBoolean("afk", false);
|
||||
}
|
||||
@@ -682,15 +716,12 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return afk;
|
||||
}
|
||||
|
||||
public void _setAfk(boolean set) {
|
||||
public void _setAfk(final boolean set) {
|
||||
afk = set;
|
||||
config.setProperty("afk", set);
|
||||
config.save();
|
||||
}
|
||||
|
||||
private boolean newplayer;
|
||||
private String geolocation;
|
||||
|
||||
private String _getGeoLocation() {
|
||||
return config.getString("geolocation");
|
||||
}
|
||||
@@ -699,7 +730,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return geolocation;
|
||||
}
|
||||
|
||||
public void setGeoLocation(String geolocation) {
|
||||
public void setGeoLocation(final String geolocation) {
|
||||
if (geolocation == null || geolocation.isEmpty()) {
|
||||
this.geolocation = null;
|
||||
config.removeProperty("geolocation");
|
||||
@@ -710,8 +741,6 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
config.save();
|
||||
}
|
||||
|
||||
private boolean isSocialSpyEnabled;
|
||||
|
||||
private boolean _isSocialSpyEnabled() {
|
||||
return config.getBoolean("socialspy", false);
|
||||
}
|
||||
@@ -720,14 +749,12 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return isSocialSpyEnabled;
|
||||
}
|
||||
|
||||
public void setSocialSpyEnabled(boolean status) {
|
||||
public void setSocialSpyEnabled(final boolean status) {
|
||||
isSocialSpyEnabled = status;
|
||||
config.setProperty("socialspy", status);
|
||||
config.save();
|
||||
}
|
||||
|
||||
private boolean isNPC;
|
||||
|
||||
private boolean _isNPC() {
|
||||
return config.getBoolean("npc", false);
|
||||
}
|
||||
@@ -736,43 +763,39 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return isNPC;
|
||||
}
|
||||
|
||||
private String lastAccountName = null;
|
||||
public void setNPC(final boolean set) {
|
||||
isNPC = set;
|
||||
config.setProperty("npc", set);
|
||||
config.save();
|
||||
}
|
||||
|
||||
public String getLastAccountName() {
|
||||
return lastAccountName;
|
||||
}
|
||||
|
||||
public String _getLastAccountName() {
|
||||
return config.getString("lastAccountName", null);
|
||||
}
|
||||
|
||||
public void setLastAccountName(String lastAccountName) {
|
||||
public void setLastAccountName(final String lastAccountName) {
|
||||
this.lastAccountName = lastAccountName;
|
||||
config.setProperty("lastAccountName", lastAccountName);
|
||||
config.save();
|
||||
ess.getUserMap().trackUUID(getConfigUUID(), lastAccountName, true);
|
||||
}
|
||||
|
||||
public void setNPC(boolean set) {
|
||||
isNPC = set;
|
||||
config.setProperty("npc", set);
|
||||
config.save();
|
||||
public String _getLastAccountName() {
|
||||
return config.getString("lastAccountName", null);
|
||||
}
|
||||
|
||||
private boolean arePowerToolsEnabled;
|
||||
|
||||
public boolean arePowerToolsEnabled() {
|
||||
return arePowerToolsEnabled;
|
||||
}
|
||||
|
||||
public void setPowerToolsEnabled(boolean set) {
|
||||
public void setPowerToolsEnabled(final boolean set) {
|
||||
arePowerToolsEnabled = set;
|
||||
config.setProperty("powertoolsenabled", set);
|
||||
config.save();
|
||||
}
|
||||
|
||||
public boolean togglePowerToolsEnabled() {
|
||||
boolean ret = !arePowerToolsEnabled();
|
||||
final boolean ret = !arePowerToolsEnabled();
|
||||
setPowerToolsEnabled(ret);
|
||||
return ret;
|
||||
}
|
||||
@@ -781,14 +804,12 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return config.getBoolean("powertoolsenabled", true);
|
||||
}
|
||||
|
||||
private Map<String, Long> kitTimestamps;
|
||||
|
||||
private Map<String, Long> _getKitTimestamps() {
|
||||
|
||||
if (config.isConfigurationSection("timestamps.kits")) {
|
||||
final ConfigurationSection section = config.getConfigurationSection("timestamps.kits");
|
||||
final Map<String, Long> timestamps = new HashMap<String, Long>();
|
||||
for (String command : section.getKeys(false)) {
|
||||
final Map<String, Long> timestamps = new HashMap<>();
|
||||
for (final String command : section.getKeys(false)) {
|
||||
if (section.isLong(command)) {
|
||||
timestamps.put(command.toLowerCase(Locale.ENGLISH), section.getLong(command));
|
||||
} else if (section.isInt(command)) {
|
||||
@@ -797,7 +818,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
}
|
||||
return timestamps;
|
||||
}
|
||||
return new HashMap<String, Long>();
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
public long getKitTimestamp(String name) {
|
||||
@@ -815,7 +836,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
config.save();
|
||||
}
|
||||
|
||||
public void setConfigProperty(String node, Object object) {
|
||||
public void setConfigProperty(String node, final Object object) {
|
||||
final String prefix = "info.";
|
||||
node = prefix + node;
|
||||
if (object instanceof Map) {
|
||||
@@ -836,37 +857,34 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
if (config.isConfigurationSection("info")) {
|
||||
return config.getConfigurationSection("info").getKeys(true);
|
||||
}
|
||||
return new HashSet<String>();
|
||||
return new HashSet<>();
|
||||
}
|
||||
|
||||
public Map<String, Object> getConfigMap() {
|
||||
if (config.isConfigurationSection("info")) {
|
||||
return config.getConfigurationSection("info").getValues(true);
|
||||
}
|
||||
return new HashMap<String, Object>();
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
public Map<String, Object> getConfigMap(String node) {
|
||||
public Map<String, Object> getConfigMap(final String node) {
|
||||
if (config.isConfigurationSection("info." + node)) {
|
||||
return config.getConfigurationSection("info." + node).getValues(true);
|
||||
}
|
||||
return new HashMap<String, Object>();
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
// Pattern, Date. Pattern for less pattern creations
|
||||
private Map<Pattern, Long> commandCooldowns;
|
||||
|
||||
private Map<Pattern, Long> _getCommandCooldowns() {
|
||||
if (!config.isConfigurationSection("timestamps.command-cooldowns")) {
|
||||
if (!config.contains("timestamps.command-cooldowns")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// See saveCommandCooldowns() for deserialization explanation
|
||||
List<Map<?, ?>> section = config.getMapList("timestamps.command-cooldowns");
|
||||
HashMap<Pattern, Long> result = new HashMap<>();
|
||||
for (Map<?, ?> map : section) {
|
||||
Pattern pattern = Pattern.compile(map.get("pattern").toString());
|
||||
long expiry = ((Number) map.get("expiry")).longValue();
|
||||
final List<Map<?, ?>> section = config.getMapList("timestamps.command-cooldowns");
|
||||
final HashMap<Pattern, Long> result = new HashMap<>();
|
||||
for (final Map<?, ?> map : section) {
|
||||
final Pattern pattern = Pattern.compile(map.get("pattern").toString());
|
||||
final long expiry = ((Number) map.get("expiry")).longValue();
|
||||
result.put(pattern, expiry);
|
||||
}
|
||||
return result;
|
||||
@@ -879,9 +897,9 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return Collections.unmodifiableMap(this.commandCooldowns);
|
||||
}
|
||||
|
||||
public Date getCommandCooldownExpiry(String label) {
|
||||
public Date getCommandCooldownExpiry(final String label) {
|
||||
if (commandCooldowns != null) {
|
||||
for (Entry<Pattern, Long> entry : this.commandCooldowns.entrySet()) {
|
||||
for (final Entry<Pattern, Long> entry : this.commandCooldowns.entrySet()) {
|
||||
if (entry.getKey().matcher(label).matches()) {
|
||||
return new Date(entry.getValue());
|
||||
}
|
||||
@@ -890,7 +908,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addCommandCooldown(Pattern pattern, Date expiresAt, boolean save) {
|
||||
public void addCommandCooldown(final Pattern pattern, final Date expiresAt, final boolean save) {
|
||||
if (this.commandCooldowns == null) {
|
||||
this.commandCooldowns = new HashMap<>();
|
||||
}
|
||||
@@ -900,12 +918,12 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean clearCommandCooldown(Pattern pattern) {
|
||||
public boolean clearCommandCooldown(final Pattern pattern) {
|
||||
if (this.commandCooldowns == null) {
|
||||
return false; // false for no modification
|
||||
}
|
||||
|
||||
if(this.commandCooldowns.remove(pattern) != null) {
|
||||
if (this.commandCooldowns.remove(pattern) != null) {
|
||||
saveCommandCooldowns();
|
||||
return true;
|
||||
}
|
||||
@@ -919,14 +937,14 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
// When serializing patterns (which commonly include full stops .) Bukkit/Essentials config framework
|
||||
// interprets it as a path separator, thus it breaks up the regex into sub nodes causing invalid syntax.
|
||||
// Thus each command cooldown is instead stored as a Map of {pattern: .., expiry: ..} to work around this.
|
||||
List<Object> serialized = new ArrayList<>();
|
||||
for (Entry<Pattern, Long> entry : this.commandCooldowns.entrySet()) {
|
||||
final List<Object> serialized = new ArrayList<>();
|
||||
for (final Entry<Pattern, Long> entry : this.commandCooldowns.entrySet()) {
|
||||
// Don't save expired cooldowns
|
||||
if (entry.getValue() < System.currentTimeMillis()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Map<?, ?> map = ImmutableMap.builder()
|
||||
final Map<?, ?> map = ImmutableMap.builder()
|
||||
.put("pattern", entry.getKey().pattern())
|
||||
.put("expiry", entry.getValue())
|
||||
.build();
|
||||
@@ -936,8 +954,6 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
save();
|
||||
}
|
||||
|
||||
private boolean acceptingPay = true; // players accept pay by default
|
||||
|
||||
public boolean _getAcceptingPay() {
|
||||
return config.getBoolean("acceptingPay", true);
|
||||
}
|
||||
@@ -946,14 +962,12 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return acceptingPay;
|
||||
}
|
||||
|
||||
public void setAcceptingPay(boolean acceptingPay) {
|
||||
public void setAcceptingPay(final boolean acceptingPay) {
|
||||
this.acceptingPay = acceptingPay;
|
||||
config.setProperty("acceptingPay", acceptingPay);
|
||||
save();
|
||||
}
|
||||
|
||||
private Boolean confirmPay;
|
||||
|
||||
private Boolean _getConfirmPay() {
|
||||
return (Boolean) config.get("confirm-pay");
|
||||
}
|
||||
@@ -962,14 +976,12 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return confirmPay != null ? confirmPay : ess.getSettings().isConfirmCommandEnabledByDefault("pay");
|
||||
}
|
||||
|
||||
public void setPromptingPayConfirm(boolean prompt) {
|
||||
public void setPromptingPayConfirm(final boolean prompt) {
|
||||
this.confirmPay = prompt;
|
||||
config.setProperty("confirm-pay", prompt);
|
||||
save();
|
||||
}
|
||||
|
||||
private Boolean confirmClear;
|
||||
|
||||
private Boolean _getConfirmClear() {
|
||||
return (Boolean) config.get("confirm-clear");
|
||||
}
|
||||
@@ -978,14 +990,12 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return confirmClear != null ? confirmClear : ess.getSettings().isConfirmCommandEnabledByDefault("clearinventory");
|
||||
}
|
||||
|
||||
public void setPromptingClearConfirm(boolean prompt) {
|
||||
public void setPromptingClearConfirm(final boolean prompt) {
|
||||
this.confirmClear = prompt;
|
||||
config.setProperty("confirm-clear", prompt);
|
||||
save();
|
||||
}
|
||||
|
||||
private boolean lastMessageReplyRecipient;
|
||||
|
||||
private boolean _getLastMessageReplyRecipient() {
|
||||
return config.getBoolean("last-message-reply-recipient", ess.getSettings().isLastMessageReplyRecipient());
|
||||
}
|
||||
@@ -994,7 +1004,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return this.lastMessageReplyRecipient;
|
||||
}
|
||||
|
||||
public void setLastMessageReplyRecipient(boolean enabled) {
|
||||
public void setLastMessageReplyRecipient(final boolean enabled) {
|
||||
this.lastMessageReplyRecipient = enabled;
|
||||
config.setProperty("last-message-reply-recipient", enabled);
|
||||
save();
|
||||
|
||||
@@ -13,22 +13,26 @@ import org.bukkit.entity.Player;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentSkipListMap;
|
||||
import java.util.concurrent.ConcurrentSkipListSet;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
public class UserMap extends CacheLoader<String, User> implements IConf {
|
||||
private static boolean legacy = false;
|
||||
private static Method getLegacy;
|
||||
private final transient IEssentials ess;
|
||||
private final transient ConcurrentSkipListSet<UUID> keys = new ConcurrentSkipListSet<>();
|
||||
private final transient ConcurrentSkipListMap<String, UUID> names = new ConcurrentSkipListMap<>();
|
||||
private final transient ConcurrentSkipListMap<UUID, ArrayList<String>> history = new ConcurrentSkipListMap<>();
|
||||
private UUIDMap uuidMap;
|
||||
|
||||
private final UUIDMap uuidMap;
|
||||
private final transient Cache<String, User> users;
|
||||
private static boolean legacy = false;
|
||||
private final Pattern validUserPattern = Pattern.compile("^[a-zA-Z0-9_]{2,16}$");
|
||||
|
||||
public UserMap(final IEssentials ess) {
|
||||
super();
|
||||
@@ -36,11 +40,11 @@ public class UserMap extends CacheLoader<String, User> implements IConf {
|
||||
uuidMap = new UUIDMap(ess);
|
||||
//RemovalListener<UUID, User> remListener = new UserMapRemovalListener();
|
||||
//users = CacheBuilder.newBuilder().maximumSize(ess.getSettings().getMaxUserCacheCount()).softValues().removalListener(remListener).build(this);
|
||||
CacheBuilder<Object, Object> cacheBuilder = CacheBuilder.newBuilder();
|
||||
int maxCount = ess.getSettings().getMaxUserCacheCount();
|
||||
final CacheBuilder<Object, Object> cacheBuilder = CacheBuilder.newBuilder();
|
||||
final int maxCount = ess.getSettings().getMaxUserCacheCount();
|
||||
try {
|
||||
cacheBuilder.maximumSize(maxCount);
|
||||
} catch (NoSuchMethodError nsme) {
|
||||
} catch (final NoSuchMethodError nsme) {
|
||||
legacy = true;
|
||||
legacyMaximumSize(cacheBuilder, maxCount);
|
||||
}
|
||||
@@ -53,29 +57,26 @@ public class UserMap extends CacheLoader<String, User> implements IConf {
|
||||
}
|
||||
|
||||
private void loadAllUsersAsync(final IEssentials ess) {
|
||||
ess.runTaskAsynchronously(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (users) {
|
||||
final File userdir = new File(ess.getDataFolder(), "userdata");
|
||||
if (!userdir.exists()) {
|
||||
return;
|
||||
}
|
||||
keys.clear();
|
||||
users.invalidateAll();
|
||||
for (String string : userdir.list()) {
|
||||
if (!string.endsWith(".yml")) {
|
||||
continue;
|
||||
}
|
||||
final String name = string.substring(0, string.length() - 4);
|
||||
try {
|
||||
keys.add(UUID.fromString(name));
|
||||
} catch (IllegalArgumentException ex) {
|
||||
//Ignore these users till they rejoin.
|
||||
}
|
||||
}
|
||||
uuidMap.loadAllUsers(names, history);
|
||||
ess.runTaskAsynchronously(() -> {
|
||||
synchronized (users) {
|
||||
final File userdir = new File(ess.getDataFolder(), "userdata");
|
||||
if (!userdir.exists()) {
|
||||
return;
|
||||
}
|
||||
keys.clear();
|
||||
users.invalidateAll();
|
||||
for (final String string : userdir.list()) {
|
||||
if (!string.endsWith(".yml")) {
|
||||
continue;
|
||||
}
|
||||
final String name = string.substring(0, string.length() - 4);
|
||||
try {
|
||||
keys.add(UUID.fromString(name));
|
||||
} catch (final IllegalArgumentException ex) {
|
||||
//Ignore these users till they rejoin.
|
||||
}
|
||||
}
|
||||
uuidMap.loadAllUsers(names, history);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -95,12 +96,12 @@ public class UserMap extends CacheLoader<String, User> implements IConf {
|
||||
final File userFile = getUserFileFromString(sanitizedName);
|
||||
if (userFile.exists()) {
|
||||
ess.getLogger().info("Importing user " + name + " to usermap.");
|
||||
User user = new User(new OfflinePlayer(sanitizedName, ess.getServer()), ess);
|
||||
final User user = new User(new OfflinePlayer(sanitizedName, ess.getServer()), ess);
|
||||
trackUUID(user.getBase().getUniqueId(), user.getName(), true);
|
||||
return user;
|
||||
}
|
||||
return null;
|
||||
} catch (UncheckedExecutionException ex) {
|
||||
} catch (final UncheckedExecutionException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -112,14 +113,12 @@ public class UserMap extends CacheLoader<String, User> implements IConf {
|
||||
} else {
|
||||
return legacyCacheGet(uuid);
|
||||
}
|
||||
} catch (ExecutionException ex) {
|
||||
return null;
|
||||
} catch (UncheckedExecutionException ex) {
|
||||
} catch (final ExecutionException | UncheckedExecutionException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void trackUUID(final UUID uuid, final String name, boolean replace) {
|
||||
public void trackUUID(final UUID uuid, final String name, final boolean replace) {
|
||||
if (uuid != null) {
|
||||
keys.add(uuid);
|
||||
if (name != null && name.length() > 0) {
|
||||
@@ -144,7 +143,7 @@ public class UserMap extends CacheLoader<String, User> implements IConf {
|
||||
|
||||
@Override
|
||||
public User load(final String stringUUID) throws Exception {
|
||||
UUID uuid = UUID.fromString(stringUUID);
|
||||
final UUID uuid = UUID.fromString(stringUUID);
|
||||
Player player = ess.getServer().getPlayer(uuid);
|
||||
if (player != null) {
|
||||
final User user = new User(player, ess);
|
||||
@@ -180,7 +179,7 @@ public class UserMap extends CacheLoader<String, User> implements IConf {
|
||||
ess.getLogger().warning("Name collection is null, cannot remove user.");
|
||||
return;
|
||||
}
|
||||
UUID uuid = names.get(name);
|
||||
final UUID uuid = names.get(name);
|
||||
if (uuid != null) {
|
||||
keys.remove(uuid);
|
||||
users.invalidate(uuid.toString());
|
||||
@@ -212,6 +211,18 @@ public class UserMap extends CacheLoader<String, User> implements IConf {
|
||||
public UUIDMap getUUIDMap() {
|
||||
return uuidMap;
|
||||
}
|
||||
// class UserMapRemovalListener implements RemovalListener
|
||||
// {
|
||||
// @Override
|
||||
// public void onRemoval(final RemovalNotification notification)
|
||||
// {
|
||||
// Object value = notification.getValue();
|
||||
// if (value != null)
|
||||
// {
|
||||
// ((User)value).cleanup();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
private File getUserFileFromID(final UUID uuid) {
|
||||
final File userFolder = new File(ess.getDataFolder(), "userdata");
|
||||
@@ -222,20 +233,6 @@ public class UserMap extends CacheLoader<String, User> implements IConf {
|
||||
final File userFolder = new File(ess.getDataFolder(), "userdata");
|
||||
return new File(userFolder, StringUtil.sanitizeFileName(name) + ".yml");
|
||||
}
|
||||
// class UserMapRemovalListener implements RemovalListener
|
||||
// {
|
||||
// @Override
|
||||
// public void onRemoval(final RemovalNotification notification)
|
||||
// {
|
||||
// Object value = notification.getValue();
|
||||
// if (value != null)
|
||||
// {
|
||||
// ((User)value).cleanup();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
private final Pattern validUserPattern = Pattern.compile("^[a-zA-Z0-9_]{2,16}$");
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public User getUserFromBukkit(String name) {
|
||||
@@ -247,14 +244,14 @@ public class UserMap extends CacheLoader<String, User> implements IConf {
|
||||
if (name == null || !validUserPattern.matcher(name).matches()) {
|
||||
return null;
|
||||
}
|
||||
org.bukkit.OfflinePlayer offlinePlayer = ess.getServer().getOfflinePlayer(name);
|
||||
final org.bukkit.OfflinePlayer offlinePlayer = ess.getServer().getOfflinePlayer(name);
|
||||
if (offlinePlayer == null) {
|
||||
return null;
|
||||
}
|
||||
UUID uuid;
|
||||
final UUID uuid;
|
||||
try {
|
||||
uuid = offlinePlayer.getUniqueId();
|
||||
} catch (UnsupportedOperationException | NullPointerException e) {
|
||||
} catch (final UnsupportedOperationException | NullPointerException e) {
|
||||
return null;
|
||||
}
|
||||
// This is how Bukkit generates fake UUIDs
|
||||
@@ -266,12 +263,10 @@ public class UserMap extends CacheLoader<String, User> implements IConf {
|
||||
}
|
||||
}
|
||||
|
||||
private static Method getLegacy;
|
||||
|
||||
private User legacyCacheGet(UUID uuid) {
|
||||
private User legacyCacheGet(final UUID uuid) {
|
||||
if (getLegacy == null) {
|
||||
Class<?> usersClass = users.getClass();
|
||||
for (Method m : usersClass.getDeclaredMethods()) {
|
||||
final Class<?> usersClass = users.getClass();
|
||||
for (final Method m : usersClass.getDeclaredMethods()) {
|
||||
if (m.getName().equals("get")) {
|
||||
getLegacy = m;
|
||||
getLegacy.setAccessible(true);
|
||||
@@ -281,25 +276,25 @@ public class UserMap extends CacheLoader<String, User> implements IConf {
|
||||
}
|
||||
try {
|
||||
return (User) getLegacy.invoke(users, uuid.toString());
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
} catch (final IllegalAccessException | InvocationTargetException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void legacyMaximumSize(CacheBuilder builder, int maxCount) {
|
||||
private void legacyMaximumSize(final CacheBuilder builder, final int maxCount) {
|
||||
try {
|
||||
Method maxSizeLegacy = builder.getClass().getDeclaredMethod("maximumSize", Integer.TYPE);
|
||||
final Method maxSizeLegacy = builder.getClass().getDeclaredMethod("maximumSize", Integer.TYPE);
|
||||
maxSizeLegacy.setAccessible(true);
|
||||
maxSizeLegacy.invoke(builder, maxCount);
|
||||
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
|
||||
} catch (final NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Cache<String, User> legacyBuild(CacheBuilder builder) {
|
||||
private Cache<String, User> legacyBuild(final CacheBuilder builder) {
|
||||
Method build = null;
|
||||
for (Method method : builder.getClass().getDeclaredMethods()) {
|
||||
for (final Method method : builder.getClass().getDeclaredMethods()) {
|
||||
if (method.getName().equals("build")) {
|
||||
build = method;
|
||||
break;
|
||||
@@ -310,7 +305,7 @@ public class UserMap extends CacheLoader<String, User> implements IConf {
|
||||
assert build != null;
|
||||
build.setAccessible(true);
|
||||
legacyUsers = (Cache<String, User>) build.invoke(builder, this);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
} catch (final IllegalAccessException | InvocationTargetException e) {
|
||||
legacyUsers = null;
|
||||
}
|
||||
return legacyUsers;
|
||||
|
||||
@@ -6,21 +6,28 @@ import net.ess3.api.InvalidNameException;
|
||||
import net.ess3.api.InvalidWorldException;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class Warps implements IConf, net.ess3.api.IWarps {
|
||||
private static final Logger logger = Logger.getLogger("Essentials");
|
||||
private final Map<StringIgnoreCase, EssentialsConf> warpPoints = new HashMap<StringIgnoreCase, EssentialsConf>();
|
||||
private final Map<StringIgnoreCase, EssentialsConf> warpPoints = new HashMap<>();
|
||||
private final File warpsFolder;
|
||||
private final Server server;
|
||||
|
||||
public Warps(Server server, File dataFolder) {
|
||||
public Warps(final Server server, final File dataFolder) {
|
||||
this.server = server;
|
||||
warpsFolder = new File(dataFolder, "warps");
|
||||
if (!warpsFolder.exists()) {
|
||||
@@ -36,17 +43,17 @@ public class Warps implements IConf, net.ess3.api.IWarps {
|
||||
|
||||
@Override
|
||||
public Collection<String> getList() {
|
||||
final List<String> keys = new ArrayList<String>();
|
||||
for (StringIgnoreCase stringIgnoreCase : warpPoints.keySet()) {
|
||||
final List<String> keys = new ArrayList<>();
|
||||
for (final StringIgnoreCase stringIgnoreCase : warpPoints.keySet()) {
|
||||
keys.add(stringIgnoreCase.getString());
|
||||
}
|
||||
Collections.sort(keys, String.CASE_INSENSITIVE_ORDER);
|
||||
keys.sort(String.CASE_INSENSITIVE_ORDER);
|
||||
return keys;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getWarp(String warp) throws WarpNotFoundException, InvalidWorldException {
|
||||
EssentialsConf conf = warpPoints.get(new StringIgnoreCase(warp));
|
||||
public Location getWarp(final String warp) throws WarpNotFoundException, InvalidWorldException {
|
||||
final EssentialsConf conf = warpPoints.get(new StringIgnoreCase(warp));
|
||||
if (conf == null) {
|
||||
throw new WarpNotFoundException();
|
||||
}
|
||||
@@ -54,16 +61,16 @@ public class Warps implements IConf, net.ess3.api.IWarps {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWarp(String name, Location loc) throws Exception {
|
||||
public void setWarp(final String name, final Location loc) throws Exception {
|
||||
setWarp(null, name, loc);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setWarp(IUser user, String name, Location loc) throws Exception {
|
||||
String filename = StringUtil.sanitizeFileName(name);
|
||||
public void setWarp(final IUser user, final String name, final Location loc) throws Exception {
|
||||
final String filename = StringUtil.sanitizeFileName(name);
|
||||
EssentialsConf conf = warpPoints.get(new StringIgnoreCase(name));
|
||||
if (conf == null) {
|
||||
File confFile = new File(warpsFolder, filename + ".yml");
|
||||
final File confFile = new File(warpsFolder, filename + ".yml");
|
||||
if (confFile.exists()) {
|
||||
throw new Exception(tl("similarWarpExist"));
|
||||
}
|
||||
@@ -75,28 +82,28 @@ public class Warps implements IConf, net.ess3.api.IWarps {
|
||||
if (user != null) conf.setProperty("lastowner", user.getBase().getUniqueId().toString());
|
||||
try {
|
||||
conf.saveWithError();
|
||||
} catch (IOException ex) {
|
||||
} catch (final IOException ex) {
|
||||
throw new IOException(tl("invalidWarpName"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public UUID getLastOwner(String warp) throws WarpNotFoundException {
|
||||
EssentialsConf conf = warpPoints.get(new StringIgnoreCase(warp));
|
||||
public UUID getLastOwner(final String warp) throws WarpNotFoundException {
|
||||
final EssentialsConf conf = warpPoints.get(new StringIgnoreCase(warp));
|
||||
if (conf == null) {
|
||||
throw new WarpNotFoundException();
|
||||
}
|
||||
UUID uuid = null;
|
||||
try {
|
||||
uuid = UUID.fromString(conf.getString("lastowner"));
|
||||
} catch (final Exception ignored) {
|
||||
}
|
||||
catch (Exception ex) {}
|
||||
return uuid;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void removeWarp(String name) throws Exception {
|
||||
EssentialsConf conf = warpPoints.get(new StringIgnoreCase(name));
|
||||
public void removeWarp(final String name) throws Exception {
|
||||
final EssentialsConf conf = warpPoints.get(new StringIgnoreCase(name));
|
||||
if (conf == null) {
|
||||
throw new Exception(tl("warpNotExist"));
|
||||
}
|
||||
@@ -109,19 +116,19 @@ public class Warps implements IConf, net.ess3.api.IWarps {
|
||||
@Override
|
||||
public final void reloadConfig() {
|
||||
warpPoints.clear();
|
||||
File[] listOfFiles = warpsFolder.listFiles();
|
||||
final File[] listOfFiles = warpsFolder.listFiles();
|
||||
if (listOfFiles.length >= 1) {
|
||||
for (int i = 0; i < listOfFiles.length; i++) {
|
||||
String filename = listOfFiles[i].getName();
|
||||
if (listOfFiles[i].isFile() && filename.endsWith(".yml")) {
|
||||
for (final File listOfFile : listOfFiles) {
|
||||
final String filename = listOfFile.getName();
|
||||
if (listOfFile.isFile() && filename.endsWith(".yml")) {
|
||||
try {
|
||||
EssentialsConf conf = new EssentialsConf(listOfFiles[i]);
|
||||
final EssentialsConf conf = new EssentialsConf(listOfFile);
|
||||
conf.load();
|
||||
String name = conf.getString("name");
|
||||
final String name = conf.getString("name");
|
||||
if (name != null) {
|
||||
warpPoints.put(new StringIgnoreCase(name), conf);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
} catch (final Exception ex) {
|
||||
logger.log(Level.WARNING, tl("loadWarpError", filename), ex);
|
||||
}
|
||||
}
|
||||
@@ -129,9 +136,12 @@ public class Warps implements IConf, net.ess3.api.IWarps {
|
||||
}
|
||||
}
|
||||
|
||||
//This is here for future 3.x api support. Not implemented here becasue storage is handled differently
|
||||
/**
|
||||
* @deprecated This method relates to the abandoned 3.x storage refactor and is not implemented.
|
||||
*/
|
||||
@Override
|
||||
public File getWarpFile(String name) throws InvalidNameException {
|
||||
@Deprecated
|
||||
public File getWarpFile(final String name) throws InvalidNameException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@@ -143,7 +153,7 @@ public class Warps implements IConf, net.ess3.api.IWarps {
|
||||
private static class StringIgnoreCase {
|
||||
private final String string;
|
||||
|
||||
public StringIgnoreCase(String string) {
|
||||
StringIgnoreCase(final String string) {
|
||||
this.string = string;
|
||||
}
|
||||
|
||||
@@ -153,7 +163,7 @@ public class Warps implements IConf, net.ess3.api.IWarps {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(final Object o) {
|
||||
if (o instanceof StringIgnoreCase) {
|
||||
return getString().equalsIgnoreCase(((StringIgnoreCase) o).getString());
|
||||
}
|
||||
|
||||
@@ -12,11 +12,10 @@ import java.util.Locale;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Worth implements IConf {
|
||||
private final EssentialsConf config;
|
||||
|
||||
public Worth(File dataFolder) {
|
||||
public Worth(final File dataFolder) {
|
||||
config = new EssentialsConf(new File(dataFolder, "worth.yml"));
|
||||
config.setTemplateName("/worth.yml");
|
||||
config.load();
|
||||
@@ -29,10 +28,10 @@ public class Worth implements IConf {
|
||||
* @param itemStack The item stack to look up in the config.
|
||||
* @return The price from the config.
|
||||
*/
|
||||
public BigDecimal getPrice(IEssentials ess, ItemStack itemStack) {
|
||||
public BigDecimal getPrice(final IEssentials ess, final ItemStack itemStack) {
|
||||
BigDecimal result;
|
||||
|
||||
String itemname = itemStack.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", "");
|
||||
final String itemname = itemStack.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", "");
|
||||
|
||||
// Check for matches with data value from stack
|
||||
// Note that we always default to BigDecimal.ONE.negate(), equivalent to -1
|
||||
@@ -73,7 +72,7 @@ public class Worth implements IConf {
|
||||
* @return The amount of items to sell from the player's inventory.
|
||||
* @throws Exception Thrown if trying to sell air or an invalid amount.
|
||||
*/
|
||||
public int getAmount(IEssentials ess, User user, ItemStack is, String[] args, boolean isBulkSell) throws Exception {
|
||||
public int getAmount(final IEssentials ess, final User user, final ItemStack is, final String[] args, final boolean isBulkSell) throws Exception {
|
||||
if (is == null || is.getType() == Material.AIR) {
|
||||
throw new Exception(tl("itemSellAir"));
|
||||
}
|
||||
@@ -83,7 +82,7 @@ public class Worth implements IConf {
|
||||
if (args.length > 1) {
|
||||
try {
|
||||
amount = Integer.parseInt(args[1].replaceAll("[^0-9]", ""));
|
||||
} catch (NumberFormatException ex) {
|
||||
} catch (final NumberFormatException ex) {
|
||||
throw new NotEnoughArgumentsException(ex);
|
||||
}
|
||||
if (args[1].startsWith("-")) {
|
||||
@@ -91,15 +90,15 @@ public class Worth implements IConf {
|
||||
}
|
||||
}
|
||||
|
||||
boolean stack = args.length > 1 && args[1].endsWith("s");
|
||||
boolean requireStack = ess.getSettings().isTradeInStacks(is.getType());
|
||||
final boolean stack = args.length > 1 && args[1].endsWith("s");
|
||||
final boolean requireStack = ess.getSettings().isTradeInStacks(is.getType());
|
||||
|
||||
if (requireStack && !stack) {
|
||||
throw new Exception(tl("itemMustBeStacked"));
|
||||
}
|
||||
|
||||
int max = 0;
|
||||
for (ItemStack s : user.getBase().getInventory().getContents()) {
|
||||
for (final ItemStack s : user.getBase().getInventory().getContents()) {
|
||||
if (s == null || !s.isSimilar(is)) {
|
||||
continue;
|
||||
}
|
||||
@@ -136,7 +135,7 @@ public class Worth implements IConf {
|
||||
* @param itemStack A stack of the item to save.
|
||||
* @param price The new price of the item.
|
||||
*/
|
||||
public void setPrice(IEssentials ess, ItemStack itemStack, double price) {
|
||||
public void setPrice(final IEssentials ess, final ItemStack itemStack, final double price) {
|
||||
String path = "worth." + itemStack.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", "");
|
||||
|
||||
// Spigot 1.13+ throws an exception if a 1.13+ plugin even *attempts* to do set data.
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.earth2me.essentials.utils.StringUtil;
|
||||
import com.google.common.base.Charsets;
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.MaxMoneyException;
|
||||
import net.ess3.api.events.UserBalanceUpdateEvent;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.File;
|
||||
@@ -17,34 +18,35 @@ import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
||||
/**
|
||||
* You should use Vault instead of directly using this class.
|
||||
*/
|
||||
public class Economy {
|
||||
public Economy() {
|
||||
}
|
||||
|
||||
private static final Logger logger = Logger.getLogger("Essentials");
|
||||
private static IEssentials ess;
|
||||
private static final String noCallBeforeLoad = "Essentials API is called before Essentials is loaded.";
|
||||
public static final MathContext MATH_CONTEXT = MathContext.DECIMAL128;
|
||||
private static final Logger logger = Logger.getLogger("Essentials");
|
||||
private static final String noCallBeforeLoad = "Essentials API is called before Essentials is loaded.";
|
||||
private static IEssentials ess;
|
||||
|
||||
protected Economy() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param aEss the ess to set
|
||||
*/
|
||||
public static void setEss(IEssentials aEss) {
|
||||
public static void setEss(final IEssentials aEss) {
|
||||
ess = aEss;
|
||||
}
|
||||
|
||||
private static void createNPCFile(String name) {
|
||||
File folder = new File(ess.getDataFolder(), "userdata");
|
||||
final File folder = new File(ess.getDataFolder(), "userdata");
|
||||
name = StringUtil.safeString(name);
|
||||
if (!folder.exists()) {
|
||||
folder.mkdirs();
|
||||
if (!folder.mkdirs()) {
|
||||
throw new RuntimeException("Error while creating userdata directory!");
|
||||
}
|
||||
}
|
||||
UUID npcUUID = UUID.nameUUIDFromBytes(("NPC:" + name).getBytes(Charsets.UTF_8));
|
||||
EssentialsUserConf npcConfig = new EssentialsUserConf(name, npcUUID, new File(folder, npcUUID.toString() + ".yml"));
|
||||
final UUID npcUUID = UUID.nameUUIDFromBytes(("NPC:" + name).getBytes(Charsets.UTF_8));
|
||||
final EssentialsUserConf npcConfig = new EssentialsUserConf(name, npcUUID, new File(folder, npcUUID.toString() + ".yml"));
|
||||
npcConfig.load();
|
||||
npcConfig.setProperty("npc", true);
|
||||
npcConfig.setProperty("lastAccountName", name);
|
||||
@@ -53,17 +55,17 @@ public class Economy {
|
||||
ess.getUserMap().trackUUID(npcUUID, name, false);
|
||||
}
|
||||
|
||||
private static void deleteNPC(String name) {
|
||||
User user = ess.getUser(name);
|
||||
private static void deleteNPC(final String name) {
|
||||
final User user = ess.getUser(name);
|
||||
user.reset();
|
||||
}
|
||||
|
||||
private static User getUserByName(String name) {
|
||||
private static User getUserByName(final String name) {
|
||||
if (ess == null) {
|
||||
throw new RuntimeException(noCallBeforeLoad);
|
||||
}
|
||||
if (name == null) {
|
||||
throw new RuntimeException("Economy username cannot be null");
|
||||
throw new IllegalArgumentException("Economy username cannot be null");
|
||||
}
|
||||
|
||||
User user = ess.getUser(name);
|
||||
@@ -73,7 +75,7 @@ public class Economy {
|
||||
via Vault during player join.
|
||||
See: https://github.com/EssentialsX/Essentials/issues/2400
|
||||
*/
|
||||
Player player = ess.getServer().getPlayerExact(name);
|
||||
final Player player = ess.getServer().getPlayerExact(name);
|
||||
if (player != null) {
|
||||
user = ess.getUser(player.getUniqueId());
|
||||
if (user != null) {
|
||||
@@ -85,18 +87,27 @@ public class Economy {
|
||||
return user;
|
||||
}
|
||||
|
||||
private static User getUserByUUID(final UUID uuid) {
|
||||
if (ess == null) {
|
||||
throw new RuntimeException(noCallBeforeLoad);
|
||||
}
|
||||
if (uuid == null) {
|
||||
throw new IllegalArgumentException("Economy uuid cannot be null");
|
||||
}
|
||||
return ess.getUser(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the balance of a user
|
||||
*
|
||||
* @param name Name of the user
|
||||
*
|
||||
* @return balance
|
||||
*
|
||||
* @throws UserDoesNotExistException
|
||||
* @deprecated Use {@link Economy#getMoneyExact(UUID)} or {@link Economy#getMoneyExact(User)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static double getMoney(String name) throws UserDoesNotExistException {
|
||||
BigDecimal exactAmount = getMoneyExact(name);
|
||||
public static double getMoney(final String name) throws UserDoesNotExistException {
|
||||
final BigDecimal exactAmount = getMoneyExact(name);
|
||||
double amount = exactAmount.doubleValue();
|
||||
if (new BigDecimal(amount).compareTo(exactAmount) > 0) {
|
||||
// closest double is bigger than the exact amount
|
||||
@@ -106,11 +117,46 @@ public class Economy {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public static BigDecimal getMoneyExact(String name) throws UserDoesNotExistException {
|
||||
User user = getUserByName(name);
|
||||
/**
|
||||
* @param name Name of user
|
||||
* @return Exact balance of user
|
||||
* @throws UserDoesNotExistException
|
||||
* @deprecated Usernames can change, use {@link Economy#getMoneyExact(UUID)} or {@link Economy#getMoneyExact(User)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static BigDecimal getMoneyExact(final String name) throws UserDoesNotExistException {
|
||||
final User user = getUserByName(name);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(name);
|
||||
}
|
||||
return getMoneyExact(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the exact balance of the account with the given UUID.
|
||||
*
|
||||
* @param uuid The UUID of the user account to retrieve the balance for
|
||||
* @return The account's balance
|
||||
* @throws UserDoesNotExistException If the user does not exist
|
||||
*/
|
||||
public static BigDecimal getMoneyExact(final UUID uuid) throws UserDoesNotExistException {
|
||||
final User user = getUserByUUID(uuid);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(uuid);
|
||||
}
|
||||
return getMoneyExact(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the exact balance of the account with the given UUID.
|
||||
*
|
||||
* @param user The user account to retrieve the balance for
|
||||
* @return The account's balance
|
||||
*/
|
||||
public static BigDecimal getMoneyExact(final User user) {
|
||||
if (user == null) {
|
||||
throw new IllegalArgumentException("Economy user cannot be null");
|
||||
}
|
||||
return user.getMoney();
|
||||
}
|
||||
|
||||
@@ -119,24 +165,64 @@ public class Economy {
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param balance The balance you want to set
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exists
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @deprecated Use {@link Economy#setMoney(UUID, BigDecimal)} or {@link Economy#setMoney(User, BigDecimal)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static void setMoney(String name, double balance) throws UserDoesNotExistException, NoLoanPermittedException {
|
||||
public static void setMoney(final String name, final double balance) throws UserDoesNotExistException, NoLoanPermittedException {
|
||||
try {
|
||||
setMoney(name, BigDecimal.valueOf(balance));
|
||||
} catch (ArithmeticException e) {
|
||||
} catch (final ArithmeticException e) {
|
||||
logger.log(Level.WARNING, "Failed to set balance of " + name + " to " + balance + ": " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setMoney(String name, BigDecimal balance) throws UserDoesNotExistException, NoLoanPermittedException {
|
||||
User user = getUserByName(name);
|
||||
/**
|
||||
* Sets the balance of a user
|
||||
*
|
||||
* @param name Name of user
|
||||
* @param balance The balance you want to set
|
||||
* @throws UserDoesNotExistException If a user by that name does not exist
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @deprecated Usernames can change use {@link Economy#setMoney(UUID, BigDecimal)} or {@link Economy#setMoney(User, BigDecimal)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static void setMoney(final String name, final BigDecimal balance) throws UserDoesNotExistException, NoLoanPermittedException {
|
||||
final User user = getUserByName(name);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(name);
|
||||
}
|
||||
setMoney(user, balance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the balance of a user
|
||||
*
|
||||
* @param uuid UUID of user
|
||||
* @param balance The balance you want to set
|
||||
* @throws UserDoesNotExistException If a user by that uuid does not exist
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
*/
|
||||
public static void setMoney(final UUID uuid, final BigDecimal balance) throws NoLoanPermittedException, UserDoesNotExistException {
|
||||
final User user = getUserByUUID(uuid);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(uuid);
|
||||
}
|
||||
setMoney(user, balance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the balance of a user
|
||||
*
|
||||
* @param user User
|
||||
* @param balance The balance you want to set
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
*/
|
||||
public static void setMoney(final User user, final BigDecimal balance) throws NoLoanPermittedException {
|
||||
if (user == null) {
|
||||
throw new IllegalArgumentException("Economy user cannot be null");
|
||||
}
|
||||
if (balance.compareTo(ess.getSettings().getMinMoney()) < 0) {
|
||||
throw new NoLoanPermittedException();
|
||||
}
|
||||
@@ -144,118 +230,307 @@ public class Economy {
|
||||
throw new NoLoanPermittedException();
|
||||
}
|
||||
try {
|
||||
user.setMoney(balance);
|
||||
} catch (MaxMoneyException ex) {
|
||||
user.setMoney(balance, UserBalanceUpdateEvent.Cause.API);
|
||||
} catch (final MaxMoneyException ex) {
|
||||
//TODO: Update API to show max balance errors
|
||||
}
|
||||
Trade.log("API", "Set", "API", name, new Trade(balance, ess), null, null, null, ess);
|
||||
Trade.log("API", "Set", "API", user.getName(), new Trade(balance, ess), null, null, null, ess);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds money to the balance of a user
|
||||
* <p>
|
||||
* Use {@link Economy#add(UUID, BigDecimal)} or {@link Economy#add(User, BigDecimal)}
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param amount The money you want to add
|
||||
* @throws UserDoesNotExistException If a user by that name does not exists
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
*/
|
||||
@Deprecated
|
||||
public static void add(final String name, final double amount) throws UserDoesNotExistException, NoLoanPermittedException {
|
||||
try {
|
||||
add(name, BigDecimal.valueOf(amount));
|
||||
} catch (final ArithmeticException e) {
|
||||
logger.log(Level.WARNING, "Failed to add " + amount + " to balance of " + name + ": " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds money to the balance of a user
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param amount The money you want to add
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exists
|
||||
* @param amount The amount of money to be added to the user's account
|
||||
* @throws UserDoesNotExistException If a user by that name does not exist
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @throws ArithmeticException
|
||||
* @deprecated Usernames can change, use {@link Economy#add(UUID, BigDecimal)} or {@link Economy#add(User, BigDecimal)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static void add(String name, double amount) throws UserDoesNotExistException, NoLoanPermittedException {
|
||||
try {
|
||||
add(name, BigDecimal.valueOf(amount));
|
||||
} catch (ArithmeticException e) {
|
||||
logger.log(Level.WARNING, "Failed to add " + amount + " to balance of " + name + ": " + e.getMessage(), e);
|
||||
public static void add(final String name, final BigDecimal amount) throws UserDoesNotExistException, NoLoanPermittedException, ArithmeticException {
|
||||
final User user = getUserByName(name);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(name);
|
||||
}
|
||||
}
|
||||
|
||||
public static void add(String name, BigDecimal amount) throws UserDoesNotExistException, NoLoanPermittedException, ArithmeticException {
|
||||
BigDecimal result = getMoneyExact(name).add(amount, MATH_CONTEXT);
|
||||
setMoney(name, result);
|
||||
Trade.log("API", "Add", "API", name, new Trade(amount, ess), null, null, null, ess);
|
||||
add(user, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Substracts money from the balance of a user
|
||||
* Adds money to the balance of a user
|
||||
*
|
||||
* @param uuid UUID of the user
|
||||
* @param amount The money you want to add
|
||||
* @throws UserDoesNotExistException If a user by that uuid does not exist
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
public static void add(final UUID uuid, final BigDecimal amount) throws NoLoanPermittedException, ArithmeticException, UserDoesNotExistException {
|
||||
final User user = getUserByUUID(uuid);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(uuid);
|
||||
}
|
||||
add(user, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds money to the balance of a user
|
||||
*
|
||||
* @param user User
|
||||
* @param amount The money you want to add
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @throws ArithmeticException
|
||||
* @deprecated Usernames can change, use {@link Economy#add(UUID, BigDecimal)} or {@link Economy#add(User, BigDecimal)}
|
||||
*/
|
||||
public static void add(final User user, final BigDecimal amount) throws NoLoanPermittedException, ArithmeticException {
|
||||
if (user == null) {
|
||||
throw new IllegalArgumentException("Economy user cannot be null");
|
||||
}
|
||||
final BigDecimal result = getMoneyExact(user).add(amount, MATH_CONTEXT);
|
||||
setMoney(user, result);
|
||||
Trade.log("API", "Add", "API", user.getName(), new Trade(amount, ess), null, null, null, ess);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts money from the balance of a user
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param amount The money you want to substract
|
||||
*
|
||||
* @param amount The money you want to subtract
|
||||
* @throws UserDoesNotExistException If a user by that name does not exists
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @deprecated Use {@link Economy#subtract(UUID, BigDecimal)} or {@link Economy#subtract(User, BigDecimal)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static void subtract(String name, double amount) throws UserDoesNotExistException, NoLoanPermittedException {
|
||||
public static void subtract(final String name, final double amount) throws UserDoesNotExistException, NoLoanPermittedException {
|
||||
try {
|
||||
substract(name, BigDecimal.valueOf(amount));
|
||||
} catch (ArithmeticException e) {
|
||||
logger.log(Level.WARNING, "Failed to substract " + amount + " of balance of " + name + ": " + e.getMessage(), e);
|
||||
} catch (final ArithmeticException e) {
|
||||
logger.log(Level.WARNING, "Failed to subtract " + amount + " of balance of " + name + ": " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void substract(String name, BigDecimal amount) throws UserDoesNotExistException, NoLoanPermittedException, ArithmeticException {
|
||||
BigDecimal result = getMoneyExact(name).subtract(amount, MATH_CONTEXT);
|
||||
/**
|
||||
* Subtracts money from the balance of a user
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param amount The money you want to subtract
|
||||
* @throws UserDoesNotExistException If a user by that name does not exist
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @throws ArithmeticException
|
||||
* @deprecated Usernames can change, use {@link Economy#subtract(UUID, BigDecimal)} or {@link Economy#subtract(User, BigDecimal)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static void substract(final String name, final BigDecimal amount) throws UserDoesNotExistException, NoLoanPermittedException, ArithmeticException {
|
||||
final BigDecimal result = getMoneyExact(name).subtract(amount, MATH_CONTEXT);
|
||||
setMoney(name, result);
|
||||
Trade.log("API", "Subtract", "API", name, new Trade(amount, ess), null, null, null, ess);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts money from the balance of a user
|
||||
*
|
||||
* @param uuid UUID of the user
|
||||
* @param amount The money you want to subtract
|
||||
* @throws UserDoesNotExistException If a user by that UUID does not exist
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
public static void subtract(final UUID uuid, final BigDecimal amount) throws NoLoanPermittedException, ArithmeticException, UserDoesNotExistException {
|
||||
final User user = getUserByUUID(uuid);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(uuid);
|
||||
}
|
||||
subtract(user, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts money from the balance of a user
|
||||
*
|
||||
* @param user User
|
||||
* @param amount The money you want to subtract
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
public static void subtract(final User user, final BigDecimal amount) throws NoLoanPermittedException, ArithmeticException {
|
||||
if (user == null) {
|
||||
throw new IllegalArgumentException("Economy user cannot be null");
|
||||
}
|
||||
final BigDecimal result = getMoneyExact(user).subtract(amount, MATH_CONTEXT);
|
||||
setMoney(user, result);
|
||||
Trade.log("API", "Subtract", "API", user.getName(), new Trade(amount, ess), null, null, null, ess);
|
||||
}
|
||||
|
||||
/**
|
||||
* Divides the balance of a user by a value
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param name Name of the user
|
||||
* @param amount The balance is divided by this value
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exists
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @deprecated Use {@link Economy#divide(UUID, BigDecimal)} or {@link Economy#divide(User, BigDecimal)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static void divide(String name, double amount) throws UserDoesNotExistException, NoLoanPermittedException {
|
||||
public static void divide(final String name, final double amount) throws UserDoesNotExistException, NoLoanPermittedException {
|
||||
try {
|
||||
divide(name, BigDecimal.valueOf(amount));
|
||||
} catch (ArithmeticException e) {
|
||||
} catch (final ArithmeticException e) {
|
||||
logger.log(Level.WARNING, "Failed to divide balance of " + name + " by " + amount + ": " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void divide(String name, BigDecimal amount) throws UserDoesNotExistException, NoLoanPermittedException, ArithmeticException {
|
||||
BigDecimal result = getMoneyExact(name).divide(amount, MATH_CONTEXT);
|
||||
setMoney(name, result);
|
||||
Trade.log("API", "Divide", "API", name, new Trade(amount, ess), null, null, null, ess);
|
||||
/**
|
||||
* Divides the balance of a user by a value
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param amount The balance is divided by this value
|
||||
* @throws UserDoesNotExistException If a user by that name does not exist
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @throws ArithmeticException
|
||||
* @deprecated Usernames can change, use {@link Economy#divide(UUID, BigDecimal)} or {@link Economy#divide(User, BigDecimal)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static void divide(final String name, final BigDecimal amount) throws UserDoesNotExistException, NoLoanPermittedException, ArithmeticException {
|
||||
final User user = getUserByName(name);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(name);
|
||||
}
|
||||
divide(user, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Divides the balance of a user by a value
|
||||
*
|
||||
* @param uuid Name of the user
|
||||
* @param amount The balance is divided by this value
|
||||
* @throws UserDoesNotExistException If a user by that UUID does not exist
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
public static void divide(final UUID uuid, final BigDecimal amount) throws NoLoanPermittedException, ArithmeticException, UserDoesNotExistException {
|
||||
final User user = getUserByUUID(uuid);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(uuid);
|
||||
}
|
||||
divide(user, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Divides the balance of a user by a value
|
||||
*
|
||||
* @param user Name of the user
|
||||
* @param amount The balance is divided by this value
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
public static void divide(final User user, final BigDecimal amount) throws NoLoanPermittedException, ArithmeticException {
|
||||
if (user == null) {
|
||||
throw new IllegalArgumentException("Economy user cannot be null");
|
||||
}
|
||||
final BigDecimal result = getMoneyExact(user).divide(amount, MATH_CONTEXT);
|
||||
setMoney(user, result);
|
||||
Trade.log("API", "Divide", "API", user.getName(), new Trade(amount, ess), null, null, null, ess);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies the balance of a user by a value
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param name Name of the user
|
||||
* @param amount The balance is multiplied by this value
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exists
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @deprecated Use {@link Economy#multiply(UUID, BigDecimal)} or {@link Economy#multiply(User, BigDecimal)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static void multiply(String name, double amount) throws UserDoesNotExistException, NoLoanPermittedException {
|
||||
public static void multiply(final String name, final double amount) throws UserDoesNotExistException, NoLoanPermittedException {
|
||||
try {
|
||||
multiply(name, BigDecimal.valueOf(amount));
|
||||
} catch (ArithmeticException e) {
|
||||
} catch (final ArithmeticException e) {
|
||||
logger.log(Level.WARNING, "Failed to multiply balance of " + name + " by " + amount + ": " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void multiply(String name, BigDecimal amount) throws UserDoesNotExistException, NoLoanPermittedException, ArithmeticException {
|
||||
BigDecimal result = getMoneyExact(name).multiply(amount, MATH_CONTEXT);
|
||||
setMoney(name, result);
|
||||
Trade.log("API", "Multiply", "API", name, new Trade(amount, ess), null, null, null, ess);
|
||||
/**
|
||||
* Multiplies the balance of a user by a value
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param amount The balance is multiplied by the this value
|
||||
* @throws UserDoesNotExistException If a user by that name does not exist
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @throws ArithmeticException
|
||||
* @deprecated Usernames can change, use {@link Economy#multiply(UUID, BigDecimal)} or {@link Economy#multiply(User, BigDecimal)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static void multiply(final String name, final BigDecimal amount) throws UserDoesNotExistException, NoLoanPermittedException, ArithmeticException {
|
||||
final User user = getUserByName(name);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(name);
|
||||
}
|
||||
multiply(user, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies the balance of a user by a value
|
||||
*
|
||||
* @param uuid Name of the user
|
||||
* @param amount The balance is multiplied by the this value
|
||||
* @throws UserDoesNotExistException If a user by that uuid does not exist
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
public static void multiply(final UUID uuid, final BigDecimal amount) throws NoLoanPermittedException, ArithmeticException, UserDoesNotExistException {
|
||||
final User user = getUserByUUID(uuid);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(uuid);
|
||||
}
|
||||
multiply(user, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies the balance of a user by a value
|
||||
*
|
||||
* @param user Name of the user
|
||||
* @param amount The balance is multiplied by the this value
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
public static void multiply(final User user, final BigDecimal amount) throws NoLoanPermittedException, ArithmeticException {
|
||||
if (user == null) {
|
||||
throw new IllegalArgumentException("Economy user cannot be null");
|
||||
}
|
||||
final BigDecimal result = getMoneyExact(user).multiply(amount, MATH_CONTEXT);
|
||||
setMoney(user, result);
|
||||
Trade.log("API", "Multiply", "API", user.getName(), new Trade(amount, ess), null, null, null, ess);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the balance of a user to the starting balance
|
||||
*
|
||||
* @param name Name of the user
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exists
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @deprecated Usernames can change, use {@link Economy#resetBalance(UUID)} or {@link Economy#resetBalance(User)}
|
||||
*/
|
||||
public static void resetBalance(String name) throws UserDoesNotExistException, NoLoanPermittedException {
|
||||
@Deprecated
|
||||
public static void resetBalance(final String name) throws UserDoesNotExistException, NoLoanPermittedException {
|
||||
if (ess == null) {
|
||||
throw new RuntimeException(noCallBeforeLoad);
|
||||
}
|
||||
@@ -264,102 +539,291 @@ public class Economy {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name Name of the user
|
||||
* @param amount The amount of money the user should have
|
||||
* Resets the balance of a user to the starting balance
|
||||
*
|
||||
* @return true, if the user has more or an equal amount of money
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exists
|
||||
* @param uuid UUID of the user
|
||||
* @throws UserDoesNotExistException If a user by that UUID does not exists
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean hasEnough(String name, double amount) throws UserDoesNotExistException {
|
||||
try {
|
||||
return hasEnough(name, BigDecimal.valueOf(amount));
|
||||
} catch (ArithmeticException e) {
|
||||
logger.log(Level.WARNING, "Failed to compare balance of " + name + " with " + amount + ": " + e.getMessage(), e);
|
||||
return false;
|
||||
public static void resetBalance(final UUID uuid) throws NoLoanPermittedException, UserDoesNotExistException {
|
||||
final User user = getUserByUUID(uuid);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(uuid);
|
||||
}
|
||||
resetBalance(user);
|
||||
}
|
||||
|
||||
public static boolean hasEnough(String name, BigDecimal amount) throws UserDoesNotExistException, ArithmeticException {
|
||||
return amount.compareTo(getMoneyExact(name)) <= 0;
|
||||
/**
|
||||
* Resets the balance of a user to the starting balance
|
||||
*
|
||||
* @param user User
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
*/
|
||||
public static void resetBalance(final User user) throws NoLoanPermittedException {
|
||||
if (ess == null) {
|
||||
throw new RuntimeException(noCallBeforeLoad);
|
||||
}
|
||||
if (user == null) {
|
||||
throw new IllegalArgumentException("Economy user cannot be null");
|
||||
}
|
||||
setMoney(user, ess.getSettings().getStartingBalance());
|
||||
Trade.log("API", "Reset", "API", user.getName(), new Trade(BigDecimal.ZERO, ess), null, null, null, ess);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name Name of the user
|
||||
* @param amount The amount of money the user should have
|
||||
*
|
||||
* @return true, if the user has more money
|
||||
*
|
||||
* @return true, if the user has more or an equal amount of money
|
||||
* @throws UserDoesNotExistException If a user by that name does not exists
|
||||
* @deprecated Use {@link Economy#hasEnough(UUID, BigDecimal)} or {@link Economy#hasEnough(User, BigDecimal)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean hasMore(String name, double amount) throws UserDoesNotExistException {
|
||||
public static boolean hasEnough(final String name, final double amount) throws UserDoesNotExistException {
|
||||
try {
|
||||
return hasMore(name, BigDecimal.valueOf(amount));
|
||||
} catch (ArithmeticException e) {
|
||||
return hasEnough(name, BigDecimal.valueOf(amount));
|
||||
} catch (final ArithmeticException e) {
|
||||
logger.log(Level.WARNING, "Failed to compare balance of " + name + " with " + amount + ": " + e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasMore(String name, BigDecimal amount) throws UserDoesNotExistException, ArithmeticException {
|
||||
return amount.compareTo(getMoneyExact(name)) < 0;
|
||||
/**
|
||||
* @param name Name of the user
|
||||
* @param amount The amount of money the user should have
|
||||
* @return true, if the user has more or an equal amount of money
|
||||
* @throws UserDoesNotExistException If a user by that name does not exist
|
||||
* @throws ArithmeticException
|
||||
* @deprecated Usernames can change, use {@link Economy#hasEnough(UUID, BigDecimal)} or {@link Economy#hasEnough(User, BigDecimal)}
|
||||
*/
|
||||
public static boolean hasEnough(final String name, final BigDecimal amount) throws UserDoesNotExistException, ArithmeticException {
|
||||
final User user = getUserByName(name);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(name);
|
||||
}
|
||||
return hasEnough(user, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uuid UUID of the user
|
||||
* @param amount The amount of money the user should have
|
||||
* @return true, if the user has more or an equal amount of money
|
||||
* @throws UserDoesNotExistException If a user by that UUID does not exist
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
public static boolean hasEnough(final UUID uuid, final BigDecimal amount) throws ArithmeticException, UserDoesNotExistException {
|
||||
final User user = getUserByUUID(uuid);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(uuid);
|
||||
}
|
||||
return hasEnough(user, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param user User
|
||||
* @param amount The amount of money the user should have
|
||||
* @return true, if the user has more or an equal amount of money
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
public static boolean hasEnough(final User user, final BigDecimal amount) throws ArithmeticException {
|
||||
if (user == null) {
|
||||
throw new IllegalArgumentException("Economy user cannot be null");
|
||||
}
|
||||
return amount.compareTo(getMoneyExact(user)) <= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name Name of the user
|
||||
* @param amount The amount of money the user should have
|
||||
* @return true, if the user has more money
|
||||
* @throws UserDoesNotExistException If a user by that name does not exists
|
||||
* @deprecated Use {@link Economy#hasMore(UUID, BigDecimal)} or {@link Economy#hasMore(User, BigDecimal)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean hasMore(final String name, final double amount) throws UserDoesNotExistException {
|
||||
try {
|
||||
return hasMore(name, BigDecimal.valueOf(amount));
|
||||
} catch (final ArithmeticException e) {
|
||||
logger.log(Level.WARNING, "Failed to compare balance of " + name + " with " + amount + ": " + e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name Name of the user
|
||||
* @param amount The amount of money the user should have
|
||||
* @return true, if the user has more money
|
||||
* @throws UserDoesNotExistException If a user by that name does not exists
|
||||
* @throws ArithmeticException
|
||||
* @deprecated Usernames can change, use {@link Economy#hasMore(UUID, BigDecimal)} or {@link Economy#hasMore(User, BigDecimal)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean hasMore(final String name, final BigDecimal amount) throws UserDoesNotExistException, ArithmeticException {
|
||||
final User user = getUserByName(name);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(name);
|
||||
}
|
||||
return hasMore(user, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uuid UUID of the user
|
||||
* @param amount The amount of money the user should have
|
||||
* @return true, if the user has more money
|
||||
* @throws UserDoesNotExistException If a user by that UUID does not exists
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
public static boolean hasMore(final UUID uuid, final BigDecimal amount) throws ArithmeticException, UserDoesNotExistException {
|
||||
final User user = getUserByUUID(uuid);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(uuid);
|
||||
}
|
||||
return hasMore(user, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param user User
|
||||
* @param amount The amount of money the user should have
|
||||
* @return true, if the user has more money
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
public static boolean hasMore(final User user, final BigDecimal amount) throws ArithmeticException {
|
||||
if (user == null) {
|
||||
throw new IllegalArgumentException("Economy user cannot be null");
|
||||
}
|
||||
return amount.compareTo(getMoneyExact(user)) < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name Name of the user
|
||||
* @param amount The amount of money the user should not have
|
||||
*
|
||||
* @return true, if the user has less money
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exists
|
||||
* @deprecated Use {@link Economy#hasLess(UUID, BigDecimal)} or {@link Economy#hasLess(User, BigDecimal)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean hasLess(String name, double amount) throws UserDoesNotExistException {
|
||||
public static boolean hasLess(final String name, final double amount) throws UserDoesNotExistException {
|
||||
try {
|
||||
return hasLess(name, BigDecimal.valueOf(amount));
|
||||
} catch (ArithmeticException e) {
|
||||
} catch (final ArithmeticException e) {
|
||||
logger.log(Level.WARNING, "Failed to compare balance of " + name + " with " + amount + ": " + e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasLess(String name, BigDecimal amount) throws UserDoesNotExistException, ArithmeticException {
|
||||
return amount.compareTo(getMoneyExact(name)) > 0;
|
||||
/**
|
||||
* @param name Name of the user
|
||||
* @param amount The amount of money the user should not have
|
||||
* @return true, if the user has less money
|
||||
* @throws UserDoesNotExistException If a user by that name does not exist
|
||||
* @throws ArithmeticException
|
||||
* @deprecated Usernames can change, use {@link Economy#hasLess(UUID, BigDecimal)} or {@link Economy#hasLess(User, BigDecimal)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean hasLess(final String name, final BigDecimal amount) throws UserDoesNotExistException, ArithmeticException {
|
||||
final User user = getUserByName(name);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(name);
|
||||
}
|
||||
return hasLess(user, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uuid UUID of the user
|
||||
* @param amount The amount of money the user should not have
|
||||
* @return true, if the user has less money
|
||||
* @throws UserDoesNotExistException If a user by that UUID does not exist
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
public static boolean hasLess(final UUID uuid, final BigDecimal amount) throws ArithmeticException, UserDoesNotExistException {
|
||||
final User user = getUserByUUID(uuid);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(uuid);
|
||||
}
|
||||
return hasLess(user, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param user User
|
||||
* @param amount The amount of money the user should not have
|
||||
* @return true, if the user has less money
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
public static boolean hasLess(final User user, final BigDecimal amount) throws ArithmeticException {
|
||||
if (user == null) {
|
||||
throw new IllegalArgumentException("Economy user cannot be null");
|
||||
}
|
||||
return amount.compareTo(getMoneyExact(user)) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the user has a negative balance
|
||||
*
|
||||
* @param name Name of the user
|
||||
*
|
||||
* @return true, if the user has a negative balance
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exists
|
||||
* @deprecated Usernames can change, use {@link Economy#isNegative(UUID)} or {@link Economy#isNegative(User)}
|
||||
*/
|
||||
public static boolean isNegative(String name) throws UserDoesNotExistException {
|
||||
return getMoneyExact(name).signum() < 0;
|
||||
@Deprecated
|
||||
public static boolean isNegative(final String name) throws UserDoesNotExistException {
|
||||
final User user = getUserByName(name);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(name);
|
||||
}
|
||||
return isNegative(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the user has a negative balance
|
||||
*
|
||||
* @param uuid UUID of the user
|
||||
* @return true, if the user has a negative balance
|
||||
* @throws UserDoesNotExistException If a user by that UUID does not exists
|
||||
*/
|
||||
public static boolean isNegative(final UUID uuid) throws UserDoesNotExistException {
|
||||
final User user = getUserByUUID(uuid);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(uuid);
|
||||
}
|
||||
return isNegative(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the user has a negative balance
|
||||
*
|
||||
* @param user User
|
||||
* @return true, if the user has a negative balance
|
||||
*/
|
||||
public static boolean isNegative(final User user) {
|
||||
if (user == null) {
|
||||
throw new IllegalArgumentException("Economy user cannot be null");
|
||||
}
|
||||
return getMoneyExact(user).signum() < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the amount of money like all other Essentials functions. Example: $100000 or $12345.67
|
||||
*
|
||||
* @param amount The amount of money
|
||||
*
|
||||
* @return Formatted money
|
||||
* @deprecated Use {@link #format(BigDecimal)} if your input is already a {@link BigDecimal}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static String format(double amount) {
|
||||
public static String format(final double amount) {
|
||||
try {
|
||||
return format(BigDecimal.valueOf(amount));
|
||||
} catch (NumberFormatException e) {
|
||||
} catch (final NumberFormatException e) {
|
||||
logger.log(Level.WARNING, "Failed to display " + amount + ": " + e.getMessage(), e);
|
||||
return "NaN";
|
||||
}
|
||||
}
|
||||
|
||||
public static String format(BigDecimal amount) {
|
||||
/**
|
||||
* Formats the amount of money like all other Essentials functions. Example: $100000 or $12345.67
|
||||
*
|
||||
* @param amount The amount of money
|
||||
* @return Formatted money
|
||||
*/
|
||||
public static String format(final BigDecimal amount) {
|
||||
if (ess == null) {
|
||||
throw new RuntimeException(noCallBeforeLoad);
|
||||
}
|
||||
@@ -370,24 +834,33 @@ public class Economy {
|
||||
* Test if a player exists to avoid the UserDoesNotExistException
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @return true, if the user exists
|
||||
* @deprecated Essentials is moving away from username based economy methods. This may be removed in the future.
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean playerExists(final String name) {
|
||||
return getUserByName(name) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a player exists to avoid the UserDoesNotExistException
|
||||
*
|
||||
* @param uuid UUID of the user
|
||||
* @return true, if the user exists
|
||||
*/
|
||||
public static boolean playerExists(String name) {
|
||||
return getUserByName(name) != null;
|
||||
public static boolean playerExists(final UUID uuid) {
|
||||
return getUserByUUID(uuid) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a player is a npc
|
||||
*
|
||||
* @param name Name of the player
|
||||
*
|
||||
* @return true, if it's a npc
|
||||
*
|
||||
* @throws UserDoesNotExistException
|
||||
*/
|
||||
public static boolean isNPC(String name) throws UserDoesNotExistException {
|
||||
User user = getUserByName(name);
|
||||
public static boolean isNPC(final String name) throws UserDoesNotExistException {
|
||||
final User user = getUserByName(name);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(name);
|
||||
}
|
||||
@@ -398,11 +871,10 @@ public class Economy {
|
||||
* Creates dummy files for a npc, if there is no player yet with that name.
|
||||
*
|
||||
* @param name Name of the player
|
||||
*
|
||||
* @return true, if a new npc was created
|
||||
*/
|
||||
public static boolean createNPC(String name) {
|
||||
User user = getUserByName(name);
|
||||
public static boolean createNPC(final String name) {
|
||||
final User user = getUserByName(name);
|
||||
if (user == null) {
|
||||
createNPCFile(name);
|
||||
return true;
|
||||
@@ -414,11 +886,10 @@ public class Economy {
|
||||
* Deletes a user, if it is marked as npc.
|
||||
*
|
||||
* @param name Name of the player
|
||||
*
|
||||
* @throws UserDoesNotExistException
|
||||
*/
|
||||
public static void removeNPC(String name) throws UserDoesNotExistException {
|
||||
User user = getUserByName(name);
|
||||
public static void removeNPC(final String name) throws UserDoesNotExistException {
|
||||
final User user = getUserByName(name);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(name);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
package com.earth2me.essentials.api;
|
||||
|
||||
import com.earth2me.essentials.Trade;
|
||||
import net.ess3.api.IUser;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* Manages EssentialsX's teleport functionality for a player.
|
||||
* Use this if you want to access EssentialsX's async/safe teleport functionality and teleport warmups and cooldowns.
|
||||
*/
|
||||
public interface IAsyncTeleport {
|
||||
|
||||
/**
|
||||
* Used to skip teleportPlayer delay when teleporting someone to a location or player.
|
||||
*
|
||||
* @param loc - Where should the player end up
|
||||
* @param cooldown - If cooldown should be enforced
|
||||
* @param cause - The reported teleportPlayer cause
|
||||
* @param future - Future which is completed with the success status of the execution
|
||||
*/
|
||||
void now(Location loc, boolean cooldown, PlayerTeleportEvent.TeleportCause cause, CompletableFuture<Boolean> future);
|
||||
|
||||
/**
|
||||
* Used to skip teleportPlayer delay when teleporting someone to a location or player.
|
||||
*
|
||||
* @param entity - Where should the player end up
|
||||
* @param cooldown - If cooldown should be enforced
|
||||
* @param cause - The reported teleportPlayer cause
|
||||
* @param future - Future which is completed with the success status of the execution
|
||||
*/
|
||||
void now(Player entity, boolean cooldown, PlayerTeleportEvent.TeleportCause cause, CompletableFuture<Boolean> future);
|
||||
|
||||
/**
|
||||
* Teleport a player to a specific location
|
||||
*
|
||||
* @param loc - Where should the player end up
|
||||
* @param chargeFor - What the user will be charged if teleportPlayer is successful
|
||||
* @param cause - The reported teleportPlayer cause.
|
||||
* @param future - Future which is completed with the success status of the execution
|
||||
*/
|
||||
void teleport(Location loc, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause, CompletableFuture<Boolean> future);
|
||||
|
||||
/**
|
||||
* Teleport a player to a specific player
|
||||
*
|
||||
* @param entity - Where should the player end up
|
||||
* @param chargeFor - What the user will be charged if teleportPlayer is successful
|
||||
* @param cause - The reported teleportPlayer cause
|
||||
* @param future - Future which is completed with the success status of the execution
|
||||
*/
|
||||
void teleport(Player entity, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause, CompletableFuture<Boolean> future);
|
||||
|
||||
/**
|
||||
* Teleport a player to a specific location
|
||||
*
|
||||
* @param otherUser - Which user will be teleported
|
||||
* @param loc - Where should the player end up
|
||||
* @param chargeFor - What the user will be charged if teleportPlayer is successful
|
||||
* @param cause - The reported teleportPlayer cause
|
||||
* @param future - Future which is completed with the success status of the execution
|
||||
*/
|
||||
void teleportPlayer(IUser otherUser, Location loc, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause, CompletableFuture<Boolean> future);
|
||||
|
||||
/**
|
||||
* Teleport a player to a specific player
|
||||
*
|
||||
* @param otherUser - Which user will be teleported
|
||||
* @param entity - Where should the player end up
|
||||
* @param chargeFor - What the user will be charged if teleportPlayer is successful
|
||||
* @param cause - The reported teleportPlayer cause
|
||||
* @param future - Future which is completed with the success status of the execution
|
||||
*/
|
||||
void teleportPlayer(IUser otherUser, Player entity, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause, CompletableFuture<Boolean> future);
|
||||
|
||||
/**
|
||||
* Teleport wrapper used to handle tp fallback on /jail and /home
|
||||
*
|
||||
* @param chargeFor - What the user will be charged if teleportPlayer is successful
|
||||
* @param cause - The reported teleportPlayer cause
|
||||
* @param future - Future which is completed with the success status of the execution
|
||||
*/
|
||||
void respawn(final Trade chargeFor, PlayerTeleportEvent.TeleportCause cause, CompletableFuture<Boolean> future);
|
||||
|
||||
/**
|
||||
* Teleport wrapper used to handle /warp teleports
|
||||
*
|
||||
* @param otherUser - Which user will be teleported
|
||||
* @param warp - The name of the warp the user will be teleported too.
|
||||
* @param chargeFor - What the user will be charged if teleportPlayer is successful
|
||||
* @param cause - The reported teleportPlayer cause
|
||||
* @param future - Future which is completed with the success status of the execution
|
||||
*/
|
||||
void warp(IUser otherUser, String warp, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause, CompletableFuture<Boolean> future);
|
||||
|
||||
/**
|
||||
* Teleport wrapper used to handle /back teleports
|
||||
*
|
||||
* @param chargeFor - What the user will be charged if teleportPlayer is successful
|
||||
* @param future - Future which is completed with the success status of the execution
|
||||
*/
|
||||
void back(Trade chargeFor, CompletableFuture<Boolean> future);
|
||||
|
||||
/**
|
||||
* Teleport wrapper used to handle /back teleports that
|
||||
* are executed by a different player with this
|
||||
* instance of teleport as a target.
|
||||
*
|
||||
* @param teleporter - The user performing the /back command.
|
||||
* This value may be {@code null} to indicate console.
|
||||
* @param chargeFor - What the {@code teleporter} will be charged if teleportPlayer is successful
|
||||
* @param future - Future which is completed with the success status of the execution
|
||||
*/
|
||||
void back(IUser teleporter, Trade chargeFor, CompletableFuture<Boolean> future);
|
||||
|
||||
/**
|
||||
* Teleport wrapper used to handle throwing user home after a jail sentence
|
||||
*
|
||||
* @param future - Future which is completed with the success status of the execution
|
||||
*/
|
||||
void back(CompletableFuture<Boolean> future);
|
||||
|
||||
}
|
||||
@@ -1,8 +1,16 @@
|
||||
package com.earth2me.essentials.api;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
|
||||
/**
|
||||
* Provides access to the current locale in use.
|
||||
*
|
||||
* @deprecated External plugins should prefer to use either the player's client language ({@link Player#getLocale()} or
|
||||
* {@link net.ess3.api.II18n} in case of future additions.
|
||||
*/
|
||||
@Deprecated
|
||||
public interface II18n {
|
||||
/**
|
||||
* Gets the current locale setting
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
package com.earth2me.essentials.api;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import net.ess3.api.IEssentials;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
@@ -13,13 +11,19 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
|
||||
/**
|
||||
* Provides access to the current item alias registry.
|
||||
*
|
||||
* @deprecated External plugins should use {@link net.ess3.api.IItemDb} instead, which includes access to {@link net.ess3.api.IItemDb.ItemResolver}
|
||||
* APIs.
|
||||
*/
|
||||
@Deprecated
|
||||
public interface IItemDb {
|
||||
|
||||
/**
|
||||
* Create a stack from the given name with the given quantity.
|
||||
*
|
||||
* @param name Item name to look up in the database
|
||||
* @param name Item name to look up in the database
|
||||
* @param quantity Quantity of the item stack
|
||||
* @return The requested item stack
|
||||
* @throws Exception if the item stack cannot be created
|
||||
@@ -32,7 +36,7 @@ public interface IItemDb {
|
||||
|
||||
/**
|
||||
* Create a stack from the given name with the maximum stack size for that material.
|
||||
*
|
||||
* <p>
|
||||
* Note that this will always check against resolver functions from other plugins as well.
|
||||
* To avoid this behaviour, use net.ess3.api.IItemDb#get(String name, boolean useResolvers).
|
||||
*
|
||||
@@ -48,14 +52,14 @@ public interface IItemDb {
|
||||
* @param item Item stack whose names to find
|
||||
* @return Comma-separated list of up to 15 item names
|
||||
*/
|
||||
default String names(ItemStack item) {
|
||||
default String names(final ItemStack item) {
|
||||
List<String> nameList = nameList(item);
|
||||
|
||||
if (nameList.size() > 15) {
|
||||
nameList = nameList.subList(0, 14);
|
||||
}
|
||||
return StringUtil.joinList(", ", nameList);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a List of all aliases for the given item stack.
|
||||
@@ -85,13 +89,12 @@ public interface IItemDb {
|
||||
List<ItemStack> getMatching(User user, String[] args) throws Exception;
|
||||
|
||||
/**
|
||||
* Serialise an ItemStack into a format that can be decoded by
|
||||
* {@link #get(String) get} and
|
||||
* {@link com.earth2me.essentials.MetaItemStack#parseStringMeta(CommandSource, boolean, String[], int, IEssentials)} MetaItemStack#parseStringMeta}.
|
||||
* Used to encode items for kits.
|
||||
* Converts the given {@link ItemStack} to a string representation that can be saved.
|
||||
* This is typically used for /createkit but can be used by other plugins for various purposes too.
|
||||
* Note that this will try registered resolvers first - to avoid this, use {@link net.ess3.api.IItemDb#serialize(ItemStack, boolean)} instead.
|
||||
*
|
||||
* @param is Stack to serialise
|
||||
* @return Serialised stack
|
||||
* @param is The stack to serialize
|
||||
* @return A string representing the given stack
|
||||
*/
|
||||
String serialize(ItemStack is);
|
||||
|
||||
@@ -110,7 +113,7 @@ public interface IItemDb {
|
||||
* @return Updated material
|
||||
*/
|
||||
@Deprecated
|
||||
default Material getFromLegacyId(int id) {
|
||||
default Material getFromLegacyId(final int id) {
|
||||
return getFromLegacy(id, (byte) 0);
|
||||
}
|
||||
|
||||
@@ -130,11 +133,13 @@ public interface IItemDb {
|
||||
* item IDs to modern names.
|
||||
*
|
||||
* @param item Legacy ID in colon syntax.
|
||||
* @return
|
||||
* @return Material if an appropriate material exists, else null.
|
||||
*/
|
||||
default Material getFromLegacy(String item) {
|
||||
default Material getFromLegacy(final String item) {
|
||||
final String[] split = item.split(":");
|
||||
|
||||
if (!NumberUtil.isInt(split[0])) return null;
|
||||
|
||||
final int id = Integer.parseInt(split[0]);
|
||||
byte damage = 0;
|
||||
|
||||
@@ -149,7 +154,7 @@ public interface IItemDb {
|
||||
* Convert legacy ID and damage value to Material. Used for conversion from item IDs to
|
||||
* modern names.
|
||||
*
|
||||
* @param id Legacy ID
|
||||
* @param id Legacy ID
|
||||
* @param damage Damage value
|
||||
* @return Material
|
||||
*/
|
||||
|
||||
@@ -4,16 +4,20 @@ import net.ess3.api.IUser;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
|
||||
/**
|
||||
* Provides access to the storage of jail locations. Maintainers should add methods to <i>this interface</i>.
|
||||
*
|
||||
* @deprecated External plugins should use {@link net.ess3.api.IJails} instead of this interface in case future APIs are added.
|
||||
*/
|
||||
@Deprecated
|
||||
public interface IJails extends IReload {
|
||||
/**
|
||||
* Gets the location of the jail with the given name
|
||||
*
|
||||
* @param jailName The name of the jail
|
||||
*
|
||||
* @return the location of the jail
|
||||
*
|
||||
* @throws Exception if the jail does not exist
|
||||
*/
|
||||
Location getJail(String jailName) throws Exception;
|
||||
@@ -22,7 +26,6 @@ public interface IJails extends IReload {
|
||||
* Gets a list of jails by names
|
||||
*
|
||||
* @return a list of jails, if there are none the list will be empty
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
Collection<String> getList() throws Exception;
|
||||
@@ -38,7 +41,6 @@ public interface IJails extends IReload {
|
||||
* Remove the jail with the given name
|
||||
*
|
||||
* @param jail the jail to remove
|
||||
*
|
||||
* @throws Exception if the jail does not exist
|
||||
*/
|
||||
void removeJail(String jail) throws Exception;
|
||||
@@ -48,17 +50,27 @@ public interface IJails extends IReload {
|
||||
*
|
||||
* @param user the user to send to jail
|
||||
* @param jail the jail to send the user to
|
||||
* @throws Exception if the user is offline or jail does not exist
|
||||
* @deprecated Use {@link IJails#sendToJail(IUser, String, CompletableFuture)}
|
||||
*/
|
||||
@Deprecated
|
||||
void sendToJail(IUser user, String jail) throws Exception;
|
||||
|
||||
/**
|
||||
* Attempts to send the given user to the given jail
|
||||
*
|
||||
* @param user the user to send to jail
|
||||
* @param jail the jail to send the user to
|
||||
* @param future Future which is completed with the success status of the execution
|
||||
* @throws Exception if the user is offline or jail does not exist
|
||||
*/
|
||||
void sendToJail(IUser user, String jail) throws Exception;
|
||||
void sendToJail(IUser user, String jail, CompletableFuture<Boolean> future) throws Exception;
|
||||
|
||||
/**
|
||||
* Set a new jail with the given name and location
|
||||
*
|
||||
* @param jailName the name of the jail being set
|
||||
* @param loc the location of the jail being set
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
void setJail(String jailName, Location loc) throws Exception;
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
package com.earth2me.essentials.api;
|
||||
|
||||
|
||||
/**
|
||||
* Represents a storage object that is reloadable.
|
||||
*
|
||||
* @deprecated This is a remnant of the abandoned 3.x storage system. Neither future 2.x code nor external plugins
|
||||
* should use this interface.
|
||||
*/
|
||||
@Deprecated
|
||||
public interface IReload {
|
||||
/**
|
||||
* Reloads the given storage object.
|
||||
*/
|
||||
void onReload();
|
||||
}
|
||||
@@ -6,7 +6,9 @@ import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated This API is not asynchronous and is no longer maintained. Use {@link com.earth2me.essentials.api.IAsyncTeleport IAsyncTeleport}.
|
||||
*/
|
||||
public interface ITeleport {
|
||||
/**
|
||||
* Used to skip teleportPlayer delay when teleporting someone to a location or player.
|
||||
@@ -14,9 +16,9 @@ public interface ITeleport {
|
||||
* @param loc - Where should the player end up
|
||||
* @param cooldown - If cooldown should be enforced
|
||||
* @param cause - The reported teleportPlayer cause
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Deprecated
|
||||
void now(Location loc, boolean cooldown, PlayerTeleportEvent.TeleportCause cause) throws Exception;
|
||||
|
||||
/**
|
||||
@@ -25,11 +27,18 @@ public interface ITeleport {
|
||||
* @param entity - Where should the player end up
|
||||
* @param cooldown - If cooldown should be enforced
|
||||
* @param cause - The reported teleportPlayer cause
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Deprecated
|
||||
void now(Player entity, boolean cooldown, PlayerTeleportEvent.TeleportCause cause) throws Exception;
|
||||
|
||||
/**
|
||||
* Teleport a player to a specific location
|
||||
*
|
||||
* @param loc - Where should the player end up
|
||||
* @param chargeFor - What the user will be charged if teleportPlayer is successful
|
||||
* @throws Exception
|
||||
*/
|
||||
@Deprecated
|
||||
void teleport(Location loc, Trade chargeFor) throws Exception;
|
||||
|
||||
@@ -39,9 +48,9 @@ public interface ITeleport {
|
||||
* @param loc - Where should the player end up
|
||||
* @param chargeFor - What the user will be charged if teleportPlayer is successful
|
||||
* @param cause - The reported teleportPlayer cause
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Deprecated
|
||||
void teleport(Location loc, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause) throws Exception;
|
||||
|
||||
/**
|
||||
@@ -50,9 +59,9 @@ public interface ITeleport {
|
||||
* @param entity - Where should the player end up
|
||||
* @param chargeFor - What the user will be charged if teleportPlayer is successful
|
||||
* @param cause - The reported teleportPlayer cause
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Deprecated
|
||||
void teleport(Player entity, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause) throws Exception;
|
||||
|
||||
/**
|
||||
@@ -62,9 +71,9 @@ public interface ITeleport {
|
||||
* @param loc - Where should the player end up
|
||||
* @param chargeFor - What the user will be charged if teleportPlayer is successful
|
||||
* @param cause - The reported teleportPlayer cause
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Deprecated
|
||||
void teleportPlayer(IUser otherUser, Location loc, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause) throws Exception;
|
||||
|
||||
/**
|
||||
@@ -74,9 +83,9 @@ public interface ITeleport {
|
||||
* @param entity - Where should the player end up
|
||||
* @param chargeFor - What the user will be charged if teleportPlayer is successful
|
||||
* @param cause - The reported teleportPlayer cause
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Deprecated
|
||||
void teleportPlayer(IUser otherUser, Player entity, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause) throws Exception;
|
||||
|
||||
/**
|
||||
@@ -84,9 +93,9 @@ public interface ITeleport {
|
||||
*
|
||||
* @param chargeFor - What the user will be charged if teleportPlayer is successful
|
||||
* @param cause - The reported teleportPlayer cause
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Deprecated
|
||||
void respawn(final Trade chargeFor, PlayerTeleportEvent.TeleportCause cause) throws Exception;
|
||||
|
||||
/**
|
||||
@@ -96,18 +105,18 @@ public interface ITeleport {
|
||||
* @param warp - The name of the warp the user will be teleported too.
|
||||
* @param chargeFor - What the user will be charged if teleportPlayer is successful
|
||||
* @param cause - The reported teleportPlayer cause
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Deprecated
|
||||
void warp(IUser otherUser, String warp, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause) throws Exception;
|
||||
|
||||
/**
|
||||
* Teleport wrapper used to handle /back teleports
|
||||
*
|
||||
* @param chargeFor - What the user will be charged if teleportPlayer is successful
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Deprecated
|
||||
void back(Trade chargeFor) throws Exception;
|
||||
|
||||
/**
|
||||
@@ -117,10 +126,10 @@ public interface ITeleport {
|
||||
*
|
||||
* @param teleporter - The user performing the /back command.
|
||||
* This value may be {@code null} to indicate console.
|
||||
* @param chargeFor - What the {@code teleporter} will be charged if teleportPlayer is successful
|
||||
*
|
||||
* @param chargeFor - What the {@code teleporter} will be charged if teleportPlayer is successful
|
||||
* @throws Exception
|
||||
*/
|
||||
@Deprecated
|
||||
void back(IUser teleporter, Trade chargeFor) throws Exception;
|
||||
|
||||
/**
|
||||
@@ -128,6 +137,7 @@ public interface ITeleport {
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Deprecated
|
||||
void back() throws Exception;
|
||||
|
||||
}
|
||||
@@ -9,17 +9,20 @@ import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
|
||||
|
||||
/**
|
||||
* Provides access to the storage of warp locations. Maintainers should add methods to <i>this interface</i>.
|
||||
*
|
||||
* @deprecated External plugins should use {@link net.ess3.api.IWarps} instead of this interface, in case future APIs are added.
|
||||
*/
|
||||
@Deprecated
|
||||
public interface IWarps extends IConf {
|
||||
/**
|
||||
* Get a warp by name
|
||||
*
|
||||
* @param warp - Warp name
|
||||
*
|
||||
* @return - Location the warp is set to
|
||||
*
|
||||
* @throws WarpNotFoundException When the warp is not found
|
||||
* @throws InvalidWorldException When the world the warp is in is not found
|
||||
* @throws net.ess3.api.InvalidWorldException When the world the warp is in is not found
|
||||
*/
|
||||
Location getWarp(String warp) throws WarpNotFoundException, net.ess3.api.InvalidWorldException;
|
||||
|
||||
@@ -41,7 +44,6 @@ public interface IWarps extends IConf {
|
||||
* Delete a warp from the warp DB
|
||||
*
|
||||
* @param name - Name of warp
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
void removeWarp(String name) throws Exception;
|
||||
@@ -51,7 +53,6 @@ public interface IWarps extends IConf {
|
||||
*
|
||||
* @param name - Name of warp
|
||||
* @param loc - Location of warp
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
void setWarp(String name, Location loc) throws Exception;
|
||||
@@ -62,19 +63,18 @@ public interface IWarps extends IConf {
|
||||
* @param user - User of warp
|
||||
* @param name - Name of warp
|
||||
* @param loc - Location of warp
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
void setWarp(IUser user, String name, Location loc) throws Exception;
|
||||
|
||||
|
||||
/**
|
||||
* Gets Lastowner UUID
|
||||
*
|
||||
* @param name - Name of warp
|
||||
*
|
||||
* @param warp - Name of warp
|
||||
* @throws WarpNotFoundException
|
||||
*/
|
||||
UUID getLastOwner(String warp) throws WarpNotFoundException;
|
||||
|
||||
/**
|
||||
* Check to see if the file is empty
|
||||
*
|
||||
@@ -83,13 +83,8 @@ public interface IWarps extends IConf {
|
||||
boolean isEmpty();
|
||||
|
||||
/**
|
||||
* Get a warp file note: this is not yet implemented, as 3.x uses different storage methods
|
||||
*
|
||||
* @param name - name of file
|
||||
*
|
||||
* @return - an instance of the file
|
||||
*
|
||||
* @throws InvalidNameException - When the file is not found
|
||||
* @deprecated This method relates to the abandoned 3.x storage refactor and is not implemented.
|
||||
*/
|
||||
@Deprecated
|
||||
File getWarpFile(String name) throws net.ess3.api.InvalidNameException;
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
package com.earth2me.essentials.api;
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated This exception relates to the abandoned 3.x storage refactor and is not implemented.
|
||||
*/
|
||||
@Deprecated
|
||||
public class InvalidNameException extends Exception {
|
||||
/**
|
||||
* NOTE: This is not implemented yet, just here for future 3.x api support Allow serialization of the
|
||||
@@ -8,7 +11,7 @@ public class InvalidNameException extends Exception {
|
||||
*/
|
||||
private static final long serialVersionUID = 1485321420293663139L;
|
||||
|
||||
public InvalidNameException(Throwable thrwbl) {
|
||||
public InvalidNameException(final Throwable thrwbl) {
|
||||
super(thrwbl);
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,10 @@ package com.earth2me.essentials.api;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated This exception is unused. Use {@link net.ess3.api.InvalidWorldException} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public class InvalidWorldException extends Exception {
|
||||
private final String world;
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.earth2me.essentials.api;
|
||||
|
||||
|
||||
/**
|
||||
* Thrown when a user does not have the balance for a transaction and cannot take a loan.
|
||||
*/
|
||||
public class NoLoanPermittedException extends net.ess3.api.NoLoanPermittedException {
|
||||
|
||||
}
|
||||
@@ -1,10 +1,18 @@
|
||||
package com.earth2me.essentials.api;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
/**
|
||||
* Thrown when the requested user does not exist.
|
||||
*/
|
||||
public class UserDoesNotExistException extends Exception {
|
||||
public UserDoesNotExistException(String name) {
|
||||
public UserDoesNotExistException(final String name) {
|
||||
super(tl("userDoesNotExist", name));
|
||||
}
|
||||
|
||||
public UserDoesNotExistException(final UUID uuid) {
|
||||
super(tl("uuidDoesNotExist", uuid.toString()));
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@ package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.DateUtil;
|
||||
import net.ess3.api.events.AfkStatusChangeEvent;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -9,49 +11,48 @@ import java.util.List;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandafk extends EssentialsCommand {
|
||||
public Commandafk() {
|
||||
super("afk");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(Server server, User user, String commandLabel, String[] args) throws Exception {
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length > 0 && user.isAuthorized("essentials.afk.others")) {
|
||||
User afkUser = user; // if no player found, but message specified, set command executor to target user
|
||||
String message;
|
||||
try {
|
||||
afkUser = getPlayer(server, user, args, 0);
|
||||
message = args.length > 1 ? getFinalArg(args, 1) : null;
|
||||
} catch (PlayerNotFoundException e) {
|
||||
// If only one arg is passed, assume the command executor is targeting another player.
|
||||
if (args.length == 1) {
|
||||
throw e;
|
||||
}
|
||||
} catch (final PlayerNotFoundException e) {
|
||||
message = getFinalArg(args, 0);
|
||||
}
|
||||
toggleAfk(user, afkUser, message);
|
||||
} else {
|
||||
String message = args.length > 0 ? getFinalArg(args, 0) : null;
|
||||
final String message = args.length > 0 ? getFinalArg(args, 0) : null;
|
||||
toggleAfk(user, user, message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(Server server, CommandSource sender, String commandLabel, String[] args) throws Exception {
|
||||
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length > 0) {
|
||||
User afkUser = getPlayer(server, args, 0, true, false);
|
||||
String message = args.length > 1 ? getFinalArg(args, 1) : null;
|
||||
final User afkUser = getPlayer(server, args, 0, true, false);
|
||||
final String message = args.length > 1 ? getFinalArg(args, 1) : null;
|
||||
toggleAfk(null, afkUser, message);
|
||||
} else {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
}
|
||||
|
||||
private void toggleAfk(User sender, User user, String message) throws Exception {
|
||||
private void toggleAfk(final User sender, final User user, final String message) throws Exception {
|
||||
if (message != null && sender != null) {
|
||||
if (sender.isMuted()) {
|
||||
throw new Exception(sender.hasMuteReason() ? tl("voiceSilencedReason", sender.getMuteReason()) : tl("voiceSilenced"));
|
||||
final String dateDiff = sender.getMuteTimeout() > 0 ? DateUtil.formatDateDiff(sender.getMuteTimeout()) : null;
|
||||
if (dateDiff == null) {
|
||||
throw new Exception(sender.hasMuteReason() ? tl("voiceSilencedReason", sender.getMuteReason()) : tl("voiceSilenced"));
|
||||
}
|
||||
throw new Exception(sender.hasMuteReason() ? tl("voiceSilencedReasonTime", dateDiff, sender.getMuteReason()) : tl("voiceSilencedTime", dateDiff));
|
||||
}
|
||||
if (!sender.isAuthorized("essentials.afk.message")) {
|
||||
throw new Exception(tl("noPermToAFKMessage"));
|
||||
@@ -59,41 +60,38 @@ public class Commandafk extends EssentialsCommand {
|
||||
}
|
||||
user.setDisplayNick();
|
||||
String msg = "";
|
||||
if (!user.toggleAfk()) {
|
||||
//user.sendMessage(_("markedAsNotAway"));
|
||||
String selfmsg = "";
|
||||
if (!user.toggleAfk(AfkStatusChangeEvent.Cause.COMMAND)) {
|
||||
if (!user.isHidden()) {
|
||||
msg = tl("userIsNotAway", user.getDisplayName());
|
||||
selfmsg = tl("userIsNotAwaySelf", user.getDisplayName());
|
||||
}
|
||||
user.updateActivity(false);
|
||||
user.updateActivity(false, AfkStatusChangeEvent.Cause.COMMAND);
|
||||
} else {
|
||||
//user.sendMessage(_("markedAsAway"));
|
||||
if (!user.isHidden()) {
|
||||
if (message != null) {
|
||||
msg = tl("userIsAwayWithMessage", user.getDisplayName(), message);
|
||||
selfmsg = tl("userIsAwaySelfWithMessage", user.getDisplayName(), message);
|
||||
} else {
|
||||
msg = tl("userIsAway", user.getDisplayName());
|
||||
selfmsg = tl("userIsAwaySelf", user.getDisplayName());
|
||||
}
|
||||
}
|
||||
user.setAfkMessage(message);
|
||||
}
|
||||
if (!msg.isEmpty()) {
|
||||
ess.broadcastMessage(user, msg);
|
||||
if (!msg.isEmpty() && ess.getSettings().broadcastAfkMessage()) {
|
||||
// exclude user from receiving general AFK announcement in favor of personal message
|
||||
ess.broadcastMessage(user, msg, u -> u == user);
|
||||
}
|
||||
if (!selfmsg.isEmpty()) {
|
||||
user.sendMessage(selfmsg);
|
||||
}
|
||||
user.setDisplayNick(); // Set this again after toggling
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, User user, String commandLabel, String[] args) {
|
||||
if (args.length == 1 && user.isAuthorized("essentials.afk.others")) {
|
||||
return getPlayers(server, user);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, CommandSource sender, String commandLabel, String[] args) {
|
||||
if (args.length == 1) {
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1 && sender.isAuthorized("essentials.afk.others", ess)) {
|
||||
return getPlayers(server, sender);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.User;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class Commandanvil extends EssentialsCommand {
|
||||
|
||||
public Commandanvil() {
|
||||
super("anvil");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run(Server server, User user, String commandLabel, String[] args) throws Exception {
|
||||
if (ess.getContainerProvider() == null) {
|
||||
user.sendMessage(tl("unsupportedBrand"));
|
||||
return;
|
||||
}
|
||||
|
||||
ess.getContainerProvider().openAnvil(user.getBase());
|
||||
}
|
||||
}
|
||||
@@ -4,64 +4,49 @@ import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.Trade;
|
||||
import com.earth2me.essentials.User;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandback extends EssentialsCommand {
|
||||
public Commandback() {
|
||||
super("back");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run(Server server, User user, String commandLabel, String[] args) throws Exception {
|
||||
CommandSource sender = user.getSource();
|
||||
protected void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
final CommandSource sender = user.getSource();
|
||||
if (args.length > 0 && user.isAuthorized("essentials.back.others")) {
|
||||
this.parseCommand(server, sender, args, true);
|
||||
parseOthers(server, sender, args, commandLabel);
|
||||
return;
|
||||
}
|
||||
|
||||
teleportBack(sender, user);
|
||||
teleportBack(sender, user, commandLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run(Server server, CommandSource sender, String commandLabel, String[] args) throws Exception {
|
||||
if (args.length < 1) {
|
||||
protected void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length == 0) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
this.parseCommand(server, sender, args, true);
|
||||
parseOthers(server, sender, args, commandLabel);
|
||||
}
|
||||
|
||||
private void parseCommand(Server server, CommandSource sender, String[] args, boolean allowOthers) throws Exception {
|
||||
Collection<Player> players = new ArrayList<>();
|
||||
|
||||
if (allowOthers && args.length > 0 && args[0].trim().length() > 2) {
|
||||
players = server.matchPlayer(args[0].trim());
|
||||
}
|
||||
|
||||
if (players.size() < 1) {
|
||||
throw new PlayerNotFoundException();
|
||||
}
|
||||
|
||||
for (Player player : players) {
|
||||
sender.sendMessage(tl("backOther", player.getName()));
|
||||
teleportBack(sender, ess.getUser(player));
|
||||
}
|
||||
private void parseOthers(final Server server, final CommandSource sender, final String[] args, final String commandLabel) throws Exception {
|
||||
final User player = getPlayer(server, args, 0, true, false);
|
||||
sender.sendMessage(tl("backOther", player.getName()));
|
||||
teleportBack(sender, player, commandLabel);
|
||||
}
|
||||
|
||||
private void teleportBack(CommandSource sender, User user) throws Exception {
|
||||
private void teleportBack(final CommandSource sender, final User user, final String commandLabel) throws Exception {
|
||||
if (user.getLastLocation() == null) {
|
||||
throw new Exception(tl("noLocationFound"));
|
||||
}
|
||||
|
||||
String lastWorldName = user.getLastLocation().getWorld().getName();
|
||||
final String lastWorldName = user.getLastLocation().getWorld().getName();
|
||||
|
||||
User requester = null;
|
||||
if (sender.isPlayer()) {
|
||||
@@ -77,21 +62,21 @@ public class Commandback extends EssentialsCommand {
|
||||
}
|
||||
|
||||
if (requester == null) {
|
||||
user.getTeleport().back(null, null);
|
||||
user.getAsyncTeleport().back(null, null, getNewExceptionFuture(sender, commandLabel));
|
||||
} else if (!requester.equals(user)) {
|
||||
Trade charge = new Trade(this.getName(), this.ess);
|
||||
final Trade charge = new Trade(this.getName(), this.ess);
|
||||
charge.isAffordableFor(requester);
|
||||
user.getTeleport().back(requester, charge);
|
||||
user.getAsyncTeleport().back(requester, charge, getNewExceptionFuture(sender, commandLabel));
|
||||
} else {
|
||||
Trade charge = new Trade(this.getName(), this.ess);
|
||||
final Trade charge = new Trade(this.getName(), this.ess);
|
||||
charge.isAffordableFor(user);
|
||||
user.getTeleport().back(charge);
|
||||
user.getAsyncTeleport().back(charge, getNewExceptionFuture(sender, commandLabel));
|
||||
}
|
||||
throw new NoChargeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, User user, String commandLabel, String[] args) {
|
||||
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
|
||||
if (user.isAuthorized("essentials.back.others") && args.length == 1) {
|
||||
return getPlayers(server, user);
|
||||
} else {
|
||||
|
||||
@@ -6,7 +6,6 @@ import org.bukkit.Server;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandbackup extends EssentialsCommand {
|
||||
public Commandbackup() {
|
||||
super("backup");
|
||||
|
||||
@@ -5,13 +5,11 @@ import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandbalance extends EssentialsCommand {
|
||||
public Commandbalance() {
|
||||
super("balance");
|
||||
@@ -19,11 +17,11 @@ public class Commandbalance extends EssentialsCommand {
|
||||
|
||||
@Override
|
||||
protected void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length < 1) {
|
||||
if (args.length == 0) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
User target = getPlayer(server, args, 0, true, true);
|
||||
final User target = getPlayer(server, args, 0, false, true);
|
||||
sender.sendMessage(tl("balanceOther", target.isHidden() ? target.getName() : target.getDisplayName(), NumberUtil.displayCurrency(target.getMoney(), ess)));
|
||||
}
|
||||
|
||||
@@ -31,28 +29,17 @@ public class Commandbalance extends EssentialsCommand {
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length == 1 && user.isAuthorized("essentials.balance.others")) {
|
||||
final User target = getPlayer(server, args, 0, true, true);
|
||||
final BigDecimal bal = target.getMoney();
|
||||
user.sendMessage(tl("balanceOther", target.isHidden() ? target.getName() : target.getDisplayName(), NumberUtil.displayCurrency(bal, ess)));
|
||||
user.sendMessage(tl("balanceOther", target.isHidden() ? target.getName() : target.getDisplayName(), NumberUtil.displayCurrency(target.getMoney(), ess)));
|
||||
} else if (args.length < 2) {
|
||||
final BigDecimal bal = user.getMoney();
|
||||
user.sendMessage(tl("balance", NumberUtil.displayCurrency(bal, ess)));
|
||||
user.sendMessage(tl("balance", NumberUtil.displayCurrency(user.getMoney(), ess)));
|
||||
} else {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, User user, String commandLabel, String[] args) {
|
||||
if (args.length == 1 && user.isAuthorized("essentials.balance.others")) {
|
||||
return getPlayers(server, user);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, CommandSource sender, String commandLabel, String[] args) {
|
||||
if (args.length == 1) {
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1 && sender.isAuthorized("essentials.balance.others", ess)) {
|
||||
return getPlayers(server, sender);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
|
||||
@@ -10,23 +10,35 @@ import org.bukkit.Server;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.text.DateFormat;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandbalancetop extends EssentialsCommand {
|
||||
public static final int MINUSERS = 50;
|
||||
private static final int CACHETIME = 2 * 60 * 1000;
|
||||
private static final SimpleTextInput cache = new SimpleTextInput();
|
||||
private static final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
private static long cacheage = 0;
|
||||
|
||||
public Commandbalancetop() {
|
||||
super("balancetop");
|
||||
}
|
||||
|
||||
private static final int CACHETIME = 2 * 60 * 1000;
|
||||
public static final int MINUSERS = 50;
|
||||
private static final SimpleTextInput cache = new SimpleTextInput();
|
||||
private static long cacheage = 0;
|
||||
private static final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
private static void outputCache(final CommandSource sender, final int page) {
|
||||
final Calendar cal = Calendar.getInstance();
|
||||
cal.setTimeInMillis(cacheage);
|
||||
final DateFormat format = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
|
||||
sender.sendMessage(tl("balanceTop", format.format(cal.getTime())));
|
||||
new TextPager(cache).showPage(Integer.toString(page), null, "balancetop", sender);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
@@ -35,7 +47,7 @@ public class Commandbalancetop extends EssentialsCommand {
|
||||
if (args.length > 0) {
|
||||
try {
|
||||
page = Integer.parseInt(args[0]);
|
||||
} catch (NumberFormatException ex) {
|
||||
} catch (final NumberFormatException ex) {
|
||||
if (args[0].equalsIgnoreCase("force") && (!sender.isPlayer() || ess.getUser(sender.getPlayer()).isAuthorized("essentials.balancetop.force"))) {
|
||||
force = true;
|
||||
}
|
||||
@@ -45,7 +57,7 @@ public class Commandbalancetop extends EssentialsCommand {
|
||||
if (!force && lock.readLock().tryLock()) {
|
||||
try {
|
||||
if (cacheage > System.currentTimeMillis() - CACHETIME) {
|
||||
outputCache(sender, commandLabel, page);
|
||||
outputCache(sender, page);
|
||||
return;
|
||||
}
|
||||
if (ess.getUserMap().getUniqueUsers() > MINUSERS) {
|
||||
@@ -54,30 +66,33 @@ public class Commandbalancetop extends EssentialsCommand {
|
||||
} finally {
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
ess.runTaskAsynchronously(new Viewer(sender, commandLabel, page, force));
|
||||
} else {
|
||||
if (ess.getUserMap().getUniqueUsers() > MINUSERS) {
|
||||
sender.sendMessage(tl("orderBalances", ess.getUserMap().getUniqueUsers()));
|
||||
}
|
||||
ess.runTaskAsynchronously(new Viewer(sender, commandLabel, page, force));
|
||||
}
|
||||
ess.runTaskAsynchronously(new Viewer(sender, commandLabel, page, force));
|
||||
|
||||
}
|
||||
|
||||
private static void outputCache(final CommandSource sender, String command, int page) {
|
||||
final Calendar cal = Calendar.getInstance();
|
||||
cal.setTimeInMillis(cacheage);
|
||||
final DateFormat format = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
|
||||
sender.sendMessage(tl("balanceTop", format.format(cal.getTime())));
|
||||
new TextPager(cache).showPage(Integer.toString(page), null, "balancetop", sender);
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
final List<String> options = Lists.newArrayList("1");
|
||||
if (!sender.isPlayer() || ess.getUser(sender.getPlayer()).isAuthorized("essentials.balancetop.force")) {
|
||||
options.add("force");
|
||||
}
|
||||
return options;
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class Calculator implements Runnable {
|
||||
private final transient Viewer viewer;
|
||||
private final boolean force;
|
||||
|
||||
public Calculator(final Viewer viewer, final boolean force) {
|
||||
Calculator(final Viewer viewer, final boolean force) {
|
||||
this.viewer = viewer;
|
||||
this.force = force;
|
||||
}
|
||||
@@ -88,14 +103,14 @@ public class Commandbalancetop extends EssentialsCommand {
|
||||
try {
|
||||
if (force || cacheage <= System.currentTimeMillis() - CACHETIME) {
|
||||
cache.getLines().clear();
|
||||
final Map<String, BigDecimal> balances = new HashMap<String, BigDecimal>();
|
||||
final Map<String, BigDecimal> balances = new HashMap<>();
|
||||
BigDecimal totalMoney = BigDecimal.ZERO;
|
||||
if (ess.getSettings().isEcoDisabled()) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().info("Internal economy functions disabled, aborting baltop.");
|
||||
}
|
||||
} else {
|
||||
for (UUID u : ess.getUserMap().getAllUniqueUsers()) {
|
||||
for (final UUID u : ess.getUserMap().getAllUniqueUsers()) {
|
||||
final User user = ess.getUserMap().getUser(u);
|
||||
if (user != null) {
|
||||
if (!ess.getSettings().isNpcsInBalanceRanking() && user.isNPC()) {
|
||||
@@ -113,18 +128,13 @@ public class Commandbalancetop extends EssentialsCommand {
|
||||
}
|
||||
}
|
||||
|
||||
final List<Map.Entry<String, BigDecimal>> sortedEntries = new ArrayList<Map.Entry<String, BigDecimal>>(balances.entrySet());
|
||||
Collections.sort(sortedEntries, new Comparator<Map.Entry<String, BigDecimal>>() {
|
||||
@Override
|
||||
public int compare(final Entry<String, BigDecimal> entry1, final Entry<String, BigDecimal> entry2) {
|
||||
return entry2.getValue().compareTo(entry1.getValue());
|
||||
}
|
||||
});
|
||||
final List<Map.Entry<String, BigDecimal>> sortedEntries = new ArrayList<>(balances.entrySet());
|
||||
sortedEntries.sort((entry1, entry2) -> entry2.getValue().compareTo(entry1.getValue()));
|
||||
|
||||
cache.getLines().add(tl("serverTotal", NumberUtil.displayCurrency(totalMoney, ess)));
|
||||
int pos = 1;
|
||||
for (Map.Entry<String, BigDecimal> entry : sortedEntries) {
|
||||
cache.getLines().add(pos + ". " + entry.getKey() + ", " + NumberUtil.displayCurrency(entry.getValue(), ess));
|
||||
for (final Map.Entry<String, BigDecimal> entry : sortedEntries) {
|
||||
cache.getLines().add(tl("balanceTopLine", pos, entry.getKey(), NumberUtil.displayCurrency(entry.getValue(), ess)));
|
||||
pos++;
|
||||
}
|
||||
cacheage = System.currentTimeMillis();
|
||||
@@ -136,14 +146,13 @@ public class Commandbalancetop extends EssentialsCommand {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class Viewer implements Runnable {
|
||||
private final transient CommandSource sender;
|
||||
private final transient int page;
|
||||
private final transient boolean force;
|
||||
private final transient String commandLabel;
|
||||
|
||||
public Viewer(final CommandSource sender, final String commandLabel, final int page, final boolean force) {
|
||||
Viewer(final CommandSource sender, final String commandLabel, final int page, final boolean force) {
|
||||
this.sender = sender;
|
||||
this.page = page;
|
||||
this.force = force;
|
||||
@@ -155,7 +164,7 @@ public class Commandbalancetop extends EssentialsCommand {
|
||||
lock.readLock().lock();
|
||||
try {
|
||||
if (!force && cacheage > System.currentTimeMillis() - CACHETIME) {
|
||||
outputCache(sender, commandLabel, page);
|
||||
outputCache(sender, page);
|
||||
return;
|
||||
}
|
||||
} finally {
|
||||
@@ -164,17 +173,4 @@ public class Commandbalancetop extends EssentialsCommand {
|
||||
ess.runTaskAsynchronously(new Calculator(new Viewer(sender, commandLabel, page, false), force));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, CommandSource sender, String commandLabel, String[] args) {
|
||||
if (args.length == 1) {
|
||||
List<String> options = Lists.newArrayList("1");
|
||||
if (!sender.isPlayer() || ess.getUser(sender.getPlayer()).isAuthorized("essentials.balancetop.force")) {
|
||||
options.add("force");
|
||||
}
|
||||
return options;
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,6 @@ import java.util.logging.Level;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandban extends EssentialsCommand {
|
||||
public Commandban() {
|
||||
super("ban");
|
||||
@@ -29,7 +28,7 @@ public class Commandban extends EssentialsCommand {
|
||||
User user;
|
||||
try {
|
||||
user = getPlayer(server, args, 0, true, true);
|
||||
} catch (PlayerNotFoundException e) {
|
||||
} catch (final PlayerNotFoundException e) {
|
||||
nomatch = true;
|
||||
user = ess.getUser(new OfflinePlayer(args[0], ess.getServer()));
|
||||
}
|
||||
@@ -37,14 +36,12 @@ public class Commandban extends EssentialsCommand {
|
||||
if (sender.isPlayer() && !ess.getUser(sender.getPlayer()).isAuthorized("essentials.ban.offline")) {
|
||||
throw new Exception(tl("banExemptOffline"));
|
||||
}
|
||||
} else {
|
||||
if (user.isAuthorized("essentials.ban.exempt") && sender.isPlayer()) {
|
||||
throw new Exception(tl("banExempt"));
|
||||
}
|
||||
} else if (user.isAuthorized("essentials.ban.exempt") && sender.isPlayer()) {
|
||||
throw new Exception(tl("banExempt"));
|
||||
}
|
||||
|
||||
final String senderName = sender.isPlayer() ? sender.getPlayer().getDisplayName() : Console.NAME;
|
||||
String banReason;
|
||||
final String banReason;
|
||||
if (args.length > 1) {
|
||||
banReason = FormatUtil.replaceFormat(getFinalArg(args, 1).replace("\\n", "\n").replace("|", "\n"));
|
||||
} else {
|
||||
@@ -53,7 +50,7 @@ public class Commandban extends EssentialsCommand {
|
||||
|
||||
ess.getServer().getBanList(BanList.Type.NAME).addBan(user.getName(), banReason, null, senderName);
|
||||
|
||||
String banDisplay = tl("banFormat", banReason, senderName);
|
||||
final String banDisplay = tl("banFormat", banReason, senderName);
|
||||
|
||||
user.getBase().kickPlayer(banDisplay);
|
||||
server.getLogger().log(Level.INFO, tl("playerBanned", senderName, user.getName(), banDisplay));
|
||||
@@ -66,7 +63,7 @@ public class Commandban extends EssentialsCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, CommandSource sender, String commandLabel, String[] args) {
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
return getPlayers(server, sender);
|
||||
} else {
|
||||
|
||||
@@ -14,7 +14,6 @@ import java.util.logging.Level;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandbanip extends EssentialsCommand {
|
||||
public Commandbanip() {
|
||||
super("banip");
|
||||
@@ -33,9 +32,9 @@ public class Commandbanip extends EssentialsCommand {
|
||||
ipAddress = args[0];
|
||||
} else {
|
||||
try {
|
||||
User player = getPlayer(server, args, 0, true, true);
|
||||
final User player = getPlayer(server, args, 0, true, true);
|
||||
ipAddress = player.getLastLoginAddress();
|
||||
} catch (PlayerNotFoundException ex) {
|
||||
} catch (final PlayerNotFoundException ex) {
|
||||
ipAddress = args[0];
|
||||
}
|
||||
}
|
||||
@@ -44,19 +43,19 @@ public class Commandbanip extends EssentialsCommand {
|
||||
throw new PlayerNotFoundException();
|
||||
}
|
||||
|
||||
String banReason;
|
||||
final String banReason;
|
||||
if (args.length > 1) {
|
||||
banReason = FormatUtil.replaceFormat(getFinalArg(args, 1).replace("\\n", "\n").replace("|", "\n"));
|
||||
} else {
|
||||
banReason = tl("defaultBanReason");
|
||||
}
|
||||
|
||||
String banDisplay = tl("banFormat", banReason, senderName);
|
||||
final String banDisplay = tl("banFormat", banReason, senderName);
|
||||
|
||||
ess.getServer().getBanList(BanList.Type.IP).addBan(ipAddress, banReason, null, senderName);
|
||||
server.getLogger().log(Level.INFO, tl("playerBanIpAddress", senderName, ipAddress, banReason));
|
||||
|
||||
for (Player player : ess.getServer().getOnlinePlayers()) {
|
||||
for (final Player player : ess.getServer().getOnlinePlayers()) {
|
||||
if (player.getAddress().getAddress().getHostAddress().equalsIgnoreCase(ipAddress)) {
|
||||
player.kickPlayer(banDisplay);
|
||||
}
|
||||
@@ -66,7 +65,7 @@ public class Commandbanip extends EssentialsCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, CommandSource sender, String commandLabel, String[] args) {
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
// TODO: Also list IP addresses?
|
||||
return getPlayers(server, sender);
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.Mob;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class Commandbeezooka extends EssentialsCommand {
|
||||
|
||||
public Commandbeezooka() {
|
||||
super("beezooka");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_15_R01)) {
|
||||
user.sendMessage(tl("unsupportedFeature"));
|
||||
return;
|
||||
}
|
||||
|
||||
final Entity bee = Mob.BEE.spawn(user.getWorld(), server, user.getBase().getEyeLocation());
|
||||
bee.setVelocity(user.getBase().getEyeLocation().getDirection().multiply(2));
|
||||
|
||||
ess.scheduleSyncDelayedTask(() -> {
|
||||
final Location loc = bee.getLocation();
|
||||
bee.remove();
|
||||
loc.getWorld().createExplosion(loc, 0F);
|
||||
}, 20);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,7 +12,6 @@ import java.util.List;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandbigtree extends EssentialsCommand {
|
||||
public Commandbigtree() {
|
||||
super("bigtree");
|
||||
@@ -20,7 +19,7 @@ public class Commandbigtree extends EssentialsCommand {
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
TreeType tree;
|
||||
final TreeType tree;
|
||||
if (args.length > 0 && args[0].equalsIgnoreCase("redwood")) {
|
||||
tree = TreeType.TALL_REDWOOD;
|
||||
} else if (args.length > 0 && args[0].equalsIgnoreCase("tree")) {
|
||||
@@ -33,9 +32,11 @@ public class Commandbigtree extends EssentialsCommand {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
final Location loc = LocationUtil.getTarget(user.getBase());
|
||||
final Location safeLocation = LocationUtil.getSafeDestination(loc);
|
||||
final boolean success = user.getWorld().generateTree(safeLocation, tree);
|
||||
final Location loc = LocationUtil.getTarget(user.getBase()).add(0, 1, 0);
|
||||
if (loc.getBlock().getType().isSolid()) {
|
||||
throw new Exception(tl("bigTreeFailure"));
|
||||
}
|
||||
final boolean success = user.getWorld().generateTree(loc, tree);
|
||||
if (success) {
|
||||
user.sendMessage(tl("bigTreeSuccess"));
|
||||
} else {
|
||||
@@ -44,7 +45,7 @@ public class Commandbigtree extends EssentialsCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, User user, String commandLabel, String[] args) {
|
||||
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
return Lists.newArrayList("redwood", "tree", "jungle", "darkoak");
|
||||
} else {
|
||||
|
||||
@@ -14,7 +14,6 @@ import java.util.List;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandbook extends EssentialsCommand {
|
||||
|
||||
private static final Material WRITABLE_BOOK = EnumUtil.getMaterial("WRITABLE_BOOK", "BOOK_AND_QUILL");
|
||||
@@ -28,7 +27,7 @@ public class Commandbook extends EssentialsCommand {
|
||||
final ItemStack item = user.getItemInHand();
|
||||
final String player = user.getName();
|
||||
if (item.getType() == Material.WRITTEN_BOOK) {
|
||||
BookMeta bmeta = (BookMeta) item.getItemMeta();
|
||||
final BookMeta bmeta = (BookMeta) item.getItemMeta();
|
||||
|
||||
if (args.length > 1 && args[0].equalsIgnoreCase("author")) {
|
||||
if (user.isAuthorized("essentials.book.author") && (isAuthor(bmeta, player) || user.isAuthorized("essentials.book.others"))) {
|
||||
@@ -48,7 +47,7 @@ public class Commandbook extends EssentialsCommand {
|
||||
}
|
||||
} else {
|
||||
if (isAuthor(bmeta, player) || user.isAuthorized("essentials.book.others")) {
|
||||
ItemStack newItem = new ItemStack(WRITABLE_BOOK, item.getAmount());
|
||||
final ItemStack newItem = new ItemStack(WRITABLE_BOOK, item.getAmount());
|
||||
newItem.setItemMeta(bmeta);
|
||||
InventoryWorkaround.setItemInMainHand(user.getBase(), newItem);
|
||||
user.sendMessage(tl("editBookContents"));
|
||||
@@ -57,11 +56,11 @@ public class Commandbook extends EssentialsCommand {
|
||||
}
|
||||
}
|
||||
} else if (item.getType() == WRITABLE_BOOK) {
|
||||
BookMeta bmeta = (BookMeta) item.getItemMeta();
|
||||
final BookMeta bmeta = (BookMeta) item.getItemMeta();
|
||||
if (!user.isAuthorized("essentials.book.author")) {
|
||||
bmeta.setAuthor(player);
|
||||
}
|
||||
ItemStack newItem = new ItemStack(Material.WRITTEN_BOOK, item.getAmount());
|
||||
final ItemStack newItem = new ItemStack(Material.WRITTEN_BOOK, item.getAmount());
|
||||
newItem.setItemMeta(bmeta);
|
||||
InventoryWorkaround.setItemInMainHand(user.getBase(), newItem);
|
||||
user.sendMessage(tl("bookLocked"));
|
||||
@@ -70,16 +69,16 @@ public class Commandbook extends EssentialsCommand {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAuthor(BookMeta bmeta, String player) {
|
||||
String author = bmeta.getAuthor();
|
||||
private boolean isAuthor(final BookMeta bmeta, final String player) {
|
||||
final String author = bmeta.getAuthor();
|
||||
return author != null && author.equalsIgnoreCase(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, User user, String commandLabel, String[] args) {
|
||||
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
|
||||
// Right now, we aren't testing what's held in the player's hand - we could, but it's not necessarily worth it
|
||||
if (args.length == 1) {
|
||||
List<String> options = Lists.newArrayList("sign", "unsign"); // sign and unsign aren't real, but work
|
||||
final List<String> options = Lists.newArrayList("sign", "unsign"); // sign and unsign aren't real, but work
|
||||
if (user.isAuthorized("essentials.book.author")) {
|
||||
options.add("author");
|
||||
}
|
||||
@@ -88,7 +87,7 @@ public class Commandbook extends EssentialsCommand {
|
||||
}
|
||||
return options;
|
||||
} else if (args.length == 2 && args[0].equalsIgnoreCase("author") && user.isAuthorized("essentials.book.author")) {
|
||||
List<String> options = getPlayers(server, user);
|
||||
final List<String> options = getPlayers(server, user);
|
||||
options.add("Herobrine"); // #EasterEgg
|
||||
return options;
|
||||
} else {
|
||||
|
||||
@@ -6,11 +6,8 @@ import org.bukkit.Server;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandbreak extends EssentialsCommand {
|
||||
public Commandbreak() {
|
||||
super("break");
|
||||
@@ -19,10 +16,8 @@ public class Commandbreak extends EssentialsCommand {
|
||||
//TODO: Switch to use util class
|
||||
@Override
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
final Block block = user.getBase().getTargetBlock((Set<Material>) null, 20);
|
||||
if (block == null) {
|
||||
throw new NoChargeException();
|
||||
}
|
||||
|
||||
final Block block = user.getTargetBlock(20);
|
||||
if (block.getType() == Material.AIR) {
|
||||
throw new NoChargeException();
|
||||
}
|
||||
|
||||
@@ -1,33 +1,22 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.FormatUtil;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandbroadcast extends EssentialsCommand {
|
||||
public Commandbroadcast() {
|
||||
super("broadcast");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
sendBroadcast(user.getDisplayName(), args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
sendBroadcast(sender.getSender().getName(), args);
|
||||
}
|
||||
|
||||
private void sendBroadcast(final String name, final String[] args) throws NotEnoughArgumentsException {
|
||||
if (args.length < 1) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
ess.broadcastMessage(tl("broadcast", FormatUtil.replaceFormat(getFinalArg(args, 0)).replace("\\n", "\n"), name));
|
||||
ess.broadcastMessage(tl("broadcast", FormatUtil.replaceFormat(getFinalArg(args, 0)).replace("\\n", "\n"), sender.getDisplayName()));
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.textreader.IText;
|
||||
@@ -9,7 +7,6 @@ import com.earth2me.essentials.textreader.KeywordReplacer;
|
||||
import com.earth2me.essentials.textreader.SimpleTextInput;
|
||||
import com.earth2me.essentials.utils.FormatUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -18,6 +15,7 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class Commandbroadcastworld extends EssentialsCommand {
|
||||
|
||||
@@ -27,25 +25,21 @@ public class Commandbroadcastworld extends EssentialsCommand {
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length == 0) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
World world = user.getWorld();
|
||||
String message = getFinalArg(args, 0);
|
||||
|
||||
if (args.length < 1) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
} else if (args.length > 1 && ess.getSettings().isAllowWorldInBroadcastworld()) {
|
||||
World argWorld = ess.getWorld(args[0]);
|
||||
if (args.length > 1 && ess.getSettings().isAllowWorldInBroadcastworld()) {
|
||||
final World argWorld = ess.getWorld(args[0]);
|
||||
if (argWorld != null) {
|
||||
world = argWorld;
|
||||
message = getFinalArg(args, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (world == null) {
|
||||
world = user.getWorld();
|
||||
message = getFinalArg(args, 0);
|
||||
}
|
||||
|
||||
sendBroadcast(world.getName(), user.getDisplayName(), message);
|
||||
sendBroadcast(world, user.getDisplayName(), message);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -53,29 +47,30 @@ public class Commandbroadcastworld extends EssentialsCommand {
|
||||
if (args.length < 2) {
|
||||
throw new NotEnoughArgumentsException("world");
|
||||
}
|
||||
sendBroadcast(args[0], sender.getSender().getName(), getFinalArg(args, 1));
|
||||
}
|
||||
|
||||
private void sendBroadcast(final String worldName, final String name, final String message) throws Exception {
|
||||
World world = ess.getWorld(worldName);
|
||||
final World world = ess.getWorld(args[0]);
|
||||
if (world == null) {
|
||||
throw new Exception(tl("invalidWorld"));
|
||||
}
|
||||
sendBroadcast(world, sender.getSender().getName(), getFinalArg(args, 1));
|
||||
}
|
||||
|
||||
private void sendBroadcast(final World world, final String name, final String message) throws Exception {
|
||||
if (message.isEmpty()) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
sendToWorld(world, tl("broadcast", FormatUtil.replaceFormat(message).replace("\\n", "\n"), name));
|
||||
}
|
||||
|
||||
private void sendToWorld(World world, String message) {
|
||||
private void sendToWorld(final World world, final String message) {
|
||||
IText broadcast = new SimpleTextInput(message);
|
||||
final Collection<Player> players = ess.getOnlinePlayers();
|
||||
|
||||
for (Player player : players) {
|
||||
for (final Player player : players) {
|
||||
if (player.getWorld().equals(world)) {
|
||||
final User user = ess.getUser(player);
|
||||
broadcast = new KeywordReplacer(broadcast, new CommandSource(player), ess, false);
|
||||
for (String messageText : broadcast.getLines()) {
|
||||
for (final String messageText : broadcast.getLines()) {
|
||||
user.sendMessage(messageText);
|
||||
}
|
||||
}
|
||||
@@ -83,23 +78,10 @@ public class Commandbroadcastworld extends EssentialsCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, User user, String commandLabel, String[] args) {
|
||||
if (args.length == 1 && ess.getSettings().isAllowWorldInBroadcastworld()) {
|
||||
List<String> worlds = Lists.newArrayList();
|
||||
for (World world : server.getWorlds()) {
|
||||
worlds.add(world.getName());
|
||||
}
|
||||
return worlds;
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, CommandSource sender, String commandLabel, String[] args) {
|
||||
if (args.length == 1) {
|
||||
List<String> worlds = Lists.newArrayList();
|
||||
for (World world : server.getWorlds()) {
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1 && (!sender.isPlayer() || ess.getSettings().isAllowWorldInBroadcastworld())) {
|
||||
final List<String> worlds = Lists.newArrayList();
|
||||
for (final World world : server.getWorlds()) {
|
||||
worlds.add(world.getName());
|
||||
}
|
||||
return worlds;
|
||||
|
||||
@@ -9,7 +9,6 @@ import java.util.List;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandburn extends EssentialsCommand {
|
||||
public Commandburn() {
|
||||
super("burn");
|
||||
@@ -21,17 +20,13 @@ public class Commandburn extends EssentialsCommand {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
if (args[0].trim().length() < 2) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
User user = getPlayer(server, sender, args, 0);
|
||||
final User user = getPlayer(server, sender, args, 0);
|
||||
user.getBase().setFireTicks(Integer.parseInt(args[1]) * 20);
|
||||
sender.sendMessage(tl("burnMsg", user.getDisplayName(), Integer.parseInt(args[1])));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, CommandSource sender, String commandLabel, String[] args) {
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
return getPlayers(server, sender);
|
||||
} else if (args.length == 2) {
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.User;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class Commandcartographytable extends EssentialsCommand {
|
||||
|
||||
public Commandcartographytable() {
|
||||
super("cartographytable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
if (ess.getContainerProvider() == null) {
|
||||
user.sendMessage(tl("unsupportedBrand"));
|
||||
return;
|
||||
}
|
||||
|
||||
ess.getContainerProvider().openCartographyTable(user.getBase());
|
||||
}
|
||||
}
|
||||
@@ -1,47 +1,52 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class Commandclearinventory extends EssentialsCommand {
|
||||
|
||||
private static final int BASE_AMOUNT = 100000;
|
||||
private static final int EXTENDED_CAP = 8;
|
||||
|
||||
public Commandclearinventory() {
|
||||
super("clearinventory");
|
||||
}
|
||||
|
||||
private static final int BASE_AMOUNT = 100000;
|
||||
private static final int EXTENDED_CAP = 8;
|
||||
|
||||
@Override
|
||||
public void run(Server server, User user, String commandLabel, String[] args) throws Exception {
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
parseCommand(server, user.getSource(), commandLabel, args, user.isAuthorized("essentials.clearinventory.others"),
|
||||
user.isAuthorized("essentials.clearinventory.all") || user.isAuthorized("essentials.clearinventory.multiple"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run(Server server, CommandSource sender, String commandLabel, String[] args) throws Exception {
|
||||
protected void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
parseCommand(server, sender, commandLabel, args, true, true);
|
||||
}
|
||||
|
||||
private void parseCommand(Server server, CommandSource sender, String commandLabel, String[] args, boolean allowOthers, boolean allowAll)
|
||||
private void parseCommand(final Server server, final CommandSource sender, final String commandLabel, final String[] args, final boolean allowOthers, final boolean allowAll)
|
||||
throws Exception {
|
||||
Collection<Player> players = new ArrayList<Player>();
|
||||
User senderUser = ess.getUser(sender.getPlayer());
|
||||
Collection<Player> players = new ArrayList<>();
|
||||
final User senderUser = ess.getUser(sender.getPlayer());
|
||||
String previousClearCommand = "";
|
||||
|
||||
|
||||
int offset = 0;
|
||||
|
||||
if (sender.isPlayer()) {
|
||||
@@ -64,9 +69,8 @@ public class Commandclearinventory extends EssentialsCommand {
|
||||
throw new PlayerNotFoundException();
|
||||
}
|
||||
|
||||
|
||||
// Confirm
|
||||
String formattedCommand = formatCommand(commandLabel, args);
|
||||
final String formattedCommand = formatCommand(commandLabel, args);
|
||||
if (senderUser != null && senderUser.isPromptingClearConfirm()) {
|
||||
if (!formattedCommand.equals(previousClearCommand)) {
|
||||
senderUser.setConfirmingClearCommand(formattedCommand);
|
||||
@@ -75,45 +79,48 @@ public class Commandclearinventory extends EssentialsCommand {
|
||||
}
|
||||
}
|
||||
|
||||
for (Player player : players) {
|
||||
for (final Player player : players) {
|
||||
clearHandler(sender, player, args, offset, players.size() < EXTENDED_CAP);
|
||||
}
|
||||
}
|
||||
|
||||
protected void clearHandler(CommandSource sender, Player player, String[] args, int offset, boolean showExtended) throws Exception {
|
||||
short data = -1;
|
||||
int type = -1;
|
||||
protected void clearHandler(final CommandSource sender, final Player player, final String[] args, final int offset, final boolean showExtended) {
|
||||
ClearHandlerType type = ClearHandlerType.ALL_EXCEPT_ARMOR;
|
||||
final Set<Item> items = new HashSet<>();
|
||||
int amount = -1;
|
||||
final Set<Material> mats = new HashSet<>();
|
||||
|
||||
if (args.length > (offset + 1) && NumberUtil.isInt(args[(offset + 1)])) {
|
||||
amount = Integer.parseInt(args[(offset + 1)]);
|
||||
if (args.length > (offset + 1) && NumberUtil.isInt(args[offset + 1])) {
|
||||
amount = Integer.parseInt(args[offset + 1]);
|
||||
}
|
||||
if (args.length > offset) {
|
||||
if (args[offset].equalsIgnoreCase("**")) {
|
||||
type = -2;
|
||||
type = ClearHandlerType.ALL_INCLUDING_ARMOR;
|
||||
} else if (!args[offset].equalsIgnoreCase("*")) {
|
||||
final String[] split = args[offset].split(",");
|
||||
|
||||
for (String name : split) {
|
||||
for (final String item : split) {
|
||||
final String[] itemParts = item.split(":");
|
||||
short data;
|
||||
try {
|
||||
mats.add(ess.getItemDb().get(name).getType());
|
||||
} catch (Exception ignored) {}
|
||||
data = Short.parseShort(itemParts[1]);
|
||||
} catch (final Exception e) {
|
||||
data = 0;
|
||||
}
|
||||
try {
|
||||
items.add(new Item(ess.getItemDb().get(itemParts[0]).getType(), data));
|
||||
} catch (final Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
type = 1;
|
||||
type = ClearHandlerType.SPECIFIC_ITEM;
|
||||
}
|
||||
}
|
||||
|
||||
if (type == -1) // type -1 represents wildcard or all items
|
||||
{
|
||||
if (type == ClearHandlerType.ALL_EXCEPT_ARMOR) {
|
||||
if (showExtended) {
|
||||
sender.sendMessage(tl("inventoryClearingAllItems", player.getDisplayName()));
|
||||
}
|
||||
InventoryWorkaround.clearInventoryNoArmor(player.getInventory());
|
||||
InventoryWorkaround.setItemInOffHand(player, null);
|
||||
} else if (type == -2) // type -2 represents double wildcard or all items and armor
|
||||
{
|
||||
} else if (type == ClearHandlerType.ALL_INCLUDING_ARMOR) {
|
||||
if (showExtended) {
|
||||
sender.sendMessage(tl("inventoryClearingAllArmor", player.getDisplayName()));
|
||||
}
|
||||
@@ -121,20 +128,21 @@ public class Commandclearinventory extends EssentialsCommand {
|
||||
InventoryWorkaround.setItemInOffHand(player, null);
|
||||
player.getInventory().setArmorContents(null);
|
||||
} else {
|
||||
for (Material mat : mats) {
|
||||
if (amount == -1) // amount -1 means all items will be cleared
|
||||
{
|
||||
ItemStack stack = new ItemStack(mat, BASE_AMOUNT, data);
|
||||
ItemStack removedStack = player.getInventory().removeItem(stack).get(0);
|
||||
final int removedAmount = (BASE_AMOUNT - removedStack.getAmount());
|
||||
for (final Item item : items) {
|
||||
final ItemStack stack = new ItemStack(item.getMaterial());
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_13_0_R01)) {
|
||||
stack.setDurability(item.getData());
|
||||
}
|
||||
// amount -1 means all items will be cleared
|
||||
if (amount == -1) {
|
||||
stack.setAmount(BASE_AMOUNT);
|
||||
final ItemStack removedStack = player.getInventory().removeItem(stack).get(0);
|
||||
final int removedAmount = BASE_AMOUNT - removedStack.getAmount() + InventoryWorkaround.clearItemInOffHand(player, stack);
|
||||
if (removedAmount > 0 || showExtended) {
|
||||
sender.sendMessage(tl("inventoryClearingStack", removedAmount, stack.getType().toString().toLowerCase(Locale.ENGLISH), player.getDisplayName()));
|
||||
}
|
||||
} else {
|
||||
if (amount < 0) {
|
||||
amount = 1;
|
||||
}
|
||||
ItemStack stack = new ItemStack(mat, amount);
|
||||
stack.setAmount(amount < 0 ? 1 : amount);
|
||||
if (player.getInventory().containsAtLeast(stack, amount)) {
|
||||
sender.sendMessage(tl("inventoryClearingStack", amount, stack.getType().toString().toLowerCase(Locale.ENGLISH), player.getDisplayName()));
|
||||
player.getInventory().removeItem(stack);
|
||||
@@ -149,17 +157,17 @@ public class Commandclearinventory extends EssentialsCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, User user, String commandLabel, String[] args) {
|
||||
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
|
||||
if (user.isAuthorized("essentials.clearinventory.others")) {
|
||||
if (args.length == 1) {
|
||||
List<String> options = getPlayers(server, user);
|
||||
final List<String> options = getPlayers(server, user);
|
||||
if (user.isAuthorized("essentials.clearinventory.all") || user.isAuthorized("essentials.clearinventory.multiple")) {
|
||||
// Assume that nobody will have the 'all' permission without the 'others' permission
|
||||
options.add("*");
|
||||
}
|
||||
return options;
|
||||
} else if (args.length == 2) {
|
||||
List<String> items = new ArrayList<>(getItems());
|
||||
final List<String> items = new ArrayList<>(getItems());
|
||||
items.add("*");
|
||||
items.add("**");
|
||||
return items;
|
||||
@@ -168,7 +176,7 @@ public class Commandclearinventory extends EssentialsCommand {
|
||||
}
|
||||
} else {
|
||||
if (args.length == 1) {
|
||||
List<String> items = new ArrayList<>(getItems());
|
||||
final List<String> items = new ArrayList<>(getItems());
|
||||
items.add("*");
|
||||
items.add("**");
|
||||
return items;
|
||||
@@ -179,13 +187,13 @@ public class Commandclearinventory extends EssentialsCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, CommandSource sender, String commandLabel, String[] args) {
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
List<String> options = getPlayers(server, sender);
|
||||
final List<String> options = getPlayers(server, sender);
|
||||
options.add("*");
|
||||
return options;
|
||||
} else if (args.length == 2) {
|
||||
List<String> items = new ArrayList<>(getItems());
|
||||
final List<String> items = new ArrayList<>(getItems());
|
||||
items.add("*");
|
||||
items.add("**");
|
||||
return items;
|
||||
@@ -194,7 +202,29 @@ public class Commandclearinventory extends EssentialsCommand {
|
||||
}
|
||||
}
|
||||
|
||||
private String formatCommand(String commandLabel, String[] args) {
|
||||
return "/" + commandLabel + " " + StringUtil.joinList(" ", (Object[]) args);
|
||||
private String formatCommand(final String commandLabel, final String[] args) {
|
||||
return "/" + commandLabel + " " + StringUtil.joinList(" ", args);
|
||||
}
|
||||
|
||||
private enum ClearHandlerType {
|
||||
ALL_EXCEPT_ARMOR, ALL_INCLUDING_ARMOR, SPECIFIC_ITEM
|
||||
}
|
||||
|
||||
private static class Item {
|
||||
private final Material material;
|
||||
private final short data;
|
||||
|
||||
Item(final Material material, final short data) {
|
||||
this.material = material;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public Material getMaterial() {
|
||||
return material;
|
||||
}
|
||||
|
||||
public short getData() {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-4
@@ -1,11 +1,10 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
import com.earth2me.essentials.User;
|
||||
|
||||
import org.bukkit.Server;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class Commandclearinventoryconfirmtoggle extends EssentialsCommand {
|
||||
|
||||
public Commandclearinventoryconfirmtoggle() {
|
||||
@@ -13,7 +12,7 @@ public class Commandclearinventoryconfirmtoggle extends EssentialsCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(Server server, User user, String commandLabel, String[] args) throws Exception {
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
boolean confirmingClear = !user.isPromptingClearConfirm();
|
||||
if (commandLabel.toLowerCase().endsWith("on")) {
|
||||
confirmingClear = true;
|
||||
|
||||
@@ -5,7 +5,6 @@ import org.bukkit.Server;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandcompass extends EssentialsCommand {
|
||||
public Commandcompass() {
|
||||
super("compass");
|
||||
@@ -14,7 +13,7 @@ public class Commandcompass extends EssentialsCommand {
|
||||
@Override
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
final int bearing = (int) (user.getLocation().getYaw() + 180 + 360) % 360;
|
||||
String dir;
|
||||
final String dir;
|
||||
if (bearing < 23) {
|
||||
dir = tl("north");
|
||||
} else if (bearing < 68) {
|
||||
|
||||
@@ -12,18 +12,24 @@ import org.bukkit.inventory.Recipe;
|
||||
import org.bukkit.inventory.ShapedRecipe;
|
||||
import org.bukkit.inventory.ShapelessRecipe;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandcondense extends EssentialsCommand {
|
||||
private final Map<ItemStack, SimpleRecipe> condenseList = new HashMap<>();
|
||||
|
||||
public Commandcondense() {
|
||||
super("condense");
|
||||
}
|
||||
|
||||
private Map<ItemStack, SimpleRecipe> condenseList = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
List<ItemStack> is = new ArrayList<>();
|
||||
@@ -32,7 +38,7 @@ public class Commandcondense extends EssentialsCommand {
|
||||
if (args.length > 0) {
|
||||
is = ess.getItemDb().getMatching(user, args);
|
||||
} else {
|
||||
for (ItemStack stack : user.getBase().getInventory().getContents()) {
|
||||
for (final ItemStack stack : user.getBase().getInventory().getContents()) {
|
||||
if (stack == null || stack.getType() == Material.AIR) {
|
||||
continue;
|
||||
}
|
||||
@@ -65,7 +71,7 @@ public class Commandcondense extends EssentialsCommand {
|
||||
|
||||
if (validateReverse) {
|
||||
boolean pass = false;
|
||||
for (Recipe revRecipe : ess.getServer().getRecipesFor(input)) {
|
||||
for (final Recipe revRecipe : ess.getServer().getRecipesFor(input)) {
|
||||
if (getStackOnRecipeMatch(revRecipe, result) != null) {
|
||||
pass = true;
|
||||
break;
|
||||
@@ -84,7 +90,7 @@ public class Commandcondense extends EssentialsCommand {
|
||||
}
|
||||
}
|
||||
|
||||
int output = ((amount / input.getAmount()) * result.getAmount());
|
||||
final int output = (amount / input.getAmount()) * result.getAmount();
|
||||
amount -= amount % input.getAmount();
|
||||
|
||||
if (amount > 0) {
|
||||
@@ -106,7 +112,7 @@ public class Commandcondense extends EssentialsCommand {
|
||||
}
|
||||
|
||||
final Iterator<Recipe> intr = ess.getServer().recipeIterator();
|
||||
List<SimpleRecipe> bestRecipes = new ArrayList<>();
|
||||
final List<SimpleRecipe> bestRecipes = new ArrayList<>();
|
||||
while (intr.hasNext()) {
|
||||
final Recipe recipe = intr.next();
|
||||
final Collection<ItemStack> recipeItems = getStackOnRecipeMatch(recipe, stack);
|
||||
@@ -120,9 +126,9 @@ public class Commandcondense extends EssentialsCommand {
|
||||
}
|
||||
if (!bestRecipes.isEmpty()) {
|
||||
if (bestRecipes.size() > 1) {
|
||||
Collections.sort(bestRecipes, SimpleRecipeComparator.INSTANCE);
|
||||
bestRecipes.sort(SimpleRecipeComparator.INSTANCE);
|
||||
}
|
||||
SimpleRecipe recipe = bestRecipes.get(0);
|
||||
final SimpleRecipe recipe = bestRecipes.get(0);
|
||||
condenseList.put(stack, recipe);
|
||||
return recipe;
|
||||
}
|
||||
@@ -134,23 +140,23 @@ public class Commandcondense extends EssentialsCommand {
|
||||
final Collection<ItemStack> inputList;
|
||||
|
||||
if (recipe instanceof ShapedRecipe) {
|
||||
ShapedRecipe sRecipe = (ShapedRecipe) recipe;
|
||||
final ShapedRecipe sRecipe = (ShapedRecipe) recipe;
|
||||
if (sRecipe.getShape().length != sRecipe.getShape()[0].length()) {
|
||||
// Only accept square recipes
|
||||
return null;
|
||||
}
|
||||
inputList = sRecipe.getIngredientMap().values();
|
||||
} else if (recipe instanceof ShapelessRecipe) {
|
||||
ShapelessRecipe slRecipe = (ShapelessRecipe) recipe;
|
||||
final ShapelessRecipe slRecipe = (ShapelessRecipe) recipe;
|
||||
inputList = slRecipe.getIngredientList();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean match = true;
|
||||
Iterator<ItemStack> iter = inputList.iterator();
|
||||
final Iterator<ItemStack> iter = inputList.iterator();
|
||||
while (iter.hasNext()) {
|
||||
ItemStack inputSlot = iter.next();
|
||||
final ItemStack inputSlot = iter.next();
|
||||
if (inputSlot == null) {
|
||||
iter.remove();
|
||||
continue;
|
||||
@@ -170,12 +176,20 @@ public class Commandcondense extends EssentialsCommand {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
return getMatchingItems(args[0]);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
private class SimpleRecipe implements Recipe {
|
||||
private ItemStack result;
|
||||
private ItemStack input;
|
||||
private static final class SimpleRecipe implements Recipe {
|
||||
private final ItemStack result;
|
||||
private final ItemStack input;
|
||||
|
||||
private SimpleRecipe(ItemStack result, ItemStack input) {
|
||||
private SimpleRecipe(final ItemStack result, final ItemStack input) {
|
||||
this.result = result;
|
||||
this.input = input;
|
||||
}
|
||||
@@ -190,20 +204,12 @@ public class Commandcondense extends EssentialsCommand {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, User user, String commandLabel, String[] args) {
|
||||
if (args.length == 1) {
|
||||
return getMatchingItems(args[0]);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
private static class SimpleRecipeComparator implements Comparator<SimpleRecipe> {
|
||||
|
||||
private static final SimpleRecipeComparator INSTANCE = new SimpleRecipeComparator();
|
||||
|
||||
@Override
|
||||
public int compare(SimpleRecipe o1, SimpleRecipe o2) {
|
||||
public int compare(final SimpleRecipe o1, final SimpleRecipe o2) {
|
||||
return Integer.compare(o2.getInput().getAmount(), o1.getInput().getAmount());
|
||||
}
|
||||
}
|
||||
|
||||
Loaded 100 of 517 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user