Compare commits
297 commits
feat-trans
...
master
Author | SHA1 | Date | |
---|---|---|---|
37e42fb169 | |||
03d66b1c69 | |||
c35a70712a | |||
e91d618dd6 | |||
1a169f7709 | |||
7fe5985391 | |||
bf1d360bd5 | |||
02fd88d9c9 | |||
7fac9d0279 | |||
d8f183146b | |||
c6f37579a0 | |||
e8ac7619de | |||
520840da1f | |||
66495db59b | |||
b85325fde5 | |||
8d394df1d6 | |||
666c45735d | |||
7cacb36fec | |||
8c04009c66 | |||
0f4b239148 | |||
66c9313d0e | |||
814d7adea7 | |||
7eca066cf1 | |||
1dbb199258 | |||
bcea10c9db | |||
8e32264087 | |||
e18ecfde1a | |||
278e44ad0d | |||
1216cfbdf5 | |||
2c7ee30ad2 | |||
b908e0562f | |||
1646488316 | |||
63f2e7f699 | |||
d30f433527 | |||
1a792112cc | |||
197f4f3259 | |||
dc36a0148e | |||
a709a9195f | |||
76c8f734e7 | |||
1ce7fbe3f0 | |||
875a04a850 | |||
9adf5f34f5 | |||
c74532ce66 | |||
1edfbb9123 | |||
1a81c7c657 | |||
11730d5234 | |||
3cc2b4415d | |||
4f9e334544 | |||
a996858ba9 | |||
ff892a7451 | |||
7ba8a26af6 | |||
3d5ef0f020 | |||
ea3fa9b52e | |||
a1919caa2a | |||
3440f1fad1 | |||
9b64ec18ba | |||
f72d5c0948 | |||
fe33a003ea | |||
d804fb1207 | |||
77e8844eee | |||
95a5e99038 | |||
230acf439e | |||
18afb84caa | |||
144245fc5a | |||
20af9e7328 | |||
c99c31ba37 | |||
0ef5766004 | |||
5197fefdaf | |||
df988dbf87 | |||
23f9424fa9 | |||
a98d5a75bd | |||
d45ce65c3b | |||
1133ac4052 | |||
40401a1652 | |||
db8ddbd507 | |||
278c801de1 | |||
653c229b85 | |||
57ed194122 | |||
34d1c5c7a0 | |||
a86acd0d9d | |||
a64577ac97 | |||
81b1c8275f | |||
eb23580bc4 | |||
81b66b6110 | |||
7097e56a6d | |||
5de0037d2c | |||
![]() |
eb44504d6f | ||
![]() |
c8183ffe44 | ||
![]() |
89d2499fed | ||
![]() |
c1c2d883c4 | ||
![]() |
59addc6ee3 | ||
![]() |
d784ed448f | ||
![]() |
68ad4ac9b5 | ||
![]() |
f81ff8bd52 | ||
![]() |
4d45c4660a | ||
![]() |
dde8ea48b9 | ||
![]() |
af4625793c | ||
![]() |
ba753deafd | ||
![]() |
f14457fd8b | ||
![]() |
365ac9b2d9 | ||
![]() |
4f13d3fc2d | ||
![]() |
61132a2c88 | ||
![]() |
1a0d2ffdf7 | ||
![]() |
52edd9fa65 | ||
![]() |
ff22f5addf | ||
![]() |
aa9b71bc18 | ||
![]() |
ba9f39659b | ||
![]() |
ccac492dcd | ||
![]() |
2aab497d0a | ||
![]() |
3f038c6b3d | ||
![]() |
95b4f4cdef | ||
![]() |
b394c7ef0c | ||
![]() |
ce8f21c268 | ||
![]() |
548d210a95 | ||
![]() |
c78ba0c84a | ||
![]() |
84e792880f | ||
![]() |
3377dcf2bf | ||
![]() |
30803363ba | ||
![]() |
153d666b78 | ||
![]() |
83bc00aebe | ||
![]() |
fdada8f44f | ||
![]() |
8a544d1ba5 | ||
![]() |
95cb064e29 | ||
![]() |
d44a92372b | ||
![]() |
5d92cc6d32 | ||
![]() |
04690bf72c | ||
![]() |
a064352492 | ||
![]() |
29e50966fd | ||
![]() |
e9d6f33930 | ||
![]() |
2b71bd18eb | ||
![]() |
a08744dee3 | ||
![]() |
60fa1d46f9 | ||
![]() |
48ca85028b | ||
![]() |
cb98fd2671 | ||
![]() |
c305f03df5 | ||
![]() |
4238e7b091 | ||
![]() |
424f0df002 | ||
![]() |
b2b67b3763 | ||
![]() |
2fc3194c8c | ||
![]() |
3949113dee | ||
![]() |
dd5aff034d | ||
![]() |
2447c08636 | ||
![]() |
e360d5c8a7 | ||
![]() |
9fc902aa75 | ||
![]() |
a3227dfb94 | ||
![]() |
e5ce8bde1a | ||
![]() |
f306c3abaa | ||
![]() |
264d0745ba | ||
![]() |
8a53b2f188 | ||
![]() |
d0488bae84 | ||
![]() |
4eecbf416e | ||
![]() |
8611ef2604 | ||
![]() |
98c0a446c6 | ||
![]() |
b7fff273cf | ||
![]() |
a8483b4a15 | ||
![]() |
fc2be7c7a4 | ||
![]() |
8d1c80a5fb | ||
![]() |
99e7dd439a | ||
![]() |
4f8c3c9eec | ||
![]() |
14b118eadf | ||
![]() |
37e6f031a6 | ||
![]() |
17345a6b5f | ||
![]() |
ddb4b6d39c | ||
![]() |
fcc4590396 | ||
![]() |
d75aad6596 | ||
![]() |
d673d34a51 | ||
![]() |
9bcbb510a0 | ||
![]() |
25e3893771 | ||
![]() |
b673a6409f | ||
![]() |
46ce1036ea | ||
![]() |
3ee51ef6a7 | ||
![]() |
00e820735d | ||
![]() |
f74b6d2f81 | ||
![]() |
2cf7f4c8d4 | ||
![]() |
95cb60a6b3 | ||
![]() |
b1632c049e | ||
![]() |
2aa37a10a6 | ||
![]() |
2a326232ca | ||
![]() |
36589747af | ||
![]() |
074c07f628 | ||
![]() |
4977e59d24 | ||
![]() |
52c7c00dd1 | ||
![]() |
83b7f90976 | ||
![]() |
929423dfbe | ||
![]() |
649e23409a | ||
![]() |
854039d657 | ||
![]() |
8838961f37 | ||
![]() |
f436c7db3a | ||
![]() |
597ed23dbc | ||
![]() |
b24202e8ab | ||
![]() |
292e9a4a6b | ||
![]() |
6633ac94a8 | ||
![]() |
94bb9ffc18 | ||
![]() |
1d366855a2 | ||
![]() |
c57400707e | ||
![]() |
dd35f38dc2 | ||
![]() |
8bddd56124 | ||
![]() |
027d585210 | ||
![]() |
ccae0084ea | ||
![]() |
6a4826f441 | ||
![]() |
8d87cddbea | ||
![]() |
618af08024 | ||
![]() |
b81eac497a | ||
![]() |
ec587b56c3 | ||
![]() |
240d75b1a1 | ||
![]() |
e471d86801 | ||
![]() |
b64f56a0bb | ||
![]() |
c929e73b0d | ||
![]() |
5d3a99f72d | ||
![]() |
26daa3a038 | ||
![]() |
f157831641 | ||
![]() |
77a2623013 | ||
![]() |
2ef21a796e | ||
![]() |
fe78fd0e2b | ||
![]() |
6fae824fe2 | ||
![]() |
119392320b | ||
![]() |
378813c829 | ||
![]() |
7d07834bf7 | ||
![]() |
3a7da4b3d6 | ||
![]() |
8464909b6d | ||
![]() |
87a256c9c5 | ||
![]() |
86e65043e1 | ||
![]() |
69bae936d6 | ||
![]() |
f795d42564 | ||
![]() |
7c70ebf9b6 | ||
![]() |
cbc4c748ca | ||
![]() |
00168c03a7 | ||
![]() |
92f88a1b92 | ||
![]() |
57d09f65c2 | ||
![]() |
571ed1d31d | ||
![]() |
37b1d5bd0c | ||
![]() |
da8c7e91ce | ||
![]() |
29a557c42d | ||
![]() |
31c8c8f695 | ||
![]() |
b8a52da87e | ||
![]() |
4abcf7647f | ||
![]() |
48257e2028 | ||
![]() |
a254d3ed9b | ||
![]() |
856f550462 | ||
![]() |
4aa9b23952 | ||
![]() |
228e3c4374 | ||
![]() |
c8c55611a0 | ||
![]() |
4fa7082bf5 | ||
![]() |
f419f62f6c | ||
![]() |
a91d039dd2 | ||
![]() |
18d7322406 | ||
![]() |
c6f037a24d | ||
![]() |
de9904df52 | ||
![]() |
5cf35e5b98 | ||
![]() |
82c210459e | ||
![]() |
51ab123eaf | ||
![]() |
15b02ff390 | ||
![]() |
3ec2e7a584 | ||
![]() |
02e03794e4 | ||
![]() |
cb11f5e47a | ||
![]() |
7eacc92a22 | ||
![]() |
2fbf3318f9 | ||
![]() |
f3ebbd6a8d | ||
![]() |
50dd4c3adf | ||
![]() |
c66979133d | ||
![]() |
c3e10ae81d | ||
![]() |
7cab66a70e | ||
![]() |
bb6764af00 | ||
![]() |
f99d20ade3 | ||
![]() |
041700d070 | ||
![]() |
f9513aa751 | ||
![]() |
f447abe963 | ||
![]() |
dee3f9b91c | ||
![]() |
584b34fd51 | ||
![]() |
04fbcd99ba | ||
![]() |
ec3ca218a5 | ||
![]() |
318c0ffefd | ||
![]() |
17fa5e81e7 | ||
![]() |
f0b9c62a1b | ||
![]() |
87e998d578 | ||
![]() |
fecfb7300b | ||
![]() |
4157c71526 | ||
![]() |
f3088fca8c | ||
![]() |
3ad3da9179 | ||
![]() |
ac9af73fb6 | ||
![]() |
af7081a87a | ||
![]() |
3037945729 | ||
![]() |
1eb2af6443 | ||
![]() |
562f9ea3e4 | ||
![]() |
567184b07d | ||
![]() |
a01b564912 | ||
![]() |
7392b8aad2 | ||
![]() |
0ad2c408a6 | ||
![]() |
cee168e225 | ||
![]() |
94634f7bba | ||
![]() |
ebe539c614 | ||
![]() |
7f3ecddc51 | ||
![]() |
fd732fc886 | ||
![]() |
d17aadc09a | ||
![]() |
6e0ef4a243 | ||
![]() |
35e2db02e9 | ||
![]() |
d37a0bd3ba |
196 changed files with 6615 additions and 4925 deletions
71
.gitignore
vendored
71
.gitignore
vendored
|
@ -1,50 +1,29 @@
|
||||||
|
.gradle
|
||||||
|
build/
|
||||||
|
!gradle/wrapper/gradle-wrapper.jar
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
# Compiled class file
|
### IntelliJ IDEA ###
|
||||||
*.class
|
.idea/
|
||||||
|
*.iws
|
||||||
# Log file
|
|
||||||
*.log
|
|
||||||
|
|
||||||
# BlueJ files
|
|
||||||
*.ctxt
|
|
||||||
|
|
||||||
# Mobile Tools for Java (J2ME)
|
|
||||||
.mtj.tmp/
|
|
||||||
|
|
||||||
# Package Files #
|
|
||||||
*.jar
|
|
||||||
*.war
|
|
||||||
*.nar
|
|
||||||
*.ear
|
|
||||||
*.zip
|
|
||||||
*.tar.gz
|
|
||||||
*.rar
|
|
||||||
|
|
||||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
|
||||||
hs_err_pid*
|
|
||||||
replay_pid*
|
|
||||||
|
|
||||||
# Idea files
|
|
||||||
*.iml
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
out/
|
||||||
|
!**/src/main/**/out/
|
||||||
|
!**/src/test/**/out/
|
||||||
|
|
||||||
# Nicko first pass build files
|
### Eclipse ###
|
||||||
core/target
|
.apt_generated
|
||||||
v1_14_R1/target
|
.classpath
|
||||||
v1_15_R1/target
|
.factorypath
|
||||||
v1_16_R1/target
|
.project
|
||||||
v1_16_R2/target
|
.settings
|
||||||
v1_16_R3/target
|
.springBeans
|
||||||
v1_17_R1/target
|
.sts4-cache
|
||||||
v1_18_R1/target
|
bin/
|
||||||
v1_18_R2/target
|
!**/src/main/**/bin/
|
||||||
v1_19_R1/target
|
!**/src/test/**/bin/
|
||||||
|
|
||||||
# Idea Folder
|
### Server ###
|
||||||
.idea
|
run/
|
||||||
|
|
||||||
# Build folder
|
|
||||||
target
|
|
||||||
|
|
||||||
# Maven Dependency Reduced Pom
|
|
||||||
dist/dependency-reduced-pom.xml
|
|
||||||
core/dependency-reduced-pom.xml
|
|
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
18
.idea/gradle.xml
generated
Normal file
18
.idea/gradle.xml
generated
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||||
|
<component name="GradleSettings">
|
||||||
|
<option name="linkedExternalProjectsSettings">
|
||||||
|
<GradleProjectSettings>
|
||||||
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="modules">
|
||||||
|
<set>
|
||||||
|
<option value="$PROJECT_DIR$" />
|
||||||
|
</set>
|
||||||
|
</option>
|
||||||
|
<option name="resolveExternalAnnotations" value="true" />
|
||||||
|
</GradleProjectSettings>
|
||||||
|
</option>
|
||||||
|
<option name="parallelModelFetch" value="true" />
|
||||||
|
</component>
|
||||||
|
</project>
|
7
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
7
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="UnusedReceiverParameter" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
|
<inspection_tool class="UnusedSymbol" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
|
</profile>
|
||||||
|
</component>
|
10
.idea/misc.xml
generated
Normal file
10
.idea/misc.xml
generated
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
|
<component name="PWA">
|
||||||
|
<option name="wasEnabledAtLeastOnce" value="true" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_22" project-jdk-name="graal-22" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
</project>
|
124
.idea/uiDesigner.xml
generated
Normal file
124
.idea/uiDesigner.xml
generated
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Palette2">
|
||||||
|
<group name="Swing">
|
||||||
|
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="Button" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="RadioButton" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="CheckBox" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="Label" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||||
|
<preferred-size width="150" height="-1" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||||
|
<preferred-size width="150" height="-1" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||||
|
<preferred-size width="150" height="-1" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||||
|
<preferred-size width="200" height="200" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||||
|
<preferred-size width="200" height="200" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
||||||
|
<preferred-size width="-1" height="20" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
||||||
|
</item>
|
||||||
|
</group>
|
||||||
|
</component>
|
||||||
|
</project>
|
129
CHANGELOG.log
Normal file
129
CHANGELOG.log
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
1.3.0-RC1: Update n°13 (XX/XX/25)
|
||||||
|
[FEATURES]
|
||||||
|
- Players are now able to mark disguises as favorites.
|
||||||
|
|
||||||
|
[FIXES]
|
||||||
|
- Fixed a bug where a player was improperly named when inspecting it in the admin panel.
|
||||||
|
- Added a missing sound when players undisguised.
|
||||||
|
|
||||||
|
1.2.0-RC1: Update n°12 (XX/XX/25)
|
||||||
|
[FEATURES]
|
||||||
|
- Updated to support Minecraft 1.21.5.
|
||||||
|
- Added a sub-command (/nicko about) to get information about Nicko.
|
||||||
|
- Modernized the messages and added various sound effects upon interacting with the plugin.
|
||||||
|
- Cleaned up GUI titles.
|
||||||
|
|
||||||
|
[FIXES]
|
||||||
|
- Fixed an oversight preventing the configuration from properly being migrated.
|
||||||
|
- Fixed a rare bug that could prevent data from being saved.
|
||||||
|
- Fixed the placeholder item in the skin cache invalidation not being translated.
|
||||||
|
- Fixed a oversight about a column name using SQL storage.
|
||||||
|
|
||||||
|
[LANGUAGE]
|
||||||
|
- Moved the prefix to the language file.
|
||||||
|
|
||||||
|
[OTHER]
|
||||||
|
- Cleaned up the codebase to prepare for future updates.
|
||||||
|
|
||||||
|
1.1.7-RC1: Hotfix n°5 (04/05/24)
|
||||||
|
[OTHER]
|
||||||
|
- Restored download link again on spigotmc.org
|
||||||
|
|
||||||
|
1.1.6-RC1: Update n°11 (04/05/24)
|
||||||
|
[FEATURES]
|
||||||
|
- Update dependencies in preparation to the 1.20.5 update
|
||||||
|
|
||||||
|
[OTHER]
|
||||||
|
- Restored download link on spigotmc.org
|
||||||
|
|
||||||
|
1.1.5-RC1: Update n°10 (25/12/23)
|
||||||
|
[FEATURES]
|
||||||
|
- Various improvements to performance.
|
||||||
|
[FIXES]
|
||||||
|
- Fixed a bug related to configuration migration.
|
||||||
|
|
||||||
|
1.1.4-RC1: Update n°9 (07/02/23)
|
||||||
|
[OTHER]
|
||||||
|
- The repository hosting the previous version of Nicko had expired, this is now fixed.
|
||||||
|
|
||||||
|
1.1.3-RC1: Hotfix n°4 (28/12/23)
|
||||||
|
[FIXES]
|
||||||
|
- Fixed the English Locale version being late.
|
||||||
|
|
||||||
|
1.1.2-RC1: Update n°8 (28/12/23)
|
||||||
|
[FEATURES]
|
||||||
|
- Players now default back to their original appearance upon failure.
|
||||||
|
|
||||||
|
[FIXES]
|
||||||
|
- Fixed an invalid placeholder parameter (%nicko_random_skin% now gets if the player has random skin on login set or not).
|
||||||
|
- Fixed the error reason not appearing upon failure.
|
||||||
|
- Fixed player profiles (name and skin associated) not being reset gracefully upon failure.
|
||||||
|
- Fixed error messages not being precise enough.
|
||||||
|
- Various optimizations and improvements.
|
||||||
|
|
||||||
|
1.1.1-RC1: Update n°7 (27/12/23)
|
||||||
|
[FEATURES]
|
||||||
|
- Made Nicko compatible with 1.20.3 and 1.20.4.
|
||||||
|
|
||||||
|
|
||||||
|
1.1.0-RC1: Update n°6 (23/12/23)
|
||||||
|
[BREAKING]
|
||||||
|
- The language system has been updated to use the Adventure library (https://docs.advntr.dev/index.html). This results in the custom locale breaking
|
||||||
|
Nicko upon usage of legacy color codes (e.g., "§6Nicko"). Your custom locale will be backed up upon starting this version and you will be able to
|
||||||
|
use the new default English locale to help you make your locale compatible with the new formatting.
|
||||||
|
|
||||||
|
[FEATURES]
|
||||||
|
- Players can now choose to get a random appearance via a list of more than 400 usernames and skins associated.
|
||||||
|
- Players can now toggle a setting to automatically get a random appearance upon joining.
|
||||||
|
- Introduced a version string inside Nicko's language files to plan future updates to the file. (see [BREAKING])
|
||||||
|
|
||||||
|
(Note: the random skin functionality is still work-in-progress and might break or not work at all because of
|
||||||
|
the lack of time that I have to test all the usernames and skins associated.)
|
||||||
|
|
||||||
|
[FIXES]
|
||||||
|
- Various optimizations and improvements.
|
||||||
|
- Internal refactoring
|
||||||
|
- bStats metrics are not minified anymore.
|
||||||
|
|
||||||
|
1.0.8-RC1: Update n°5 (19/12/23)
|
||||||
|
[FEATURES]
|
||||||
|
- Introduced a version string inside Nicko's configuration to plan future updates to the file. Your previous configuration file will automatically be migrated to this current version (with the backup of your old one included!)
|
||||||
|
- Persistence and cache will now fallback to local alternatives when unreachable.
|
||||||
|
- Player check GUI has been updated to better reflect the current state of player's disguises.
|
||||||
|
- Developers can now listen to the PlayerDisguiseEvent and cancel the disguise process.
|
||||||
|
|
||||||
|
[OTHER]
|
||||||
|
- Various optimizations and improvements.
|
||||||
|
- Internal refactoring
|
||||||
|
|
||||||
|
1.0.7-RC1: Update n°4 (13/12/23)
|
||||||
|
[OTHER]
|
||||||
|
- In line with my thinking that Minecraft servers should always be in one of the latest versions to give developers more freedom and less maintenance hassle, Nicko will now only be supporting the current major version and the one before it. This results in this version of Nicko now needing at minimum Java version 17 and a server running 1.19. If you can't upgrade, consider myself sorry.
|
||||||
|
- Various optimizations and improvements following the upgrade to Java 17.
|
||||||
|
|
||||||
|
1.0.6-RC1: Update n°3 (11/12/23)
|
||||||
|
[OTHER]
|
||||||
|
- Added telemetry via bStats to gather useful informations about Nicko. This feature is optional and can be disabled inside the "bStats" folder found in plugins folder. Informations gathered are public record and can be found at: https://bstats.org/plugin/bukkit/Nicko/20483.
|
||||||
|
|
||||||
|
1.0.5-RC1: Update n°2 (11/12/23)
|
||||||
|
[OTHER]
|
||||||
|
- Moved plugin to the Gradle build chain, resulting in faster builds and smaller Jar. This has no consequences for players.
|
||||||
|
|
||||||
|
1.0.4-RC1:
|
||||||
|
[FEATURES]
|
||||||
|
- The players check GUI is now updated upon player's joining and leaving
|
||||||
|
- Administrators are now able to remove a player's disguise through the player check GUI
|
||||||
|
|
||||||
|
1.0.3-RC1: Hotfix n°3 (07/12/23)
|
||||||
|
[FIXES]
|
||||||
|
- Fixed a visual bug where players in survival mode were seeing themselves as having full health and hunger after disguising.
|
||||||
|
|
||||||
|
1.0.2-RC1: Hotfix n°2 (06/12/23)
|
||||||
|
[OTHER]
|
||||||
|
- Internal refactoring
|
||||||
|
|
||||||
|
1.0.1-RC1: Hotfix n°1 (06/12/23)
|
||||||
|
[FIXES]
|
||||||
|
- Fixed an issue when joining and players being disguised were not for the player joining.
|
||||||
|
|
||||||
|
|
31
README.md
31
README.md
|
@ -1,14 +1,29 @@
|
||||||
# _Nicko_ <img style="vertical-align:middle" src="./img/LOGO.png" alt="" width="50"/>
|
# *Nicko* <img style="vertical-align:middle" src="./img/LOGO.png" alt="" width="65"/>
|
||||||
|
|
||||||
## The next-generation, most feature-packed disguise plugin for Minecraft.
|
## The feature packed, next generation disguise plugin for Minecraft.
|
||||||
|
|
||||||
### Download:
|
---
|
||||||
|
|
||||||
Coming soon! ⏳
|
## Download:
|
||||||
|
|
||||||
|
https://www.spigotmc.org/resources/nicko.113868/
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Known bugs:
|
||||||
|
|
||||||
|
- Players who have operator (OP) status lose access to the Operator Items tab in creative mode
|
||||||
|
after disguising **(1.20 and up)**.
|
||||||
|
- When disguising and only changing their display name, players will have the new default
|
||||||
|
skins **(1.20 and up)**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
#### Version compatibility table
|
#### Version compatibility table
|
||||||
|
|
||||||
| Version | Supported |
|
| Version | Plugin |
|
||||||
|-----------|----------------------------------------------------------------------------|
|
|---------------|----------------------------------------------------------------------------|
|
||||||
| < 1.12.2 | Use [NickReloaded](https://www.spigotmc.org/resources/nickreloaded.46335/) |
|
| 1.7 and lower | Unsupported |
|
||||||
| \> 1.12.2 | Supported |
|
| 1.8 - 1.12.2 | Use [NickReloaded](https://www.spigotmc.org/resources/nickreloaded.46335/) |
|
||||||
|
| 1.13 to 1.19 | Unsupported |
|
||||||
|
| 1.20 - 1.21 | Use Nicko |
|
||||||
|
|
106
build.gradle.kts
Normal file
106
build.gradle.kts
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
plugins {
|
||||||
|
id("java")
|
||||||
|
id("com.gradleup.shadow") version "8.3.2"
|
||||||
|
id("xyz.jpenilla.run-paper") version "2.3.0"
|
||||||
|
id("io.papermc.paperweight.userdev") version "2.0.0-beta.17"
|
||||||
|
}
|
||||||
|
|
||||||
|
group = "xyz.ineanto"
|
||||||
|
version = "1.2.0"
|
||||||
|
|
||||||
|
val invuiVersion: String = "1.44"
|
||||||
|
|
||||||
|
java {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_22
|
||||||
|
targetCompatibility = JavaVersion.VERSION_22
|
||||||
|
|
||||||
|
toolchain {
|
||||||
|
languageVersion = JavaLanguageVersion.of(22)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
mavenLocal()
|
||||||
|
|
||||||
|
maven("https://repo.xenondevs.xyz/releases")
|
||||||
|
maven("https://repo.papermc.io/repository/maven-public/")
|
||||||
|
maven("https://repo.codemc.io/repository/maven-snapshots/")
|
||||||
|
maven("https://repo.extendedclip.com/content/repositories/placeholderapi/")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
paperweight.paperDevBundle("1.21.5-R0.1-SNAPSHOT")
|
||||||
|
|
||||||
|
compileOnly("me.clip:placeholderapi:2.11.5")
|
||||||
|
compileOnly("net.kyori:adventure-api:4.21.0")
|
||||||
|
compileOnly("xyz.xenondevs.invui:invui-core:$invuiVersion")
|
||||||
|
compileOnly("net.wesjd:anvilgui:1.10.4-SNAPSHOT")
|
||||||
|
compileOnly("com.comphenix.protocol:ProtocolLib:5.4.0-SNAPSHOT")
|
||||||
|
|
||||||
|
implementation("de.rapha149.signgui:signgui:2.5.0")
|
||||||
|
implementation("com.github.jsixface:yamlconfig:1.2")
|
||||||
|
implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.18.1")
|
||||||
|
implementation("com.fasterxml.jackson.core:jackson-core:2.18.1")
|
||||||
|
implementation("com.mysql:mysql-connector-j:9.2.0")
|
||||||
|
implementation("org.mariadb.jdbc:mariadb-java-client:3.5.2")
|
||||||
|
implementation("redis.clients:jedis:5.2.0")
|
||||||
|
implementation("com.google.code.gson:gson:2.13.1")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
|
||||||
|
processResources {
|
||||||
|
from("src/main/resources")
|
||||||
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||||
|
filesMatching("*.yml") {
|
||||||
|
expand("version" to version)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shadowJar {
|
||||||
|
// RELOCATIONS
|
||||||
|
relocate("net.wesjd", "xyz.ineanto.nicko.libs.anvilgui")
|
||||||
|
relocate("com.github.jsixface", "xyz.ineanto.nicko.libs.yaml")
|
||||||
|
relocate("me.clip", "xyz.ineanto.nicko.libs.placeholderapi")
|
||||||
|
relocate("com.fasterxml.jackson", "xyz.ineanto.nicko.libs.jackson")
|
||||||
|
relocate("com.mysql", "xyz.ineanto.nicko.libs.mysql")
|
||||||
|
relocate("org.mariadb.jdbc", "xyz.ineanto.nicko.libs.mariadb")
|
||||||
|
relocate("redis.clients", "xyz.ineanto.nicko.libs.redis")
|
||||||
|
relocate("com.google.gson", "xyz.ineanto.nicko.libs.gson")
|
||||||
|
relocate("org.apache.commons.pool2", "xyz.ineanto.nicko.libs.pool2")
|
||||||
|
|
||||||
|
// EXCLUSIONS
|
||||||
|
exclude("colors.bin")
|
||||||
|
exclude("waffle/**")
|
||||||
|
exclude("com/sun/**")
|
||||||
|
exclude("com/google/protobuf/**")
|
||||||
|
exclude("com/google/errorprone/**")
|
||||||
|
exclude("org/apache/commons/logging/**")
|
||||||
|
exclude("org/jetbrains/**")
|
||||||
|
exclude("org/intellij/**")
|
||||||
|
exclude("org/checkerframework/**")
|
||||||
|
exclude("org/json/**")
|
||||||
|
exclude("org/slf4j/**")
|
||||||
|
exclude("org/yaml/**")
|
||||||
|
exclude("google/protobuf/**")
|
||||||
|
exclude("net/kyori/**")
|
||||||
|
|
||||||
|
// MINIFY
|
||||||
|
minimize {
|
||||||
|
exclude(dependency("xyz.xenondevs.invui:.*"))
|
||||||
|
exclude(dependency("de.rapha149.signgui:.*"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
runServer {
|
||||||
|
downloadPlugins {
|
||||||
|
url("https://download.luckperms.net/1593/bukkit/loader/LuckPerms-Bukkit-5.5.8.jar")
|
||||||
|
|
||||||
|
// 1.20.5 - latest testing
|
||||||
|
url("https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBuild/artifact/build/libs/ProtocolLib.jar")
|
||||||
|
}
|
||||||
|
|
||||||
|
minecraftVersion("1.21.5")
|
||||||
|
}
|
||||||
|
}
|
178
core/pom.xml
178
core/pom.xml
|
@ -1,178 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
|
|
||||||
<artifactId>core</artifactId>
|
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<groupId>net.artelnatif</groupId>
|
|
||||||
<artifactId>nicko-parent</artifactId>
|
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<repositories>
|
|
||||||
<repository>
|
|
||||||
<id>papermc</id>
|
|
||||||
<url>https://repo.papermc.io/repository/maven-public/</url>
|
|
||||||
</repository>
|
|
||||||
<repository>
|
|
||||||
<id>spigot-repo</id>
|
|
||||||
<url>https://hub.spigotmc.org/nexus/content/groups/public/</url>
|
|
||||||
</repository>
|
|
||||||
<repository>
|
|
||||||
<id>codemc-snapshots</id>
|
|
||||||
<url>https://repo.codemc.io/repository/maven-snapshots/</url>
|
|
||||||
</repository>
|
|
||||||
<repository>
|
|
||||||
<id>placeholderapi</id>
|
|
||||||
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
|
|
||||||
</repository>
|
|
||||||
</repositories>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<!-- PlaceHolder API -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>me.clip</groupId>
|
|
||||||
<artifactId>placeholderapi</artifactId>
|
|
||||||
<version>2.11.2</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<!-- Spigot API -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.spigotmc</groupId>
|
|
||||||
<artifactId>spigot-api</artifactId>
|
|
||||||
<version>1.19.4-R0.1-SNAPSHOT</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<!-- Inventory Lib -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>xyz.xenondevs.invui</groupId>
|
|
||||||
<artifactId>invui</artifactId>
|
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- AnvilGUI -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.wesjd</groupId>
|
|
||||||
<artifactId>anvilgui</artifactId>
|
|
||||||
<version>1.6.3-SNAPSHOT</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- Google Guava (GSON) -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.guava</groupId>
|
|
||||||
<artifactId>guava</artifactId>
|
|
||||||
<version>31.1-jre</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<!-- MockBukkit 1.19 (Bukkit Unit Tests) -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.github.seeseemelk</groupId>
|
|
||||||
<artifactId>MockBukkit-v1.19</artifactId>
|
|
||||||
<version>2.29.0</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<!-- MariaDB JDBC Driver -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.mariadb.jdbc</groupId>
|
|
||||||
<artifactId>mariadb-java-client</artifactId>
|
|
||||||
<version>3.1.2</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- YAML Reader -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.github.jsixface</groupId>
|
|
||||||
<artifactId>yamlconfig</artifactId>
|
|
||||||
<version>1.1.2</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
|
||||||
<artifactId>jackson-core</artifactId>
|
|
||||||
<version>2.14.2</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
|
||||||
<artifactId>jackson-dataformat-yaml</artifactId>
|
|
||||||
<version>2.14.2</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- Redis -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>redis.clients</groupId>
|
|
||||||
<artifactId>jedis</artifactId>
|
|
||||||
<version>4.3.0</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
|
||||||
<version>3.0.0-M7</version>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
|
||||||
<version>3.3.1-SNAPSHOT</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>shade</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<artifactSet>
|
|
||||||
<includes>
|
|
||||||
<include>net.wesjd:anvilgui</include>
|
|
||||||
<include>xyz.xenondevs.invui:*</include>
|
|
||||||
<include>com.github.jsixface:*</include>
|
|
||||||
<include>com.fasterxml.jackson.dataformat</include>
|
|
||||||
<include>com.fasterxml.jackson.core</include>
|
|
||||||
<include>org.mariadb.jdbc</include>
|
|
||||||
</includes>
|
|
||||||
</artifactSet>
|
|
||||||
<relocations>
|
|
||||||
<relocation>
|
|
||||||
<pattern>net.wesjd.anvilgui</pattern>
|
|
||||||
<shadedPattern>net.artelnatif.libs.anvilgui</shadedPattern>
|
|
||||||
</relocation>
|
|
||||||
<relocation>
|
|
||||||
<pattern>xyz.xenondevs.invui</pattern>
|
|
||||||
<shadedPattern>net.artelnatif.libs.invui</shadedPattern>
|
|
||||||
</relocation>
|
|
||||||
<relocation>
|
|
||||||
<pattern>com.github.jsixface</pattern>
|
|
||||||
<shadedPattern>net.artelnatif.libs.yaml</shadedPattern>
|
|
||||||
</relocation>
|
|
||||||
<relocation>
|
|
||||||
<pattern>com.fasterxml.jackson.dataformat</pattern>
|
|
||||||
<shadedPattern>net.artelnatif.libs.jackson.yaml</shadedPattern>
|
|
||||||
</relocation>
|
|
||||||
<relocation>
|
|
||||||
<pattern>com.fasterxml.jackson.core</pattern>
|
|
||||||
<shadedPattern>net.artelnatif.libs.jackson.core</shadedPattern>
|
|
||||||
</relocation>
|
|
||||||
<relocation>
|
|
||||||
<pattern>org.mariadb.jdbc</pattern>
|
|
||||||
<shadedPattern>net.artelnatif.libs.mariadb</shadedPattern>
|
|
||||||
</relocation>
|
|
||||||
</relocations>
|
|
||||||
<!-- Prevents breaking AnvilGUI's VersionWrapper. -->
|
|
||||||
<minimizeJar>false</minimizeJar>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
<resources>
|
|
||||||
<resource>
|
|
||||||
<filtering>true</filtering>
|
|
||||||
<directory>${basedir}/src/main/resources/</directory>
|
|
||||||
</resource>
|
|
||||||
</resources>
|
|
||||||
</build>
|
|
||||||
</project>
|
|
|
@ -1,167 +0,0 @@
|
||||||
package net.artelnatif.nicko;
|
|
||||||
|
|
||||||
import net.artelnatif.nicko.gui.items.common.OptionUnavailable;
|
|
||||||
import xyz.xenondevs.invui.gui.structure.Structure;
|
|
||||||
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
|
||||||
import xyz.xenondevs.invui.item.impl.SimpleItem;
|
|
||||||
import net.artelnatif.nicko.command.NickoCommand;
|
|
||||||
import net.artelnatif.nicko.config.Configuration;
|
|
||||||
import net.artelnatif.nicko.config.ConfigurationManager;
|
|
||||||
import net.artelnatif.nicko.event.PlayerJoinListener;
|
|
||||||
import net.artelnatif.nicko.event.PlayerQuitListener;
|
|
||||||
import net.artelnatif.nicko.gui.items.main.ExitGUI;
|
|
||||||
import net.artelnatif.nicko.i18n.Locale;
|
|
||||||
import net.artelnatif.nicko.i18n.LocaleFileManager;
|
|
||||||
import net.artelnatif.nicko.impl.Internals;
|
|
||||||
import net.artelnatif.nicko.impl.InternalsProvider;
|
|
||||||
import net.artelnatif.nicko.mojang.MojangAPI;
|
|
||||||
import net.artelnatif.nicko.placeholder.PlaceHolderHook;
|
|
||||||
import net.artelnatif.nicko.storage.PlayerDataStore;
|
|
||||||
import net.artelnatif.nicko.storage.name.PlayerNameStore;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.command.PluginCommand;
|
|
||||||
import org.bukkit.plugin.PluginDescriptionFile;
|
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
|
||||||
import org.bukkit.plugin.java.JavaPluginLoader;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class NickoBukkit extends JavaPlugin {
|
|
||||||
private static NickoBukkit plugin;
|
|
||||||
|
|
||||||
private final boolean unitTesting;
|
|
||||||
|
|
||||||
private MojangAPI mojangAPI;
|
|
||||||
private PlayerDataStore dataStore;
|
|
||||||
private ConfigurationManager configurationManager;
|
|
||||||
private Configuration configuration;
|
|
||||||
private LocaleFileManager localeFileManager;
|
|
||||||
private PlayerNameStore nameStore;
|
|
||||||
|
|
||||||
public NickoBukkit() { this.unitTesting = false; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used by MockBukkit
|
|
||||||
*/
|
|
||||||
protected NickoBukkit(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) {
|
|
||||||
this(loader, description, dataFolder, file, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used by MockBukkit
|
|
||||||
*/
|
|
||||||
protected NickoBukkit(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file, Configuration configuration) {
|
|
||||||
super(loader, description, dataFolder, file);
|
|
||||||
unitTesting = true;
|
|
||||||
this.configuration = configuration;
|
|
||||||
getLogger().info("Unit Testing Mode enabled.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnable() {
|
|
||||||
plugin = this;
|
|
||||||
configurationManager = new ConfigurationManager(getDataFolder());
|
|
||||||
configurationManager.saveDefaultConfig();
|
|
||||||
|
|
||||||
mojangAPI = new MojangAPI();
|
|
||||||
dataStore = new PlayerDataStore(mojangAPI, getNickoConfig());
|
|
||||||
nameStore = new PlayerNameStore();
|
|
||||||
|
|
||||||
if (!dataStore.getStorage().isError()) {
|
|
||||||
getLogger().info("Loading persistence...");
|
|
||||||
if (!dataStore.getStorage().getProvider().init()) {
|
|
||||||
dataStore.getStorage().setError(true);
|
|
||||||
getLogger().severe("Failed to open persistence, data will NOT be saved!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!unitTesting) {
|
|
||||||
getLogger().info("Loading internals...");
|
|
||||||
if (getInternals() == null) {
|
|
||||||
getLogger().severe("Nicko could not find a valid implementation for this server version. Is your server supported?");
|
|
||||||
dataStore.getStorage().setError(true);
|
|
||||||
getServer().getPluginManager().disablePlugin(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
localeFileManager = new LocaleFileManager();
|
|
||||||
if (configuration.isCustomLocale()) {
|
|
||||||
if (localeFileManager.dumpFromLocale(Locale.ENGLISH)) {
|
|
||||||
getLogger().info("Successfully loaded custom language file.");
|
|
||||||
} else {
|
|
||||||
getLogger().severe("Failed to load custom language file!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final PluginCommand command = getCommand("nicko");
|
|
||||||
if (command != null) {
|
|
||||||
command.setExecutor(new NickoCommand());
|
|
||||||
}
|
|
||||||
|
|
||||||
Structure.addGlobalIngredient('#', new SimpleItem(new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE).setDisplayName(" ")));
|
|
||||||
Structure.addGlobalIngredient('%', new SimpleItem(new ItemBuilder(Material.ORANGE_STAINED_GLASS_PANE).setDisplayName(" ")));
|
|
||||||
Structure.addGlobalIngredient('U', new OptionUnavailable());
|
|
||||||
Structure.addGlobalIngredient('E', new ExitGUI());
|
|
||||||
|
|
||||||
new PlaceHolderHook(this).hook();
|
|
||||||
|
|
||||||
getServer().getPluginManager().registerEvents(new PlayerJoinListener(), this);
|
|
||||||
getServer().getPluginManager().registerEvents(new PlayerQuitListener(), this);
|
|
||||||
|
|
||||||
getLogger().info("Nicko (Bukkit) has been enabled.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDisable() {
|
|
||||||
if (!getDataStore().getStorage().isError()) {
|
|
||||||
getLogger().info("Closing persistence...");
|
|
||||||
nameStore.clearStoredNames();
|
|
||||||
Bukkit.getOnlinePlayers().forEach(player -> dataStore.saveData(player));
|
|
||||||
if (!dataStore.getStorage().getProvider().close()) {
|
|
||||||
getLogger().severe("Failed to close persistence!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getLogger().info("Nicko (Bukkit) has been disabled.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static NickoBukkit getInstance() {
|
|
||||||
return plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Configuration getNickoConfig() {
|
|
||||||
try {
|
|
||||||
if (configuration == null) { return configuration = configurationManager.load(); }
|
|
||||||
return configuration;
|
|
||||||
} catch (IOException e) {
|
|
||||||
getLogger().severe("Failed to load the configuration file!");
|
|
||||||
getLogger().severe("It may be have been generated with an older version of Nicko.");
|
|
||||||
getLogger().severe("Delete the configuration and restart the server please :)");
|
|
||||||
getLogger().severe("(" + e.getMessage() + ")");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public PlayerDataStore getDataStore() {
|
|
||||||
return dataStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PlayerNameStore getNameStore() {
|
|
||||||
return nameStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MojangAPI getMojangAPI() {
|
|
||||||
return mojangAPI;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocaleFileManager getLocaleFileManager() {
|
|
||||||
return localeFileManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Internals getInternals() {
|
|
||||||
return InternalsProvider.getInternals();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,106 +0,0 @@
|
||||||
package net.artelnatif.nicko.anvil;
|
|
||||||
|
|
||||||
import net.artelnatif.nicko.NickoBukkit;
|
|
||||||
import net.artelnatif.nicko.appearance.AppearanceManager;
|
|
||||||
import net.artelnatif.nicko.disguise.ActionResult;
|
|
||||||
import net.artelnatif.nicko.i18n.I18N;
|
|
||||||
import net.artelnatif.nicko.i18n.I18NDict;
|
|
||||||
import net.artelnatif.nicko.mojang.MojangUtils;
|
|
||||||
import net.wesjd.anvilgui.AnvilGUI;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class AnvilManager {
|
|
||||||
private final Player player;
|
|
||||||
private final AppearanceManager appearanceManager;
|
|
||||||
|
|
||||||
public AnvilManager(Player player) {
|
|
||||||
this.player = player;
|
|
||||||
this.appearanceManager = AppearanceManager.get(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void openNameThenSkinAnvil() {
|
|
||||||
getNameThenSkinAnvil().open(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void openSkinAnvil() {
|
|
||||||
getSkinAnvil().open(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void openNameAnvil() {
|
|
||||||
getNameAnvil().open(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AnvilGUI.Builder getNameThenSkinAnvil() {
|
|
||||||
return new AnvilGUI.Builder()
|
|
||||||
.plugin(NickoBukkit.getInstance())
|
|
||||||
.itemLeft(getLeftItem(false))
|
|
||||||
.interactableSlots(AnvilGUI.Slot.OUTPUT)
|
|
||||||
.onComplete((completion) -> {
|
|
||||||
if (MojangUtils.isUsernameInvalid(completion.getText())) {
|
|
||||||
return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!"));
|
|
||||||
} else {
|
|
||||||
appearanceManager.setName(completion.getText());
|
|
||||||
openSkinAnvil();
|
|
||||||
return Collections.singletonList(AnvilGUI.ResponseAction.close());
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.text("New name...");
|
|
||||||
}
|
|
||||||
|
|
||||||
public AnvilGUI.Builder getNameAnvil() {
|
|
||||||
return new AnvilGUI.Builder()
|
|
||||||
.plugin(NickoBukkit.getInstance())
|
|
||||||
.itemLeft(getLeftItem(false))
|
|
||||||
.interactableSlots(AnvilGUI.Slot.OUTPUT)
|
|
||||||
.onComplete((completion) -> {
|
|
||||||
if (MojangUtils.isUsernameInvalid(completion.getText())) {
|
|
||||||
return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!"));
|
|
||||||
} else {
|
|
||||||
appearanceManager.setName(completion.getText());
|
|
||||||
final ActionResult<Void> actionResult = appearanceManager.updatePlayer(false);
|
|
||||||
return sendResultAndClose(actionResult);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.text("New name...");
|
|
||||||
}
|
|
||||||
|
|
||||||
private AnvilGUI.Builder getSkinAnvil() {
|
|
||||||
return new AnvilGUI.Builder()
|
|
||||||
.plugin(NickoBukkit.getInstance())
|
|
||||||
.itemLeft(getLeftItem(true))
|
|
||||||
.interactableSlots(AnvilGUI.Slot.OUTPUT)
|
|
||||||
.onComplete((completion) -> {
|
|
||||||
if (MojangUtils.isUsernameInvalid(completion.getText())) {
|
|
||||||
return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!"));
|
|
||||||
} else {
|
|
||||||
appearanceManager.setSkin(completion.getText());
|
|
||||||
final ActionResult<Void> actionResult = appearanceManager.updatePlayer(true);
|
|
||||||
return sendResultAndClose(actionResult);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.text("New skin...");
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<AnvilGUI.ResponseAction> sendResultAndClose(ActionResult<Void> actionResult) {
|
|
||||||
if (!actionResult.isError()) {
|
|
||||||
player.sendMessage(I18N.translate(player, I18NDict.Event.Disguise.SUCCESS));
|
|
||||||
} else {
|
|
||||||
player.sendMessage(I18N.translate(player, I18NDict.Event.Disguise.FAIL, I18N.translateWithoutPrefix(player, actionResult.getErrorMessage())));
|
|
||||||
}
|
|
||||||
return Collections.singletonList(AnvilGUI.ResponseAction.close());
|
|
||||||
}
|
|
||||||
|
|
||||||
private ItemStack getLeftItem(boolean skin) {
|
|
||||||
final ItemStack item = new ItemStack(Material.PAPER);
|
|
||||||
final ItemMeta meta = item.getItemMeta();
|
|
||||||
meta.setDisplayName("§0New " + (skin ? "skin" : "name") + "...");
|
|
||||||
item.setItemMeta(meta);
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,89 +0,0 @@
|
||||||
package net.artelnatif.nicko.appearance;
|
|
||||||
|
|
||||||
import net.artelnatif.nicko.NickoBukkit;
|
|
||||||
import net.artelnatif.nicko.disguise.ActionResult;
|
|
||||||
import net.artelnatif.nicko.disguise.NickoProfile;
|
|
||||||
import net.artelnatif.nicko.storage.PlayerDataStore;
|
|
||||||
import net.artelnatif.nicko.storage.name.PlayerNameStore;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class AppearanceManager {
|
|
||||||
private final NickoProfile profile;
|
|
||||||
private final Player player;
|
|
||||||
private final NickoBukkit instance = NickoBukkit.getInstance();
|
|
||||||
private final PlayerDataStore dataStore = instance.getDataStore();
|
|
||||||
private final PlayerNameStore nameStore = instance.getNameStore();
|
|
||||||
|
|
||||||
private AppearanceManager(UUID uuid) {
|
|
||||||
this.player = Bukkit.getPlayer(uuid);
|
|
||||||
this.profile = dataStore.getData(uuid).orElse(NickoProfile.EMPTY_PROFILE.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
private AppearanceManager(String name) {
|
|
||||||
this.player = null;
|
|
||||||
this.profile = dataStore.getOfflineData(name).orElse(NickoProfile.EMPTY_PROFILE.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AppearanceManager get(Player player) {
|
|
||||||
return new AppearanceManager(player.getUniqueId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AppearanceManager get(String name) {
|
|
||||||
return new AppearanceManager(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasData() {
|
|
||||||
return !profile.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSkin(String skin) {
|
|
||||||
profile.setSkin(skin);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSkin() {
|
|
||||||
return profile.getSkin();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean needsASkinChange() {
|
|
||||||
return profile.getSkin() != null && !profile.getSkin().equals(player.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
profile.setName(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return profile.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
public NickoProfile getProfile() {
|
|
||||||
return profile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNameAndSkin(String name, String skin) {
|
|
||||||
this.profile.setName(name);
|
|
||||||
this.profile.setSkin(skin);
|
|
||||||
updatePlayer(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionResult<Void> reset() {
|
|
||||||
final String defaultName = nameStore.getStoredName(player);
|
|
||||||
this.profile.setName(defaultName);
|
|
||||||
this.profile.setSkin(defaultName);
|
|
||||||
final ActionResult<Void> actionResult = resetPlayer();
|
|
||||||
this.profile.setSkin(null);
|
|
||||||
this.profile.setName(null);
|
|
||||||
return actionResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionResult<Void> resetPlayer() {
|
|
||||||
return NickoBukkit.getInstance().getInternals().updateProfile(player, profile, true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionResult<Void> updatePlayer(boolean skinChange) {
|
|
||||||
return NickoBukkit.getInstance().getInternals().updateProfile(player, profile, skinChange, false);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
package net.artelnatif.nicko.command;
|
|
||||||
|
|
||||||
import net.artelnatif.nicko.NickoBukkit;
|
|
||||||
import net.artelnatif.nicko.command.sub.NickoCheckSubCmd;
|
|
||||||
import net.artelnatif.nicko.command.sub.NickoDebugSubCmd;
|
|
||||||
import net.artelnatif.nicko.gui.MainGUI;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandExecutor;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class NickoCommand implements CommandExecutor {
|
|
||||||
private String helpMessage = "§cNicko §8§o[{version}] §f- §2Help:\n" +
|
|
||||||
"§6/nicko §f- §7Open the GUI.\n" +
|
|
||||||
"§6/nicko help §f- §7Print this help message.\n";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
|
||||||
if (sender instanceof Player) {
|
|
||||||
Player player = (Player) sender;
|
|
||||||
if (args.length >= 1) {
|
|
||||||
switch (args[0]) {
|
|
||||||
case "debug":
|
|
||||||
new NickoDebugSubCmd().execute(player, args);
|
|
||||||
break;
|
|
||||||
case "check":
|
|
||||||
new NickoCheckSubCmd().execute(player, args);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
sendHelpMessage(sender);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
new MainGUI(player).open();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
sender.sendMessage("This plugin can only be used in-game. Sorry!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendHelpMessage(CommandSender sender) {
|
|
||||||
helpMessage = helpMessage.replace("{version}", NickoBukkit.getInstance().getDescription().getVersion());
|
|
||||||
sender.sendMessage(helpMessage);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
package net.artelnatif.nicko.command.sub;
|
|
||||||
|
|
||||||
import net.artelnatif.nicko.NickoBukkit;
|
|
||||||
import net.artelnatif.nicko.appearance.AppearanceManager;
|
|
||||||
import net.artelnatif.nicko.i18n.I18N;
|
|
||||||
import net.artelnatif.nicko.i18n.I18NDict;
|
|
||||||
import net.artelnatif.nicko.mojang.MojangUtils;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.StringJoiner;
|
|
||||||
|
|
||||||
public class NickoCheckSubCmd {
|
|
||||||
public void execute(Player player, String[] args) {
|
|
||||||
final String targetName = args[1];
|
|
||||||
final Player target = Bukkit.getPlayerExact(targetName);
|
|
||||||
|
|
||||||
AppearanceManager appearanceManager;
|
|
||||||
if (MojangUtils.isUsernameInvalid(targetName)) {
|
|
||||||
player.sendMessage(I18N.translate(player, I18NDict.Error.INVALID_USERNAME));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target == null) {
|
|
||||||
appearanceManager = AppearanceManager.get(targetName);
|
|
||||||
} else {
|
|
||||||
appearanceManager = AppearanceManager.get(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
final StringJoiner builder = new StringJoiner("\n");
|
|
||||||
builder.add("§c" + NickoBukkit.getInstance().getNickoConfig().getPrefix() + "§6Check for: §f§o" + targetName);
|
|
||||||
if (!appearanceManager.hasData()) {
|
|
||||||
builder.add("§cThis player has not data.");
|
|
||||||
} else {
|
|
||||||
builder.add("§7- §fNicked: §a✔");
|
|
||||||
builder.add("§7- §fName: §6" + appearanceManager.getName());
|
|
||||||
builder.add("§7- §fSkin: §6" + appearanceManager.getSkin());
|
|
||||||
}
|
|
||||||
|
|
||||||
player.sendMessage(builder.toString());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
package net.artelnatif.nicko.command.sub;
|
|
||||||
|
|
||||||
import net.artelnatif.nicko.NickoBukkit;
|
|
||||||
import net.artelnatif.nicko.appearance.AppearanceManager;
|
|
||||||
import net.artelnatif.nicko.mojang.MojangUtils;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Sound;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class NickoDebugSubCmd {
|
|
||||||
public void execute(CommandSender sender, String[] args) {
|
|
||||||
final String prefix = NickoBukkit.getInstance().getNickoConfig().getPrefix();
|
|
||||||
|
|
||||||
Player target;
|
|
||||||
String name, skin;
|
|
||||||
if (args.length == 3) {
|
|
||||||
target = (Player) sender;
|
|
||||||
name = args[1];
|
|
||||||
skin = args[2];
|
|
||||||
} else {
|
|
||||||
if (args.length < 3) {
|
|
||||||
sender.sendMessage(prefix + "§cMissing argument.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final String playerName = args[1];
|
|
||||||
name = args[2];
|
|
||||||
skin = args[3];
|
|
||||||
|
|
||||||
target = Bukkit.getPlayer(playerName);
|
|
||||||
if (target == null) {
|
|
||||||
sender.sendMessage(prefix + "§cSpecified player is offline.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final AppearanceManager appearanceManager = AppearanceManager.get(target.getPlayer());
|
|
||||||
|
|
||||||
if (MojangUtils.isUsernameInvalid(name) || MojangUtils.isUsernameInvalid(skin)) {
|
|
||||||
sender.sendMessage(prefix + "§cSpecified username is invalid.");
|
|
||||||
}
|
|
||||||
|
|
||||||
appearanceManager.setNameAndSkin(name, skin);
|
|
||||||
target.sendMessage(prefix + "§aWhoosh!");
|
|
||||||
target.playSound(target.getLocation(), Sound.ENTITY_ITEM_FRAME_PLACE, 1, 1);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
package net.artelnatif.nicko.config;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
|
|
||||||
public class Configuration {
|
|
||||||
@JsonProperty("sql")
|
|
||||||
private final DataSourceConfiguration sqlConfiguration;
|
|
||||||
@JsonProperty("redis")
|
|
||||||
private final DataSourceConfiguration redisConfiguration;
|
|
||||||
private final String prefix;
|
|
||||||
private final Boolean local;
|
|
||||||
private final Boolean customLocale;
|
|
||||||
|
|
||||||
public Configuration(DataSourceConfiguration sqlConfiguration, DataSourceConfiguration redisConfiguration, String prefix, Boolean local, Boolean customLocale) {
|
|
||||||
this.sqlConfiguration = sqlConfiguration;
|
|
||||||
this.redisConfiguration = redisConfiguration;
|
|
||||||
this.prefix = prefix;
|
|
||||||
this.local = local;
|
|
||||||
this.customLocale = customLocale;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Configuration() {
|
|
||||||
this(
|
|
||||||
new DataSourceConfiguration("", 3306, "", ""),
|
|
||||||
new DataSourceConfiguration("", 6379, "", ""),
|
|
||||||
"",
|
|
||||||
false,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DataSourceConfiguration getSqlConfiguration() {
|
|
||||||
return sqlConfiguration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DataSourceConfiguration getRedisConfiguration() {
|
|
||||||
return redisConfiguration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPrefix() {
|
|
||||||
return prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean isLocal() {
|
|
||||||
return local;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean isCustomLocale() {
|
|
||||||
return customLocale;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
package net.artelnatif.nicko.config;
|
|
||||||
|
|
||||||
public class DataSourceConfiguration {
|
|
||||||
public static final DataSourceConfiguration SQL_EMPTY = new DataSourceConfiguration("127.0.0.1", 3306, "root", "");
|
|
||||||
public static final DataSourceConfiguration REDIS_EMPTY = new DataSourceConfiguration("127.0.0.1", 6379, "", "");
|
|
||||||
|
|
||||||
private final String address;
|
|
||||||
private final Integer port;
|
|
||||||
private final String username;
|
|
||||||
private final String password;
|
|
||||||
|
|
||||||
public DataSourceConfiguration(String address, Integer port, String username, String password) {
|
|
||||||
this.address = address;
|
|
||||||
this.port = port;
|
|
||||||
this.username = username;
|
|
||||||
this.password = password;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DataSourceConfiguration() { this("", 0, "", ""); }
|
|
||||||
|
|
||||||
public String getAddress() {
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getPort() {
|
|
||||||
return port;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUsername() {
|
|
||||||
return username;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPassword() {
|
|
||||||
return password;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
package net.artelnatif.nicko.disguise;
|
|
||||||
|
|
||||||
import net.artelnatif.nicko.i18n.I18NDict;
|
|
||||||
|
|
||||||
public class ActionResult<R> {
|
|
||||||
private final I18NDict errorMessage;
|
|
||||||
private boolean error = false;
|
|
||||||
private R result;
|
|
||||||
|
|
||||||
public ActionResult() {
|
|
||||||
this.errorMessage = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionResult(I18NDict errorMessage) {
|
|
||||||
this.errorMessage = errorMessage;
|
|
||||||
this.error = true;
|
|
||||||
this.result = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionResult(R result) {
|
|
||||||
this.errorMessage = null;
|
|
||||||
this.result = result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public R getResult() {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isError() {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
public I18NDict getErrorMessage() {
|
|
||||||
return errorMessage;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
package net.artelnatif.nicko.disguise;
|
|
||||||
|
|
||||||
import net.artelnatif.nicko.i18n.Locale;
|
|
||||||
|
|
||||||
public class NickoProfile implements Cloneable {
|
|
||||||
public static final NickoProfile EMPTY_PROFILE = new NickoProfile(null, null, Locale.ENGLISH, true);
|
|
||||||
|
|
||||||
private String name;
|
|
||||||
private String skin;
|
|
||||||
private Locale locale;
|
|
||||||
private boolean bungeecordTransfer;
|
|
||||||
|
|
||||||
public NickoProfile(String name, String skin, Locale locale, boolean bungeecordTransfer) {
|
|
||||||
this.name = name;
|
|
||||||
this.skin = skin;
|
|
||||||
this.locale = locale;
|
|
||||||
this.bungeecordTransfer = bungeecordTransfer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEmpty() {
|
|
||||||
return name == null && skin == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSkin() {
|
|
||||||
return skin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSkin(String skin) {
|
|
||||||
this.skin = skin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Locale getLocale() { return locale; }
|
|
||||||
|
|
||||||
public void setLocale(Locale locale) { this.locale = locale; }
|
|
||||||
|
|
||||||
public boolean isBungeecordTransfer() {
|
|
||||||
return bungeecordTransfer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBungeecordTransfer(boolean bungeecordTransfer) {
|
|
||||||
this.bungeecordTransfer = bungeecordTransfer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "NickoProfile{" +
|
|
||||||
"name='" + name + '\'' +
|
|
||||||
", skin='" + skin + '\'' +
|
|
||||||
", locale=" + locale +
|
|
||||||
", bungeecordTransfer=" + bungeecordTransfer +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NickoProfile clone() {
|
|
||||||
Object o;
|
|
||||||
try {
|
|
||||||
o = super.clone();
|
|
||||||
} catch (CloneNotSupportedException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
return (NickoProfile) o;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
package net.artelnatif.nicko.event;
|
|
||||||
|
|
||||||
import net.artelnatif.nicko.NickoBukkit;
|
|
||||||
import net.artelnatif.nicko.appearance.AppearanceManager;
|
|
||||||
import net.artelnatif.nicko.disguise.ActionResult;
|
|
||||||
import net.artelnatif.nicko.disguise.NickoProfile;
|
|
||||||
import net.artelnatif.nicko.i18n.I18N;
|
|
||||||
import net.artelnatif.nicko.i18n.I18NDict;
|
|
||||||
import net.artelnatif.nicko.storage.PlayerDataStore;
|
|
||||||
import net.artelnatif.nicko.storage.name.PlayerNameStore;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
|
||||||
|
|
||||||
public class PlayerJoinListener implements Listener {
|
|
||||||
@EventHandler
|
|
||||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
|
||||||
final Player player = event.getPlayer();
|
|
||||||
final NickoBukkit instance = NickoBukkit.getInstance();
|
|
||||||
|
|
||||||
final PlayerDataStore dataStore = instance.getDataStore();
|
|
||||||
final PlayerNameStore nameStore = instance.getNameStore();
|
|
||||||
nameStore.storeName(player);
|
|
||||||
|
|
||||||
// TODO: 2/20/23 BungeeCord transfer
|
|
||||||
|
|
||||||
dataStore.performProfileUpdate(player.getUniqueId(), NickoProfile.EMPTY_PROFILE);
|
|
||||||
Bukkit.getScheduler().runTaskLater(instance, () -> {
|
|
||||||
final AppearanceManager appearanceManager = AppearanceManager.get(player);
|
|
||||||
if (appearanceManager.hasData()) {
|
|
||||||
final ActionResult<Void> actionResult = appearanceManager.updatePlayer(appearanceManager.needsASkinChange());
|
|
||||||
if (!actionResult.isError()) {
|
|
||||||
player.sendMessage(I18N.translate(player, I18NDict.Event.PreviousSkin.SUCCESS));
|
|
||||||
} else {
|
|
||||||
player.sendMessage(I18N.translate(player, I18NDict.Event.PreviousSkin.FAIL, I18N.translate(player, actionResult.getErrorMessage())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 20L);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
package net.artelnatif.nicko.event;
|
|
||||||
|
|
||||||
import net.artelnatif.nicko.NickoBukkit;
|
|
||||||
import net.artelnatif.nicko.disguise.ActionResult;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
|
||||||
|
|
||||||
public class PlayerQuitListener implements Listener {
|
|
||||||
@EventHandler
|
|
||||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
|
||||||
final Player player = event.getPlayer();
|
|
||||||
final ActionResult<Void> result = NickoBukkit.getInstance().getDataStore().saveData(player);
|
|
||||||
if (result.isError()) {
|
|
||||||
NickoBukkit.getInstance().getLogger().warning("Failed to save data for " + player.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
package net.artelnatif.nicko.gui;
|
|
||||||
|
|
||||||
import net.artelnatif.nicko.gui.items.admin.ManageCache;
|
|
||||||
import net.artelnatif.nicko.gui.items.common.GoBack;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import xyz.xenondevs.invui.gui.Gui;
|
|
||||||
import xyz.xenondevs.invui.window.Window;
|
|
||||||
|
|
||||||
public class AdminGUI {
|
|
||||||
public static final String TITLE = "Nicko > Administration";
|
|
||||||
|
|
||||||
private final Player player;
|
|
||||||
private final Gui gui;
|
|
||||||
|
|
||||||
public AdminGUI(Player player) {
|
|
||||||
this.gui = Gui.normal()
|
|
||||||
.setStructure(
|
|
||||||
"# # # # # # # # #",
|
|
||||||
"# # # S U U # # #",
|
|
||||||
"B # # # # # # # #"
|
|
||||||
)
|
|
||||||
.addIngredient('S', new ManageCache())
|
|
||||||
.addIngredient('B', new GoBack(new MainGUI(player).getGUI()))
|
|
||||||
.build();
|
|
||||||
this.player = player;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Gui getGUI() {
|
|
||||||
return gui;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void open() {
|
|
||||||
Window.single().setGui(gui).setTitle(TITLE).open(player);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
package net.artelnatif.nicko.gui;
|
|
||||||
|
|
||||||
import net.artelnatif.nicko.gui.items.main.AdminSubGUI;
|
|
||||||
import net.artelnatif.nicko.gui.items.main.ResetAppearance;
|
|
||||||
import net.artelnatif.nicko.gui.items.main.SettingsSubGUI;
|
|
||||||
import net.artelnatif.nicko.gui.items.skin.ChangeName;
|
|
||||||
import net.artelnatif.nicko.gui.items.skin.ChangeNameAndSkin;
|
|
||||||
import net.artelnatif.nicko.gui.items.skin.ChangeSkin;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import xyz.xenondevs.invui.gui.Gui;
|
|
||||||
import xyz.xenondevs.invui.window.Window;
|
|
||||||
|
|
||||||
public class MainGUI {
|
|
||||||
private final Player player;
|
|
||||||
private final Gui gui;
|
|
||||||
|
|
||||||
public MainGUI(Player player) {
|
|
||||||
final String[] dynamicStructure = new String[]{
|
|
||||||
"# # # # # # # # #",
|
|
||||||
"# # # N B S # # #",
|
|
||||||
"E P A # # # # # R"};
|
|
||||||
|
|
||||||
if (!player.hasPermission("nicko.admin") || !player.isOp()) {
|
|
||||||
dynamicStructure[2] = dynamicStructure[2].replace("A", "#");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.gui = Gui.normal()
|
|
||||||
.setStructure(dynamicStructure)
|
|
||||||
.addIngredient('R', new ResetAppearance())
|
|
||||||
.addIngredient('N', new ChangeName())
|
|
||||||
.addIngredient('B', new ChangeNameAndSkin())
|
|
||||||
.addIngredient('S', new ChangeSkin(player))
|
|
||||||
.addIngredient('P', new SettingsSubGUI())
|
|
||||||
.addIngredient('A', new AdminSubGUI())
|
|
||||||
.build();
|
|
||||||
this.player = player;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Gui getGUI() {
|
|
||||||
return gui;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void open() {
|
|
||||||
Window.single().setGui(gui).setTitle("Nicko - Home").open(player);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
package net.artelnatif.nicko.gui;
|
|
||||||
|
|
||||||
import net.artelnatif.nicko.gui.items.common.GoBack;
|
|
||||||
import net.artelnatif.nicko.gui.items.settings.BungeeCordCycling;
|
|
||||||
import net.artelnatif.nicko.gui.items.settings.LanguageCycling;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import xyz.xenondevs.invui.gui.Gui;
|
|
||||||
import xyz.xenondevs.invui.window.Window;
|
|
||||||
|
|
||||||
public class SettingsGUI {
|
|
||||||
public static final String TITLE = "Nicko > Settings";
|
|
||||||
|
|
||||||
private final Player player;
|
|
||||||
private final Gui gui;
|
|
||||||
|
|
||||||
public SettingsGUI(Player player) {
|
|
||||||
final String[] dynamicStructure = new String[]{
|
|
||||||
"# # # # # # # # #",
|
|
||||||
"# # # L T U # # #",
|
|
||||||
"B # # # # # # # #"
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: 3/6/23 Replace when Redis is not enabled
|
|
||||||
dynamicStructure[1] = dynamicStructure[1].replace("T", "U");
|
|
||||||
|
|
||||||
this.gui = Gui.normal()
|
|
||||||
.setStructure(dynamicStructure)
|
|
||||||
.addIngredient('B', new GoBack(new MainGUI(player).getGUI()))
|
|
||||||
.addIngredient('L', new LanguageCycling().get(player))
|
|
||||||
.addIngredient('T', new BungeeCordCycling().get(player))
|
|
||||||
.build();
|
|
||||||
this.player = player;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void open() {
|
|
||||||
Window.single().setGui(gui).setTitle(TITLE).open(player);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
package net.artelnatif.nicko.gui.admin;
|
|
||||||
|
|
||||||
import net.artelnatif.nicko.gui.AdminGUI;
|
|
||||||
import net.artelnatif.nicko.gui.items.admin.cache.CacheDetailed;
|
|
||||||
import net.artelnatif.nicko.gui.items.admin.cache.CacheInvalidate;
|
|
||||||
import net.artelnatif.nicko.gui.items.admin.cache.CacheOverview;
|
|
||||||
import net.artelnatif.nicko.gui.items.common.GoBack;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import xyz.xenondevs.invui.gui.Gui;
|
|
||||||
import xyz.xenondevs.invui.window.Window;
|
|
||||||
|
|
||||||
public class CacheManagementGUI {
|
|
||||||
public static final String TITLE = "Nicko > Admin... > Cache";
|
|
||||||
|
|
||||||
private final Player player;
|
|
||||||
private final Gui gui;
|
|
||||||
|
|
||||||
public CacheManagementGUI(Player player) {
|
|
||||||
this.gui = Gui.normal()
|
|
||||||
.setStructure("B # S A D")
|
|
||||||
.addIngredient('B', new GoBack(new AdminGUI(player).getGUI()))
|
|
||||||
.addIngredient('S', new CacheOverview())
|
|
||||||
.addIngredient('A', new CacheInvalidate())
|
|
||||||
.addIngredient('D', new CacheDetailed())
|
|
||||||
.build();
|
|
||||||
this.player = player;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Gui getGUI() {
|
|
||||||
return gui;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void open() {
|
|
||||||
Window.single().setGui(gui).setTitle(TITLE).open(player);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,61 +0,0 @@
|
||||||
package net.artelnatif.nicko.gui.admin.cache;
|
|
||||||
|
|
||||||
import xyz.xenondevs.invui.gui.Gui;
|
|
||||||
import xyz.xenondevs.invui.gui.ScrollGui;
|
|
||||||
import xyz.xenondevs.invui.gui.structure.Markers;
|
|
||||||
import xyz.xenondevs.invui.item.Item;
|
|
||||||
import net.artelnatif.nicko.NickoBukkit;
|
|
||||||
import net.artelnatif.nicko.gui.items.admin.cache.SkinPlaceholder;
|
|
||||||
import net.artelnatif.nicko.gui.admin.CacheManagementGUI;
|
|
||||||
import net.artelnatif.nicko.gui.items.common.GoBack;
|
|
||||||
import net.artelnatif.nicko.gui.items.common.ScrollDown;
|
|
||||||
import net.artelnatif.nicko.gui.items.common.ScrollUp;
|
|
||||||
import net.artelnatif.nicko.mojang.MojangSkin;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import xyz.xenondevs.invui.window.Window;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.concurrent.ConcurrentMap;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class CacheDetailedGUI {
|
|
||||||
public static final String TITLE = "... > Cache > Invalidate";
|
|
||||||
|
|
||||||
private final Player player;
|
|
||||||
private final Gui gui;
|
|
||||||
|
|
||||||
public CacheDetailedGUI(Player player) {
|
|
||||||
final ConcurrentMap<String, Optional<MojangSkin>> skins = NickoBukkit.getInstance().getMojangAPI().getCache().asMap();
|
|
||||||
final List<String> loadedSkins = skins.entrySet().stream()
|
|
||||||
.filter(entry -> entry.getValue().isPresent())
|
|
||||||
.map(Map.Entry::getKey)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
final List<Item> items = loadedSkins.stream()
|
|
||||||
.map(SkinPlaceholder::new)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
gui = ScrollGui.items(guiItemBuilder -> {
|
|
||||||
guiItemBuilder.setStructure(
|
|
||||||
"# # # # # # # # #",
|
|
||||||
"# x x x x x x U #",
|
|
||||||
"# x x x x x x # #",
|
|
||||||
"# x x x x x x # #",
|
|
||||||
"# x x x x x x D #",
|
|
||||||
"B # # # # # # # #");
|
|
||||||
guiItemBuilder.addIngredient('x', Markers.CONTENT_LIST_SLOT_HORIZONTAL);
|
|
||||||
guiItemBuilder.addIngredient('U', new ScrollUp());
|
|
||||||
guiItemBuilder.addIngredient('D', new ScrollDown());
|
|
||||||
guiItemBuilder.addIngredient('B', new GoBack(new CacheManagementGUI(player).getGUI()));
|
|
||||||
guiItemBuilder.setContent(items);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.player = player;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void open() {
|
|
||||||
Window.single().setGui(gui).setTitle(TITLE).open(player);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
package net.artelnatif.nicko.gui.items.admin;
|
|
||||||
|
|
||||||
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
|
||||||
import xyz.xenondevs.invui.item.builder.SkullBuilder;
|
|
||||||
import xyz.xenondevs.invui.item.impl.AsyncItem;
|
|
||||||
import net.artelnatif.nicko.gui.admin.CacheManagementGUI;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.inventory.ClickType;
|
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public class ManageCache extends AsyncItem {
|
|
||||||
public ManageCache() {
|
|
||||||
super(new ItemBuilder(Material.PAINTING)
|
|
||||||
.setDisplayName("§fManage §6skin §fcache...")
|
|
||||||
.addLoreLines("§7Access the skin cache management panel."),
|
|
||||||
() -> {
|
|
||||||
final SkullBuilder builder = new SkullBuilder("Notch");
|
|
||||||
builder.setDisplayName("§fManage §6skin §fcache...");
|
|
||||||
builder.addLoreLines("§7Access the skin cache management panel.");
|
|
||||||
return builder;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {
|
|
||||||
if (clickType.isLeftClick() || clickType.isRightClick()) {
|
|
||||||
event.getView().close();
|
|
||||||
new CacheManagementGUI(player).open();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
package net.artelnatif.nicko.gui.items.admin.cache;
|
|
||||||
|
|
||||||
import net.artelnatif.nicko.gui.admin.cache.CacheDetailedGUI;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.event.inventory.ClickType;
|
|
||||||
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
|
||||||
import xyz.xenondevs.invui.item.impl.SuppliedItem;
|
|
||||||
|
|
||||||
public class CacheDetailed extends SuppliedItem {
|
|
||||||
public CacheDetailed() {
|
|
||||||
super(() -> {
|
|
||||||
final ItemBuilder builder = new ItemBuilder(Material.PAPER);
|
|
||||||
builder.setDisplayName("§6Invalidate specific skin...");
|
|
||||||
builder.addLoreLines("§7Select a specific skin to invalidate.");
|
|
||||||
return builder;
|
|
||||||
}, (click) -> {
|
|
||||||
final ClickType clickType = click.getClickType();
|
|
||||||
if (clickType.isLeftClick() || clickType.isRightClick()) {
|
|
||||||
click.getEvent().getView().close();
|
|
||||||
new CacheDetailedGUI(click.getPlayer()).open();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
package net.artelnatif.nicko.gui.items.admin.cache;
|
|
||||||
|
|
||||||
import net.artelnatif.nicko.NickoBukkit;
|
|
||||||
import net.artelnatif.nicko.i18n.I18N;
|
|
||||||
import net.artelnatif.nicko.i18n.I18NDict;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.inventory.ClickType;
|
|
||||||
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
|
||||||
import xyz.xenondevs.invui.item.impl.SuppliedItem;
|
|
||||||
|
|
||||||
public class CacheInvalidate extends SuppliedItem {
|
|
||||||
public CacheInvalidate() {
|
|
||||||
super(() -> {
|
|
||||||
final ItemBuilder builder = new ItemBuilder(Material.TNT);
|
|
||||||
builder.setDisplayName("§fInvalidate §6skin cache");
|
|
||||||
builder.addLoreLines(
|
|
||||||
"§c§oNOT RECOMMENDED",
|
|
||||||
"§7Invalidates every skin entry present in the cache.",
|
|
||||||
"§7Does not reset player disguises.",
|
|
||||||
"§7Could be useful if a skin has been updated",
|
|
||||||
"§7recently and the cache is now outdated.");
|
|
||||||
return builder;
|
|
||||||
}, (click) -> {
|
|
||||||
final ClickType clickType = click.getClickType();
|
|
||||||
if (clickType.isLeftClick() || clickType.isRightClick()) {
|
|
||||||
final Player player = click.getPlayer();
|
|
||||||
click.getEvent().getView().close();
|
|
||||||
player.sendMessage(I18N.translate(player, I18NDict.Event.Admin.CACHE_CLEAN));
|
|
||||||
NickoBukkit.getInstance().getMojangAPI().getCache().invalidateAll();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
package net.artelnatif.nicko.gui.items.admin.cache;
|
|
||||||
|
|
||||||
import com.google.common.cache.CacheStats;
|
|
||||||
import com.google.common.cache.LoadingCache;
|
|
||||||
import net.artelnatif.nicko.NickoBukkit;
|
|
||||||
import net.artelnatif.nicko.mojang.MojangSkin;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
|
||||||
import xyz.xenondevs.invui.item.impl.SuppliedItem;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public class CacheOverview extends SuppliedItem {
|
|
||||||
public CacheOverview() {
|
|
||||||
super(() -> {
|
|
||||||
final ItemBuilder builder = new ItemBuilder(Material.OAK_SIGN);
|
|
||||||
final LoadingCache<String, Optional<MojangSkin>> cache = NickoBukkit.getInstance().getMojangAPI().getCache();
|
|
||||||
final CacheStats stats = cache.stats();
|
|
||||||
builder.setDisplayName("§6Skin cache §foverview:");
|
|
||||||
builder.addLoreLines(
|
|
||||||
"Request Count: §2" + stats.requestCount(),
|
|
||||||
"Skin Cached: §2" + Math.round(cache.size()),
|
|
||||||
"§7§oCache is cleared every 24 hours.",
|
|
||||||
"§7§o(Click to refresh)");
|
|
||||||
return builder;
|
|
||||||
}, (event) -> true);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package net.artelnatif.nicko.gui.items.admin.cache;
|
|
||||||
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
|
||||||
import xyz.xenondevs.invui.item.builder.SkullBuilder;
|
|
||||||
import xyz.xenondevs.invui.item.impl.AsyncItem;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class SkinPlaceholder extends AsyncItem {
|
|
||||||
public SkinPlaceholder(String name) {
|
|
||||||
super(new ItemBuilder(Material.PAINTING).setDisplayName("§7§oLoading..."), () -> {
|
|
||||||
final String stringUUID = name.replaceAll("(.{8})(.{4})(.{4})(.{4})(.+)", "$1-$2-$3-$4-$5");
|
|
||||||
final UUID uuid = UUID.fromString(stringUUID);
|
|
||||||
final SkullBuilder skull = new SkullBuilder(uuid);
|
|
||||||
skull.setDisplayName("§6Skin Entry");
|
|
||||||
skull.addLoreLines("§7Click to invalidate skin");
|
|
||||||
return skull;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
package net.artelnatif.nicko.gui.items.common;
|
|
||||||
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import xyz.xenondevs.invui.gui.Gui;
|
|
||||||
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
|
||||||
import xyz.xenondevs.invui.item.impl.SuppliedItem;
|
|
||||||
import xyz.xenondevs.invui.window.Window;
|
|
||||||
|
|
||||||
public class GoBack extends SuppliedItem {
|
|
||||||
public GoBack(Gui gui) {
|
|
||||||
super(() -> {
|
|
||||||
final ItemBuilder builder = new ItemBuilder(Material.ARROW);
|
|
||||||
builder.setDisplayName("Go back");
|
|
||||||
builder.addLoreLines("§7Return to the previous window.");
|
|
||||||
return builder;
|
|
||||||
}, click -> {
|
|
||||||
click.getEvent().getView().close();
|
|
||||||
// TODO: 4/1/23 Get title of parent GUI
|
|
||||||
Window.single().setGui(gui).setTitle("Nicko").open(click.getPlayer());
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
package net.artelnatif.nicko.gui.items.common;
|
|
||||||
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
|
||||||
import xyz.xenondevs.invui.item.impl.SuppliedItem;
|
|
||||||
|
|
||||||
public class OptionUnavailable extends SuppliedItem {
|
|
||||||
public OptionUnavailable() {
|
|
||||||
super(() -> {
|
|
||||||
final ItemBuilder builder = new ItemBuilder(Material.RED_TERRACOTTA);
|
|
||||||
builder.setDisplayName("§cFeature unavailable :(");
|
|
||||||
builder.addLoreLines("§7This button is disabled.");
|
|
||||||
return builder;
|
|
||||||
}, click -> true);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package net.artelnatif.nicko.gui.items.common;
|
|
||||||
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import xyz.xenondevs.invui.gui.ScrollGui;
|
|
||||||
import xyz.xenondevs.invui.item.ItemProvider;
|
|
||||||
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
|
||||||
import xyz.xenondevs.invui.item.impl.controlitem.ScrollItem;
|
|
||||||
|
|
||||||
public class ScrollDown extends ScrollItem {
|
|
||||||
|
|
||||||
public ScrollDown() {
|
|
||||||
super(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ItemProvider getItemProvider(ScrollGui gui) {
|
|
||||||
ItemBuilder builder = new ItemBuilder(Material.GREEN_STAINED_GLASS_PANE);
|
|
||||||
builder.setDisplayName("§7Scroll down");
|
|
||||||
if (!gui.canScroll(1))
|
|
||||||
builder.addLoreLines("§cYou can't scroll further down");
|
|
||||||
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
package net.artelnatif.nicko.gui.items.common;
|
|
||||||
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import xyz.xenondevs.invui.gui.ScrollGui;
|
|
||||||
import xyz.xenondevs.invui.item.ItemProvider;
|
|
||||||
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
|
||||||
import xyz.xenondevs.invui.item.impl.controlitem.ScrollItem;
|
|
||||||
|
|
||||||
public class ScrollUp extends ScrollItem {
|
|
||||||
|
|
||||||
public ScrollUp() {
|
|
||||||
super(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ItemProvider getItemProvider(ScrollGui gui) {
|
|
||||||
ItemBuilder builder = new ItemBuilder(Material.RED_STAINED_GLASS_PANE);
|
|
||||||
builder.setDisplayName("§7Scroll up");
|
|
||||||
if (!gui.canScroll(-1))
|
|
||||||
builder.addLoreLines("§cYou've reached the top");
|
|
||||||
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
package net.artelnatif.nicko.gui.items.main;
|
|
||||||
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.event.inventory.ClickType;
|
|
||||||
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
|
||||||
import xyz.xenondevs.invui.item.impl.SimpleItem;
|
|
||||||
|
|
||||||
public class ExitGUI extends SimpleItem {
|
|
||||||
public ExitGUI() {
|
|
||||||
super(new ItemBuilder(Material.OAK_DOOR).setDisplayName("§fExit"), click -> {
|
|
||||||
final ClickType clickType = click.getClickType();
|
|
||||||
if (clickType.isLeftClick() || clickType.isRightClick()) {
|
|
||||||
click.getEvent().getView().close();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
package net.artelnatif.nicko.gui.items.main;
|
|
||||||
|
|
||||||
import net.artelnatif.nicko.appearance.AppearanceManager;
|
|
||||||
import net.artelnatif.nicko.i18n.I18N;
|
|
||||||
import net.artelnatif.nicko.i18n.I18NDict;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.inventory.ClickType;
|
|
||||||
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
|
||||||
import xyz.xenondevs.invui.item.impl.SuppliedItem;
|
|
||||||
|
|
||||||
public class ResetAppearance extends SuppliedItem {
|
|
||||||
public ResetAppearance() {
|
|
||||||
super(() -> {
|
|
||||||
final ItemBuilder builder = new ItemBuilder(Material.TNT);
|
|
||||||
builder.setDisplayName("§fReset");
|
|
||||||
builder.addLoreLines("§7Get rid of your disguise.");
|
|
||||||
return builder;
|
|
||||||
}, (event) -> {
|
|
||||||
final Player player = event.getPlayer();
|
|
||||||
final ClickType clickType = event.getClickType();
|
|
||||||
if (clickType.isLeftClick() || clickType.isRightClick()) {
|
|
||||||
final AppearanceManager appearanceManager = AppearanceManager.get(player);
|
|
||||||
|
|
||||||
if (!appearanceManager.hasData()) {
|
|
||||||
player.sendMessage(I18N.translate(player, I18NDict.Event.Undisguise.NONE));
|
|
||||||
event.getEvent().getView().close();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!appearanceManager.reset().isError()) {
|
|
||||||
player.sendMessage(I18N.translate(player, I18NDict.Event.Undisguise.SUCCESS));
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
player.sendMessage(I18N.translate(player, I18NDict.Event.Undisguise.FAIL));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
package net.artelnatif.nicko.gui.items.settings;
|
|
||||||
|
|
||||||
import net.artelnatif.nicko.NickoBukkit;
|
|
||||||
import net.artelnatif.nicko.disguise.NickoProfile;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.Sound;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import xyz.xenondevs.invui.item.ItemProvider;
|
|
||||||
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
|
||||||
import xyz.xenondevs.invui.item.impl.AbstractItem;
|
|
||||||
import xyz.xenondevs.invui.item.impl.CycleItem;
|
|
||||||
import xyz.xenondevs.invui.item.impl.SimpleItem;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public class BungeeCordCycling {
|
|
||||||
private final ItemProvider[] providers = new ItemProvider[]{
|
|
||||||
getItemProviderForValue(true),
|
|
||||||
getItemProviderForValue(false)
|
|
||||||
};
|
|
||||||
|
|
||||||
public AbstractItem get(Player player) {
|
|
||||||
final Optional<NickoProfile> profile = NickoBukkit.getInstance().getDataStore().getData(player.getUniqueId());
|
|
||||||
if (profile.isPresent()) {
|
|
||||||
final NickoProfile nickoProfile = profile.get();
|
|
||||||
int startingState = nickoProfile.isBungeecordTransfer() ? 0 : 1;
|
|
||||||
return CycleItem.withStateChangeHandler((observer, integer) -> {
|
|
||||||
nickoProfile.setBungeecordTransfer(integer != 1);
|
|
||||||
observer.playSound(player, Sound.UI_BUTTON_CLICK, 1f, 0.707107f); // 0.707107 ~= C
|
|
||||||
}, startingState, providers);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new SimpleItem(ItemProvider.EMPTY);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ItemProvider getItemProviderForValue(boolean enabled) {
|
|
||||||
final ItemBuilder builder = new ItemBuilder(Material.COMPASS);
|
|
||||||
builder.setDisplayName("§6BungeeCord transfer:");
|
|
||||||
if (enabled) {
|
|
||||||
builder.addLoreLines("§7> §cDisabled");
|
|
||||||
builder.addLoreLines("§6§l> §a§lEnabled");
|
|
||||||
} else {
|
|
||||||
builder.addLoreLines("§6§l> §c§lDisabled");
|
|
||||||
builder.addLoreLines("§7> §aEnabled");
|
|
||||||
}
|
|
||||||
builder.addLoreLines("§7§oCycle through the values by", "§7§oleft and right clicking.");
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
package net.artelnatif.nicko.gui.items.settings;
|
|
||||||
|
|
||||||
import net.artelnatif.nicko.NickoBukkit;
|
|
||||||
import net.artelnatif.nicko.disguise.NickoProfile;
|
|
||||||
import net.artelnatif.nicko.i18n.Locale;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.Sound;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import xyz.xenondevs.invui.item.ItemProvider;
|
|
||||||
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
|
||||||
import xyz.xenondevs.invui.item.impl.AbstractItem;
|
|
||||||
import xyz.xenondevs.invui.item.impl.CycleItem;
|
|
||||||
import xyz.xenondevs.invui.item.impl.SimpleItem;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public class LanguageCycling {
|
|
||||||
private final ItemProvider[] providers = getItems();
|
|
||||||
|
|
||||||
public AbstractItem get(Player player) {
|
|
||||||
final Optional<NickoProfile> profile = NickoBukkit.getInstance().getDataStore().getData(player.getUniqueId());
|
|
||||||
if (profile.isPresent()) {
|
|
||||||
final NickoProfile nickoProfile = profile.get();
|
|
||||||
int localeOrdinal = nickoProfile.getLocale().ordinal();
|
|
||||||
return CycleItem.withStateChangeHandler((observer, integer) -> {
|
|
||||||
nickoProfile.setLocale(Locale.values()[integer]);
|
|
||||||
observer.playSound(player, Sound.UI_BUTTON_CLICK, 1f, 0.707107f); // 0.707107 ~= C
|
|
||||||
}, localeOrdinal, providers);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new SimpleItem(ItemProvider.EMPTY);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ItemProvider generateItem(Locale locale, List<Locale> locales) {
|
|
||||||
final ItemBuilder builder = new ItemBuilder(Material.OAK_SIGN);
|
|
||||||
builder.setDisplayName("§6Select your language:");
|
|
||||||
for (Locale value : locales) {
|
|
||||||
if (locale != value) {
|
|
||||||
builder.addLoreLines("§7> " + value.getName());
|
|
||||||
} else {
|
|
||||||
builder.addLoreLines("§6§l> §f" + value.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
builder.addLoreLines("§7§oCycle through the values by", "§7§oleft and right clicking.");
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ItemProvider[] getItems() {
|
|
||||||
final NickoBukkit instance = NickoBukkit.getInstance();
|
|
||||||
final ArrayList<ItemProvider> items = new ArrayList<>();
|
|
||||||
|
|
||||||
final ArrayList<Locale> localesToGenerate = new ArrayList<>();
|
|
||||||
Collections.addAll(localesToGenerate, Locale.values());
|
|
||||||
if (!instance.getNickoConfig().isCustomLocale()) {
|
|
||||||
localesToGenerate.remove(Locale.CUSTOM);
|
|
||||||
}
|
|
||||||
localesToGenerate.forEach(locale -> items.add(generateItem(locale, localesToGenerate)));
|
|
||||||
return items.toArray(new ItemProvider[]{});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
package net.artelnatif.nicko.gui.items.skin;
|
|
||||||
|
|
||||||
import net.artelnatif.nicko.anvil.AnvilManager;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.event.inventory.ClickType;
|
|
||||||
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
|
||||||
import xyz.xenondevs.invui.item.impl.SuppliedItem;
|
|
||||||
|
|
||||||
public class ChangeName extends SuppliedItem {
|
|
||||||
public ChangeName() {
|
|
||||||
super(() -> {
|
|
||||||
final ItemBuilder builder = new ItemBuilder(Material.NAME_TAG);
|
|
||||||
builder.setDisplayName("§fChange §6name");
|
|
||||||
builder.addLoreLines("§7Only change your name.");
|
|
||||||
return builder;
|
|
||||||
}, click -> {
|
|
||||||
final ClickType clickType = click.getClickType();
|
|
||||||
if (clickType.isLeftClick() || clickType.isRightClick()) {
|
|
||||||
click.getEvent().getView().close();
|
|
||||||
final AnvilManager manager = new AnvilManager(click.getPlayer());
|
|
||||||
manager.openNameAnvil();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
package net.artelnatif.nicko.gui.items.skin;
|
|
||||||
|
|
||||||
import net.artelnatif.nicko.anvil.AnvilManager;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.event.inventory.ClickType;
|
|
||||||
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
|
||||||
import xyz.xenondevs.invui.item.impl.SuppliedItem;
|
|
||||||
|
|
||||||
public class ChangeNameAndSkin extends SuppliedItem {
|
|
||||||
public ChangeNameAndSkin() {
|
|
||||||
super(() -> {
|
|
||||||
final ItemBuilder builder = new ItemBuilder(Material.END_PORTAL_FRAME);
|
|
||||||
builder.setDisplayName("§6Skin §fand §6name §fchange");
|
|
||||||
builder.addLoreLines("§7Change both your skin and name.");
|
|
||||||
return builder;
|
|
||||||
}, click -> {
|
|
||||||
final ClickType clickType = click.getClickType();
|
|
||||||
if (clickType.isLeftClick() || clickType.isRightClick()) {
|
|
||||||
click.getEvent().getView().close();
|
|
||||||
final AnvilManager manager = new AnvilManager(click.getPlayer());
|
|
||||||
manager.openNameThenSkinAnvil();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
package net.artelnatif.nicko.gui.items.skin;
|
|
||||||
|
|
||||||
import net.artelnatif.nicko.anvil.AnvilManager;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.inventory.ClickType;
|
|
||||||
import xyz.xenondevs.invui.item.builder.SkullBuilder;
|
|
||||||
import xyz.xenondevs.invui.item.impl.SuppliedItem;
|
|
||||||
|
|
||||||
public class ChangeSkin extends SuppliedItem {
|
|
||||||
public ChangeSkin(Player player) {
|
|
||||||
super(() -> {
|
|
||||||
final SkullBuilder builder = new SkullBuilder(player.getName());
|
|
||||||
builder.setDisplayName("§fChange §6skin");
|
|
||||||
builder.addLoreLines("§7Only change your skin.");
|
|
||||||
return builder;
|
|
||||||
}, click -> {
|
|
||||||
final ClickType clickType = click.getClickType();
|
|
||||||
if (clickType.isLeftClick() || clickType.isRightClick()) {
|
|
||||||
click.getEvent().getView().close();
|
|
||||||
final AnvilManager manager = new AnvilManager(click.getPlayer());
|
|
||||||
manager.openSkinAnvil();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
package net.artelnatif.nicko.i18n;
|
|
||||||
|
|
||||||
import com.github.jsixface.YamlConfig;
|
|
||||||
import net.artelnatif.nicko.NickoBukkit;
|
|
||||||
import net.artelnatif.nicko.disguise.NickoProfile;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.text.MessageFormat;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public class I18N {
|
|
||||||
private final static MessageFormat formatter = new MessageFormat("");
|
|
||||||
|
|
||||||
private static Locale getLocale(Player player) {
|
|
||||||
final NickoBukkit instance = NickoBukkit.getInstance();
|
|
||||||
try {
|
|
||||||
final Optional<NickoProfile> profile = instance.getDataStore().getData(player.getUniqueId());
|
|
||||||
return !profile.isPresent() ? Locale.FALLBACK_LOCALE : profile.get().getLocale();
|
|
||||||
} catch (IllegalArgumentException exception) {
|
|
||||||
instance.getLogger().severe("Invalid locale provided by " + player.getName() + ", defaulting to " + Locale.FALLBACK_LOCALE.getCode() + ".");
|
|
||||||
return Locale.FALLBACK_LOCALE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String translate(Player player, I18NDict key, Object... arguments) {
|
|
||||||
final NickoBukkit instance = NickoBukkit.getInstance();
|
|
||||||
final String translation = findTranslation(player, key);
|
|
||||||
|
|
||||||
try {
|
|
||||||
formatter.applyPattern(translation);
|
|
||||||
return instance.getNickoConfig().getPrefix() + formatter.format(arguments);
|
|
||||||
} catch (Exception e) {
|
|
||||||
return instance.getNickoConfig().getPrefix() + key.key();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String translateWithoutPrefix(Player player, I18NDict key, Object... arguments) {
|
|
||||||
final String translation = findTranslation(player, key);
|
|
||||||
try {
|
|
||||||
formatter.applyPattern(translation);
|
|
||||||
return formatter.format(arguments);
|
|
||||||
} catch (Exception e) {
|
|
||||||
return key.key();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String findTranslation(Player player, I18NDict key) {
|
|
||||||
final NickoBukkit instance = NickoBukkit.getInstance();
|
|
||||||
final Locale locale = getLocale(player);
|
|
||||||
String translation;
|
|
||||||
if (locale == Locale.CUSTOM) {
|
|
||||||
translation = instance.getLocaleFileManager().get(key.key());
|
|
||||||
} else {
|
|
||||||
final InputStream resource = instance.getResource(locale.getCode() + ".yml");
|
|
||||||
final YamlConfig yamlConfig = YamlConfig.load(resource);
|
|
||||||
translation = yamlConfig.getString(key.key());
|
|
||||||
}
|
|
||||||
|
|
||||||
return translation;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
package net.artelnatif.nicko.i18n;
|
|
||||||
|
|
||||||
public class I18NDict {
|
|
||||||
private final String key;
|
|
||||||
|
|
||||||
public I18NDict(String key) { this.key = key; }
|
|
||||||
|
|
||||||
public static class Event {
|
|
||||||
public static class Admin {
|
|
||||||
public static final I18NDict CACHE_CLEAN = new I18NDict("event.admin.cache_clear");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Disguise {
|
|
||||||
public static final I18NDict SUCCESS = new I18NDict("event.disguise.success");
|
|
||||||
public static final I18NDict FAIL = new I18NDict("event.disguise.fail");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Undisguise {
|
|
||||||
public static final I18NDict SUCCESS = new I18NDict("event.undisguise.success");
|
|
||||||
public static final I18NDict FAIL = new I18NDict("event.undisguise.fail");
|
|
||||||
public static final I18NDict NONE = new I18NDict("event.undisguise.none");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class PreviousSkin {
|
|
||||||
public static final I18NDict SUCCESS = new I18NDict("event.previous_skin_applied.success");
|
|
||||||
public static final I18NDict FAIL = new I18NDict("event.previous_skin_applied.fail");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Error {
|
|
||||||
public static final I18NDict PLAYER_OFFLINE = new I18NDict("error.player_offline");
|
|
||||||
public static final I18NDict SKIN_FAIL_MOJANG = new I18NDict("error.couldnt_get_skin_from_mojang");
|
|
||||||
public static final I18NDict SKIN_FAIL_CACHE = new I18NDict("error.couldnt_get_skin_from_cache");
|
|
||||||
public static final I18NDict NAME_FAIL_MOJANG = new I18NDict("error.couldnt_get_name_from_mojang");
|
|
||||||
public static final I18NDict INVALID_USERNAME = new I18NDict("error.invalid_username");
|
|
||||||
public static final I18NDict UNEXPECTED_ERROR = new I18NDict("error.generic");
|
|
||||||
public static final I18NDict SQL_ERROR = new I18NDict("error.sql");
|
|
||||||
public static final I18NDict JSON_ERROR = new I18NDict("error.json");
|
|
||||||
}
|
|
||||||
|
|
||||||
public String key() {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
package net.artelnatif.nicko.i18n;
|
|
||||||
|
|
||||||
import com.github.jsixface.YamlConfig;
|
|
||||||
import net.artelnatif.nicko.NickoBukkit;
|
|
||||||
import xyz.xenondevs.invui.util.IOUtils;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
|
|
||||||
public class LocaleFileManager {
|
|
||||||
private final File folder = new File(NickoBukkit.getInstance().getDataFolder() + "/lang/");
|
|
||||||
private final File file = new File(folder, "lang.yml");
|
|
||||||
|
|
||||||
public String get(String key) {
|
|
||||||
if (!file.exists()) return key;
|
|
||||||
try (BufferedInputStream inputStream = new BufferedInputStream(Files.newInputStream(file.toPath()))) {
|
|
||||||
final YamlConfig yamlConfig = YamlConfig.load(inputStream);
|
|
||||||
return yamlConfig.getString(key);
|
|
||||||
} catch (IOException e) {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean dumpFromLocale(Locale locale) {
|
|
||||||
if (locale == Locale.CUSTOM) return true;
|
|
||||||
if (file.exists()) return true;
|
|
||||||
final InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(locale.getCode() + ".yml");
|
|
||||||
try {
|
|
||||||
if (folder.mkdirs()) {
|
|
||||||
if (file.createNewFile()) {
|
|
||||||
try (FileOutputStream outputStream = new FileOutputStream(file)) {
|
|
||||||
IOUtils.copy(inputStream, outputStream, 8192);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
package net.artelnatif.nicko.impl;
|
|
||||||
|
|
||||||
import net.artelnatif.nicko.NickoBukkit;
|
|
||||||
import net.artelnatif.nicko.disguise.NickoProfile;
|
|
||||||
import net.artelnatif.nicko.disguise.ActionResult;
|
|
||||||
import net.artelnatif.nicko.i18n.I18NDict;
|
|
||||||
import net.artelnatif.nicko.mojang.MojangAPI;
|
|
||||||
import net.artelnatif.nicko.mojang.MojangSkin;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
|
|
||||||
public interface Internals {
|
|
||||||
void updateSelf(Player player);
|
|
||||||
|
|
||||||
void updateOthers(Player player);
|
|
||||||
|
|
||||||
ActionResult<Void> updateProfile(Player player, NickoProfile profile, boolean skinChange, boolean reset);
|
|
||||||
|
|
||||||
default ActionResult<MojangSkin> fetchSkinTextures(NickoProfile profile, boolean reset) {
|
|
||||||
Optional<MojangSkin> skin;
|
|
||||||
try {
|
|
||||||
final MojangAPI mojang = NickoBukkit.getInstance().getMojangAPI();
|
|
||||||
final Optional<String> uuid = mojang.getUUID(profile.getSkin());
|
|
||||||
if (uuid.isPresent()) {
|
|
||||||
skin = (reset ? mojang.getSkinWithoutCaching(uuid.get()) : mojang.getSkin(uuid.get()));
|
|
||||||
return skin.map(ActionResult::new).orElseGet(() -> new ActionResult<>(I18NDict.Error.SKIN_FAIL_MOJANG));
|
|
||||||
}
|
|
||||||
return new ActionResult<>(I18NDict.Error.NAME_FAIL_MOJANG);
|
|
||||||
} catch (ExecutionException e) {
|
|
||||||
return new ActionResult<>(I18NDict.Error.SKIN_FAIL_CACHE);
|
|
||||||
} catch (IOException e) {
|
|
||||||
return new ActionResult<>(I18NDict.Error.NAME_FAIL_MOJANG);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
package net.artelnatif.nicko.impl;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
public class InternalsProvider {
|
|
||||||
private static final Logger logger = Logger.getLogger("Internals");
|
|
||||||
private static Internals internals;
|
|
||||||
|
|
||||||
static {
|
|
||||||
try {
|
|
||||||
final String packageName = Internals.class.getPackage().getName();
|
|
||||||
final String bukkitVersion = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
|
|
||||||
final String fullClassName = packageName + "." + bukkitVersion;
|
|
||||||
final Class<?> clazz = Class.forName(fullClassName);
|
|
||||||
internals = (Internals) clazz.getConstructors()[0].newInstance();
|
|
||||||
logger.info("Loaded support for " + bukkitVersion);
|
|
||||||
} catch (InvocationTargetException | ClassNotFoundException | InstantiationException | IllegalAccessException |
|
|
||||||
ClassCastException exception) {
|
|
||||||
internals = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Internals getInternals() {
|
|
||||||
return internals;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,116 +0,0 @@
|
||||||
package net.artelnatif.nicko.mojang;
|
|
||||||
|
|
||||||
import com.google.common.cache.CacheBuilder;
|
|
||||||
import com.google.common.cache.CacheLoader;
|
|
||||||
import com.google.common.cache.LoadingCache;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonParseException;
|
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.net.ssl.HttpsURLConnection;
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
public class MojangAPI {
|
|
||||||
public static final String URL_NAME = "https://api.mojang.com/users/profiles/minecraft/{name}";
|
|
||||||
public static final String URL_SKIN = "https://sessionserver.mojang.com/session/minecraft/profile/{uuid}?unsigned=false";
|
|
||||||
|
|
||||||
private final Logger logger = Logger.getLogger("MojangAPI");
|
|
||||||
|
|
||||||
private final CacheLoader<String, Optional<MojangSkin>> loader = new CacheLoader<String, Optional<MojangSkin>>() {
|
|
||||||
@Nonnull
|
|
||||||
public Optional<MojangSkin> load(@Nonnull String uuid) throws Exception {
|
|
||||||
return getSkinFromMojang(uuid);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private final LoadingCache<String, Optional<MojangSkin>> cache = CacheBuilder
|
|
||||||
.newBuilder()
|
|
||||||
.recordStats()
|
|
||||||
.expireAfterWrite(24, TimeUnit.HOURS)
|
|
||||||
.build(loader);
|
|
||||||
|
|
||||||
public Optional<MojangSkin> getSkin(String uuid) throws IOException, ExecutionException {
|
|
||||||
return cache.get(uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Optional<MojangSkin> getSkinWithoutCaching(String uuid) throws IOException {
|
|
||||||
return getSkinFromMojang(uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Optional<String> getUUID(String name) throws IOException {
|
|
||||||
final String parametrizedUrl = URL_NAME.replace("{name}", name);
|
|
||||||
final JsonObject object = getRequestToUrl(parametrizedUrl);
|
|
||||||
if (hasNoError(object)) {
|
|
||||||
return Optional.of(object.get("id").getAsString());
|
|
||||||
}
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Optional<MojangSkin> getSkinFromMojang(String uuid) throws IOException {
|
|
||||||
final String parametrizedUrl = URL_SKIN.replace("{uuid}", uuid);
|
|
||||||
final JsonObject object = getRequestToUrl(parametrizedUrl);
|
|
||||||
if (hasNoError(object)) {
|
|
||||||
final MojangSkin skin = MojangSkin.buildFromJson(object);
|
|
||||||
return Optional.of(skin);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
private JsonObject getRequestToUrl(String parametrizedUrl) throws IOException {
|
|
||||||
final URL url = new URL(parametrizedUrl);
|
|
||||||
final HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
|
|
||||||
con.setDoInput(true);
|
|
||||||
con.setRequestMethod("GET");
|
|
||||||
|
|
||||||
switch (con.getResponseCode()) {
|
|
||||||
case 400:
|
|
||||||
logger.warning("Failed to parse request: Invalid Name");
|
|
||||||
return getErrorObject();
|
|
||||||
case 429:
|
|
||||||
logger.warning("Failed to parse request: The connection is throttled.");
|
|
||||||
return getErrorObject();
|
|
||||||
case 200:
|
|
||||||
final BufferedReader input = new BufferedReader(new InputStreamReader(con.getInputStream()));
|
|
||||||
final StringBuilder builder = new StringBuilder();
|
|
||||||
String line;
|
|
||||||
while ((line = input.readLine()) != null) {
|
|
||||||
builder.append(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
final JsonElement jsonElt = JsonParser.parseString(builder.toString());
|
|
||||||
return jsonElt.getAsJsonObject();
|
|
||||||
} catch (JsonParseException | IllegalStateException exception) {
|
|
||||||
logger.warning("Failed to parse request (" + parametrizedUrl + ")!");
|
|
||||||
return getErrorObject();
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
logger.warning("Unhandled response code from Mojang: " + con.getResponseCode());
|
|
||||||
return getErrorObject();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private JsonObject getErrorObject() {
|
|
||||||
final JsonObject errorObject = new JsonObject();
|
|
||||||
errorObject.addProperty("error", "An error occurred.");
|
|
||||||
return errorObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasNoError(JsonObject object) {
|
|
||||||
return object.get("error") == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LoadingCache<String, Optional<MojangSkin>> getCache() {
|
|
||||||
return cache;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
package net.artelnatif.nicko.placeholder;
|
|
||||||
|
|
||||||
import net.artelnatif.nicko.NickoBukkit;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
|
|
||||||
public class PlaceHolderHook {
|
|
||||||
private final NickoBukkit instance;
|
|
||||||
|
|
||||||
public PlaceHolderHook(NickoBukkit instance) {
|
|
||||||
this.instance = instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void hook() {
|
|
||||||
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
|
|
||||||
instance.getLogger().info("Enabling PlaceHolderAPI support...");
|
|
||||||
new NickoExpansion(instance).register();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,92 +0,0 @@
|
||||||
package net.artelnatif.nicko.storage;
|
|
||||||
|
|
||||||
import net.artelnatif.nicko.config.Configuration;
|
|
||||||
import net.artelnatif.nicko.disguise.ActionResult;
|
|
||||||
import net.artelnatif.nicko.disguise.NickoProfile;
|
|
||||||
import net.artelnatif.nicko.i18n.I18NDict;
|
|
||||||
import net.artelnatif.nicko.mojang.MojangAPI;
|
|
||||||
import net.artelnatif.nicko.mojang.MojangUtils;
|
|
||||||
import net.artelnatif.nicko.storage.cache.Cache;
|
|
||||||
import net.artelnatif.nicko.storage.cache.redis.RedisCache;
|
|
||||||
import net.artelnatif.nicko.storage.json.JSONStorage;
|
|
||||||
import net.artelnatif.nicko.storage.sql.SQLStorage;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class PlayerDataStore {
|
|
||||||
private final Storage storage;
|
|
||||||
private final Cache cache;
|
|
||||||
private final MojangAPI mojangAPI;
|
|
||||||
private final HashMap<UUID, NickoProfile> profiles = new HashMap<>();
|
|
||||||
|
|
||||||
public PlayerDataStore(MojangAPI mojangAPI, Configuration configuration) {
|
|
||||||
this.mojangAPI = mojangAPI;
|
|
||||||
this.storage = configuration.isLocal() ? new JSONStorage() : new SQLStorage(configuration);
|
|
||||||
this.cache = new RedisCache(); // The only option for now!
|
|
||||||
}
|
|
||||||
|
|
||||||
public void performProfileUpdate(UUID uuid, NickoProfile profile) {
|
|
||||||
if (!profiles.containsKey(uuid)) {
|
|
||||||
profiles.put(uuid, profile);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
profiles.replace(uuid, profile);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Optional<NickoProfile> getData(UUID uuid) {
|
|
||||||
if (storage.isError()) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (profiles.containsKey(uuid)) {
|
|
||||||
return Optional.of(profiles.get(uuid));
|
|
||||||
} else if (storage.isStored(uuid)) {
|
|
||||||
final Optional<NickoProfile> retrievedProfile = storage.retrieve(uuid);
|
|
||||||
retrievedProfile.ifPresent(profile -> profiles.put(uuid, profile));
|
|
||||||
return retrievedProfile;
|
|
||||||
} else {
|
|
||||||
final NickoProfile newProfile = NickoProfile.EMPTY_PROFILE.clone();
|
|
||||||
profiles.put(uuid, newProfile);
|
|
||||||
return Optional.of(newProfile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Optional<NickoProfile> getOfflineData(String name) {
|
|
||||||
if (storage.isError()) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
final Optional<String> uuidTrimmed = mojangAPI.getUUID(name);
|
|
||||||
if (uuidTrimmed.isPresent()) {
|
|
||||||
final UUID uuid = MojangUtils.fromTrimmed(uuidTrimmed.get());
|
|
||||||
return getData(uuid);
|
|
||||||
}
|
|
||||||
return Optional.empty();
|
|
||||||
} catch (IOException e) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionResult<Void> saveData(Player player) {
|
|
||||||
if (storage.isError()) { return new ActionResult<>(I18NDict.Error.UNEXPECTED_ERROR); }
|
|
||||||
if (!profiles.containsKey(player.getUniqueId())) { return new ActionResult<>(I18NDict.Error.UNEXPECTED_ERROR); }
|
|
||||||
|
|
||||||
final ActionResult<Void> store = storage.store(player.getUniqueId(), profiles.get(player.getUniqueId()));
|
|
||||||
profiles.remove(player.getUniqueId());
|
|
||||||
return store;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Storage getStorage() {
|
|
||||||
return storage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Cache getCache() {
|
|
||||||
return cache;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
package net.artelnatif.nicko.storage.cache.redis;
|
|
||||||
|
|
||||||
import net.artelnatif.nicko.disguise.ActionResult;
|
|
||||||
import net.artelnatif.nicko.disguise.NickoProfile;
|
|
||||||
import net.artelnatif.nicko.storage.cache.Cache;
|
|
||||||
import net.artelnatif.nicko.storage.cache.CacheProvider;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class RedisCache extends Cache {
|
|
||||||
@Override
|
|
||||||
public CacheProvider getProvider() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ActionResult<Void> cache(UUID uuid, NickoProfile profile) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCached(UUID uuid) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<NickoProfile> retrieve(UUID uuid) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
package net.artelnatif.nicko.storage.cache.redis;
|
|
||||||
|
|
||||||
import net.artelnatif.nicko.storage.cache.CacheProvider;
|
|
||||||
import redis.clients.jedis.Jedis;
|
|
||||||
import redis.clients.jedis.JedisPool;
|
|
||||||
|
|
||||||
public class RedisCacheProvider implements CacheProvider {
|
|
||||||
private JedisPool pool;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean init() {
|
|
||||||
// TODO: 3/12/23 Get port from configuration
|
|
||||||
pool = new JedisPool("localhost", 6379);
|
|
||||||
return !pool.isClosed() && pool.getResource() != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean close() {
|
|
||||||
pool.close();
|
|
||||||
return pool.isClosed();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Jedis getJedis() {
|
|
||||||
return pool.getResource();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
error:
|
|
||||||
couldnt_get_name_from_mojang: "Failed to get username from Mojang"
|
|
||||||
couldnt_get_skin_from_cache: "Failed to get skin from cache"
|
|
||||||
couldnt_get_skin_from_mojang: "Failed to get skin from Mojang"
|
|
||||||
generic: "Unknown error"
|
|
||||||
invalid_username: "§cThe specified username is not a valid Minecraft username."
|
|
||||||
player_offline: "§c{0} §fis offline, please try again."
|
|
||||||
sql: "SQL Error"
|
|
||||||
json: "JSON Error"
|
|
||||||
event:
|
|
||||||
admin:
|
|
||||||
cache_clear: "§aSkin cache cleaned."
|
|
||||||
disguise:
|
|
||||||
fail: "§cUnable to apply your disguise. §7§o({0})"
|
|
||||||
success: "§aDisguise applied!"
|
|
||||||
previous_skin_applied:
|
|
||||||
fail: "§cFailed to apply your previous disguise back. §7§o({0})"
|
|
||||||
success: "§aYour previous active disguise has been applied back."
|
|
||||||
undisguise:
|
|
||||||
fail: "§cUnable to remove your disguise. It will be set back to default on your next login. Sorry!"
|
|
||||||
none: "§cYou do not have an active disguise."
|
|
||||||
success: "§aDisguise removed."
|
|
|
@ -1,22 +0,0 @@
|
||||||
error:
|
|
||||||
couldnt_get_name_from_mojang: "Impossible de récupérer le nom d''utilisateur depuis Mojang"
|
|
||||||
couldnt_get_skin_from_cache: "Impossible de récupérer le skin depuis le cache"
|
|
||||||
couldnt_get_skin_from_mojang: "Impossible de récupérer le skin depuis Mojang"
|
|
||||||
generic: "Erreur inconnue"
|
|
||||||
invalid_username: "§cLe pseudo spécifié n''est pas un pseudo Minecraft valide."
|
|
||||||
player_offline: "§c{0} §fest hors-ligne, veuillez réessayer."
|
|
||||||
sql: "Erreur SQL"
|
|
||||||
json: "Erreur JSON"
|
|
||||||
event:
|
|
||||||
admin:
|
|
||||||
cache_clear: "§aCache des skins nettoyé."
|
|
||||||
disguise:
|
|
||||||
fail: "§cImpossible d''appliquer votre déguisement. §7§o({0})"
|
|
||||||
success: "§aDéguisement appliqué !"
|
|
||||||
previous_skin_applied:
|
|
||||||
fail: "§cImpossible d''appliquer votre déguisement précédent. §7§o({0})"
|
|
||||||
success: "§aVotre précédent déguisement a été réappliqué."
|
|
||||||
undisguise:
|
|
||||||
fail: "§cImpossible de retier votre déguisement. Il sera remis par défaut à votre prochaine reconnexion. Désolé !"
|
|
||||||
none: "§cVous n''avez pas de déguisement."
|
|
||||||
success: "§aDéguisement retiré."
|
|
|
@ -1,17 +0,0 @@
|
||||||
name: Nicko
|
|
||||||
main: net.artelnatif.nicko.NickoBukkit
|
|
||||||
version: 1.0-SNAPSHOT
|
|
||||||
author: Aro
|
|
||||||
api-version: 1.13
|
|
||||||
softdepend: [ PlaceholderAPI ]
|
|
||||||
commands:
|
|
||||||
nicko:
|
|
||||||
description: "Opens Nicko's GUI."
|
|
||||||
permission: nicko.admin
|
|
||||||
permissions:
|
|
||||||
nicko.*:
|
|
||||||
default: op
|
|
||||||
children:
|
|
||||||
- nicko.use
|
|
||||||
nicko.use:
|
|
||||||
default: op
|
|
|
@ -1,36 +0,0 @@
|
||||||
package net.artelnatif.nicko.test;
|
|
||||||
|
|
||||||
import be.seeseemelk.mockbukkit.MockBukkit;
|
|
||||||
import net.artelnatif.nicko.NickoBukkit;
|
|
||||||
import net.artelnatif.nicko.config.Configuration;
|
|
||||||
import net.artelnatif.nicko.config.DataSourceConfiguration;
|
|
||||||
import org.junit.jupiter.api.*;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
|
||||||
|
|
||||||
public class NickoPluginTest {
|
|
||||||
private static NickoBukkit plugin;
|
|
||||||
|
|
||||||
@BeforeAll
|
|
||||||
public static void setup() {
|
|
||||||
final Configuration config = new Configuration(
|
|
||||||
DataSourceConfiguration.SQL_EMPTY,
|
|
||||||
DataSourceConfiguration.REDIS_EMPTY,
|
|
||||||
"",
|
|
||||||
true,
|
|
||||||
false);
|
|
||||||
MockBukkit.mock();
|
|
||||||
plugin = MockBukkit.load(NickoBukkit.class, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Plugin Initialization")
|
|
||||||
public void initializePlugin() {
|
|
||||||
assertNotNull(plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterAll
|
|
||||||
public static void shutdown() {
|
|
||||||
MockBukkit.unmock();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
package net.artelnatif.nicko.test.config;
|
|
||||||
|
|
||||||
import be.seeseemelk.mockbukkit.MockBukkit;
|
|
||||||
import net.artelnatif.nicko.NickoBukkit;
|
|
||||||
import net.artelnatif.nicko.config.Configuration;
|
|
||||||
import org.junit.jupiter.api.AfterAll;
|
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
|
||||||
import org.junit.jupiter.api.DisplayName;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
public class ConfigurationTest {
|
|
||||||
private static NickoBukkit plugin;
|
|
||||||
|
|
||||||
@BeforeAll
|
|
||||||
public static void setup() {
|
|
||||||
MockBukkit.mock();
|
|
||||||
plugin = MockBukkit.load(NickoBukkit.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Read configuration")
|
|
||||||
public void readConfiguration() {
|
|
||||||
final Configuration configuration = plugin.getNickoConfig();
|
|
||||||
assertTrue(configuration.isLocal());
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterAll
|
|
||||||
public static void shutdown() {
|
|
||||||
MockBukkit.unmock();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
package net.artelnatif.nicko.test.storage;
|
|
||||||
|
|
||||||
import be.seeseemelk.mockbukkit.MockBukkit;
|
|
||||||
import be.seeseemelk.mockbukkit.ServerMock;
|
|
||||||
import be.seeseemelk.mockbukkit.entity.PlayerMock;
|
|
||||||
import net.artelnatif.nicko.NickoBukkit;
|
|
||||||
import net.artelnatif.nicko.config.Configuration;
|
|
||||||
import net.artelnatif.nicko.config.DataSourceConfiguration;
|
|
||||||
import net.artelnatif.nicko.disguise.ActionResult;
|
|
||||||
import net.artelnatif.nicko.disguise.NickoProfile;
|
|
||||||
import org.junit.jupiter.api.*;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
public class BrokenSQLTest {
|
|
||||||
private static ServerMock server;
|
|
||||||
private static NickoBukkit plugin;
|
|
||||||
private static PlayerMock player;
|
|
||||||
|
|
||||||
@BeforeAll
|
|
||||||
public static void setup() {
|
|
||||||
final Configuration config = new Configuration(
|
|
||||||
DataSourceConfiguration.SQL_EMPTY,
|
|
||||||
DataSourceConfiguration.REDIS_EMPTY,
|
|
||||||
"",
|
|
||||||
false,
|
|
||||||
false);
|
|
||||||
server = MockBukkit.mock();
|
|
||||||
plugin = MockBukkit.load(NickoBukkit.class, config);
|
|
||||||
player = server.addPlayer();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Fail to create Tables")
|
|
||||||
public void createSQLTables() {
|
|
||||||
assertTrue(plugin.getDataStore().getStorage().isError());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Fail to Store Player Via SQL")
|
|
||||||
public void storePlayer() {
|
|
||||||
final Optional<NickoProfile> optionalProfile = plugin.getDataStore().getData(player.getUniqueId());
|
|
||||||
assertFalse(optionalProfile.isPresent());
|
|
||||||
ActionResult<Void> result = plugin.getDataStore().saveData(player);
|
|
||||||
assertTrue(result.isError());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Fail to Retrieve Player Via SQL")
|
|
||||||
public void retrievePlayer() {
|
|
||||||
final Optional<NickoProfile> storeAction = plugin.getDataStore().getData(player.getUniqueId());
|
|
||||||
assertFalse(storeAction.isPresent());
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterAll
|
|
||||||
public static void shutdown() {
|
|
||||||
MockBukkit.unmock();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,117 +0,0 @@
|
||||||
package net.artelnatif.nicko.test.storage;
|
|
||||||
|
|
||||||
import be.seeseemelk.mockbukkit.MockBukkit;
|
|
||||||
import be.seeseemelk.mockbukkit.ServerMock;
|
|
||||||
import be.seeseemelk.mockbukkit.entity.PlayerMock;
|
|
||||||
import net.artelnatif.nicko.NickoBukkit;
|
|
||||||
import net.artelnatif.nicko.config.DataSourceConfiguration;
|
|
||||||
import net.artelnatif.nicko.i18n.Locale;
|
|
||||||
import net.artelnatif.nicko.config.Configuration;
|
|
||||||
import net.artelnatif.nicko.disguise.ActionResult;
|
|
||||||
import net.artelnatif.nicko.disguise.NickoProfile;
|
|
||||||
import org.junit.jupiter.api.*;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
|
||||||
public class SQLStorageTest {
|
|
||||||
private static ServerMock server;
|
|
||||||
private static NickoBukkit plugin;
|
|
||||||
private static PlayerMock player;
|
|
||||||
|
|
||||||
@BeforeAll
|
|
||||||
public static void setup() {
|
|
||||||
final Configuration config = new Configuration(
|
|
||||||
new DataSourceConfiguration("127.0.0.1", 3306, "root", "12345"),
|
|
||||||
DataSourceConfiguration.REDIS_EMPTY,
|
|
||||||
"",
|
|
||||||
false,
|
|
||||||
false);
|
|
||||||
server = MockBukkit.mock();
|
|
||||||
plugin = MockBukkit.load(NickoBukkit.class, config);
|
|
||||||
player = server.addPlayer();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Create SQL Tables")
|
|
||||||
@Order(1)
|
|
||||||
public void createSQLTables() {
|
|
||||||
assertFalse(plugin.getDataStore().getStorage().isError());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Store Player Via SQL")
|
|
||||||
@Order(2)
|
|
||||||
public void storePlayer() {
|
|
||||||
final Optional<NickoProfile> optionalProfile = plugin.getDataStore().getData(player.getUniqueId());
|
|
||||||
assertTrue(optionalProfile.isPresent());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Retrieve Player Via SQL")
|
|
||||||
@Order(3)
|
|
||||||
public void retrievePlayer() {
|
|
||||||
final Optional<NickoProfile> storeAction = plugin.getDataStore().getData(player.getUniqueId());
|
|
||||||
assertTrue(storeAction.isPresent());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Update Player Via SQL")
|
|
||||||
@Order(4)
|
|
||||||
public void updatePlayer() {
|
|
||||||
final Optional<NickoProfile> optionalProfile = plugin.getDataStore().getData(player.getUniqueId());
|
|
||||||
assertTrue(optionalProfile.isPresent());
|
|
||||||
|
|
||||||
final NickoProfile profile = optionalProfile.get();
|
|
||||||
Assertions.assertNull(profile.getName());
|
|
||||||
Assertions.assertNull(profile.getSkin());
|
|
||||||
Assertions.assertEquals(profile.getLocale(), Locale.ENGLISH);
|
|
||||||
assertTrue(profile.isBungeecordTransfer());
|
|
||||||
|
|
||||||
profile.setName("Notch");
|
|
||||||
profile.setSkin("Notch");
|
|
||||||
profile.setLocale(Locale.FRENCH);
|
|
||||||
profile.setBungeecordTransfer(false);
|
|
||||||
|
|
||||||
final ActionResult<Void> result = plugin.getDataStore().saveData(player);
|
|
||||||
assertFalse(result.isError());
|
|
||||||
|
|
||||||
final Optional<NickoProfile> optionalUpdatedProfile = plugin.getDataStore().getData(player.getUniqueId());
|
|
||||||
assertTrue(optionalUpdatedProfile.isPresent());
|
|
||||||
final NickoProfile updatedProfile = optionalProfile.get();
|
|
||||||
Assertions.assertEquals(updatedProfile.getName(), "Notch");
|
|
||||||
Assertions.assertEquals(updatedProfile.getSkin(), "Notch");
|
|
||||||
Assertions.assertEquals(updatedProfile.getLocale(), Locale.FRENCH);
|
|
||||||
assertFalse(updatedProfile.isBungeecordTransfer());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Remove Player Disguise Via SQL")
|
|
||||||
@Order(5)
|
|
||||||
public void removePlayerDisguise() {
|
|
||||||
final Optional<NickoProfile> optionalProfile = plugin.getDataStore().getData(player.getUniqueId());
|
|
||||||
assertTrue(optionalProfile.isPresent());
|
|
||||||
|
|
||||||
final NickoProfile profile = optionalProfile.get();
|
|
||||||
|
|
||||||
profile.setName(null);
|
|
||||||
profile.setSkin(null);
|
|
||||||
|
|
||||||
final ActionResult<Void> result = plugin.getDataStore().saveData(player);
|
|
||||||
assertFalse(result.isError());
|
|
||||||
|
|
||||||
final Optional<NickoProfile> optionalUpdatedProfile = plugin.getDataStore().getData(player.getUniqueId());
|
|
||||||
assertTrue(optionalUpdatedProfile.isPresent());
|
|
||||||
final NickoProfile updatedProfile = optionalProfile.get();
|
|
||||||
Assertions.assertNull(updatedProfile.getName());
|
|
||||||
Assertions.assertNull(updatedProfile.getSkin());
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterAll
|
|
||||||
public static void shutdown() {
|
|
||||||
MockBukkit.unmock();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
package net.artelnatif.nicko.test.storage.cache;
|
|
||||||
|
|
||||||
import be.seeseemelk.mockbukkit.MockBukkit;
|
|
||||||
import be.seeseemelk.mockbukkit.ServerMock;
|
|
||||||
import be.seeseemelk.mockbukkit.entity.PlayerMock;
|
|
||||||
import net.artelnatif.nicko.NickoBukkit;
|
|
||||||
import net.artelnatif.nicko.config.Configuration;
|
|
||||||
import net.artelnatif.nicko.config.DataSourceConfiguration;
|
|
||||||
import net.artelnatif.nicko.disguise.NickoProfile;
|
|
||||||
import org.junit.jupiter.api.AfterAll;
|
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
|
||||||
import org.junit.jupiter.api.DisplayName;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
public class CacheStorageTest {
|
|
||||||
private static ServerMock server;
|
|
||||||
private static NickoBukkit plugin;
|
|
||||||
private static PlayerMock player;
|
|
||||||
|
|
||||||
@BeforeAll
|
|
||||||
public static void setup() {
|
|
||||||
final Configuration config = new Configuration(
|
|
||||||
new DataSourceConfiguration("127.0.0.1", 3306, "root", "12345"),
|
|
||||||
DataSourceConfiguration.REDIS_EMPTY,
|
|
||||||
"",
|
|
||||||
false,
|
|
||||||
false);
|
|
||||||
server = MockBukkit.mock();
|
|
||||||
plugin = MockBukkit.load(NickoBukkit.class, config);
|
|
||||||
player = server.addPlayer();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Cache Player Data")
|
|
||||||
public void cachePlayerData() {
|
|
||||||
final Optional<NickoProfile> optionalProfile = plugin.getDataStore().getData(player.getUniqueId());
|
|
||||||
assertTrue(optionalProfile.isPresent());
|
|
||||||
//assertTrue(plugin.getDataStore().isCached(player.getUniqueId()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterAll
|
|
||||||
public static void shutdown() {
|
|
||||||
MockBukkit.unmock();
|
|
||||||
}
|
|
||||||
}
|
|
115
dist/pom.xml
vendored
115
dist/pom.xml
vendored
|
@ -1,115 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<groupId>net.artelnatif</groupId>
|
|
||||||
<artifactId>nicko-parent</artifactId>
|
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<artifactId>dist</artifactId>
|
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<directory>../target</directory>
|
|
||||||
<finalName>nicko-${project.version}</finalName>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
|
||||||
<version>3.3.1-SNAPSHOT</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>shade</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<artifactSet>
|
|
||||||
<includes>
|
|
||||||
<include>net.artelnatif:*</include>
|
|
||||||
</includes>
|
|
||||||
</artifactSet>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.artelnatif</groupId>
|
|
||||||
<artifactId>core</artifactId>
|
|
||||||
<version>${project.parent.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.artelnatif</groupId>
|
|
||||||
<artifactId>v1_13_R1</artifactId>
|
|
||||||
<version>${project.parent.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.artelnatif</groupId>
|
|
||||||
<artifactId>v1_13_R2</artifactId>
|
|
||||||
<version>${project.parent.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.artelnatif</groupId>
|
|
||||||
<artifactId>v1_14_R1</artifactId>
|
|
||||||
<version>${project.parent.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.artelnatif</groupId>
|
|
||||||
<artifactId>v1_15_R1</artifactId>
|
|
||||||
<version>${project.parent.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.artelnatif</groupId>
|
|
||||||
<artifactId>v1_16_R1</artifactId>
|
|
||||||
<version>${project.parent.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.artelnatif</groupId>
|
|
||||||
<artifactId>v1_16_R2</artifactId>
|
|
||||||
<version>${project.parent.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.artelnatif</groupId>
|
|
||||||
<artifactId>v1_16_R3</artifactId>
|
|
||||||
<version>${project.parent.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.artelnatif</groupId>
|
|
||||||
<artifactId>v1_17_R1</artifactId>
|
|
||||||
<version>${project.parent.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.artelnatif</groupId>
|
|
||||||
<artifactId>v1_18_R1</artifactId>
|
|
||||||
<version>${project.parent.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.artelnatif</groupId>
|
|
||||||
<artifactId>v1_18_R2</artifactId>
|
|
||||||
<version>${project.parent.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.artelnatif</groupId>
|
|
||||||
<artifactId>v1_19_R1</artifactId>
|
|
||||||
<version>${project.parent.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.artelnatif</groupId>
|
|
||||||
<artifactId>v1_19_R2</artifactId>
|
|
||||||
<version>${project.parent.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.artelnatif</groupId>
|
|
||||||
<artifactId>v1_19_R3</artifactId>
|
|
||||||
<version>${project.parent.version}</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</project>
|
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
7
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
7
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip
|
||||||
|
networkTimeout=10000
|
||||||
|
validateDistributionUrl=true
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
251
gradlew
vendored
Executable file
251
gradlew
vendored
Executable file
|
@ -0,0 +1,251 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright © 2015-2021 the original authors.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# Gradle start up script for POSIX generated by Gradle.
|
||||||
|
#
|
||||||
|
# Important for running:
|
||||||
|
#
|
||||||
|
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||||
|
# noncompliant, but you have some other compliant shell such as ksh or
|
||||||
|
# bash, then to run this script, type that shell name before the whole
|
||||||
|
# command line, like:
|
||||||
|
#
|
||||||
|
# ksh Gradle
|
||||||
|
#
|
||||||
|
# Busybox and similar reduced shells will NOT work, because this script
|
||||||
|
# requires all of these POSIX shell features:
|
||||||
|
# * functions;
|
||||||
|
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||||
|
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||||
|
# * compound commands having a testable exit status, especially «case»;
|
||||||
|
# * various built-in commands including «command», «set», and «ulimit».
|
||||||
|
#
|
||||||
|
# Important for patching:
|
||||||
|
#
|
||||||
|
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||||
|
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||||
|
#
|
||||||
|
# The "traditional" practice of packing multiple parameters into a
|
||||||
|
# space-separated string is a well documented source of bugs and security
|
||||||
|
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||||
|
# options in "$@", and eventually passing that to Java.
|
||||||
|
#
|
||||||
|
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||||
|
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||||
|
# see the in-line comments for details.
|
||||||
|
#
|
||||||
|
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||||
|
# Darwin, MinGW, and NonStop.
|
||||||
|
#
|
||||||
|
# (3) This script is generated from the Groovy template
|
||||||
|
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
|
# within the Gradle project.
|
||||||
|
#
|
||||||
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
app_path=$0
|
||||||
|
|
||||||
|
# Need this for daisy-chained symlinks.
|
||||||
|
while
|
||||||
|
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||||
|
[ -h "$app_path" ]
|
||||||
|
do
|
||||||
|
ls=$( ls -ld "$app_path" )
|
||||||
|
link=${ls#*' -> '}
|
||||||
|
case $link in #(
|
||||||
|
/*) app_path=$link ;; #(
|
||||||
|
*) app_path=$APP_HOME$link ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# This is normally unused
|
||||||
|
# shellcheck disable=SC2034
|
||||||
|
APP_BASE_NAME=${0##*/}
|
||||||
|
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||||
|
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD=maximum
|
||||||
|
|
||||||
|
warn () {
|
||||||
|
echo "$*"
|
||||||
|
} >&2
|
||||||
|
|
||||||
|
die () {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
} >&2
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
nonstop=false
|
||||||
|
case "$( uname )" in #(
|
||||||
|
CYGWIN* ) cygwin=true ;; #(
|
||||||
|
Darwin* ) darwin=true ;; #(
|
||||||
|
MSYS* | MINGW* ) msys=true ;; #(
|
||||||
|
NONSTOP* ) nonstop=true ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||||
|
else
|
||||||
|
JAVACMD=$JAVA_HOME/bin/java
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD=java
|
||||||
|
if ! command -v java >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||||
|
case $MAX_FD in #(
|
||||||
|
max*)
|
||||||
|
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||||
|
# shellcheck disable=SC2039,SC3045
|
||||||
|
MAX_FD=$( ulimit -H -n ) ||
|
||||||
|
warn "Could not query maximum file descriptor limit"
|
||||||
|
esac
|
||||||
|
case $MAX_FD in #(
|
||||||
|
'' | soft) :;; #(
|
||||||
|
*)
|
||||||
|
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||||
|
# shellcheck disable=SC2039,SC3045
|
||||||
|
ulimit -n "$MAX_FD" ||
|
||||||
|
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Collect all arguments for the java command, stacking in reverse order:
|
||||||
|
# * args from the command line
|
||||||
|
# * the main class name
|
||||||
|
# * -classpath
|
||||||
|
# * -D...appname settings
|
||||||
|
# * --module-path (only if needed)
|
||||||
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||||
|
|
||||||
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
|
if "$cygwin" || "$msys" ; then
|
||||||
|
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||||
|
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||||
|
|
||||||
|
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||||
|
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
for arg do
|
||||||
|
if
|
||||||
|
case $arg in #(
|
||||||
|
-*) false ;; # don't mess with options #(
|
||||||
|
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||||
|
[ -e "$t" ] ;; #(
|
||||||
|
*) false ;;
|
||||||
|
esac
|
||||||
|
then
|
||||||
|
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||||
|
fi
|
||||||
|
# Roll the args list around exactly as many times as the number of
|
||||||
|
# args, so each arg winds up back in the position where it started, but
|
||||||
|
# possibly modified.
|
||||||
|
#
|
||||||
|
# NB: a `for` loop captures its iteration list before it begins, so
|
||||||
|
# changing the positional parameters here affects neither the number of
|
||||||
|
# iterations, nor the values presented in `arg`.
|
||||||
|
shift # remove old arg
|
||||||
|
set -- "$@" "$arg" # push replacement arg
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
|
# Collect all arguments for the java command:
|
||||||
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||||
|
# and any embedded shellness will be escaped.
|
||||||
|
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||||
|
# treated as '${Hostname}' itself on the command line.
|
||||||
|
|
||||||
|
set -- \
|
||||||
|
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||||
|
-classpath "$CLASSPATH" \
|
||||||
|
org.gradle.wrapper.GradleWrapperMain \
|
||||||
|
"$@"
|
||||||
|
|
||||||
|
# Stop when "xargs" is not available.
|
||||||
|
if ! command -v xargs >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
die "xargs is not available"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Use "xargs" to parse quoted args.
|
||||||
|
#
|
||||||
|
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||||
|
#
|
||||||
|
# In Bash we could simply go:
|
||||||
|
#
|
||||||
|
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||||
|
# set -- "${ARGS[@]}" "$@"
|
||||||
|
#
|
||||||
|
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||||
|
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||||
|
# character that might be a shell metacharacter, then use eval to reverse
|
||||||
|
# that process (while maintaining the separation between arguments), and wrap
|
||||||
|
# the whole thing up as a single "set" statement.
|
||||||
|
#
|
||||||
|
# This will of course break if any of these variables contains a newline or
|
||||||
|
# an unmatched quote.
|
||||||
|
#
|
||||||
|
|
||||||
|
eval "set -- $(
|
||||||
|
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||||
|
xargs -n1 |
|
||||||
|
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||||
|
tr '\n' ' '
|
||||||
|
)" '"$@"'
|
||||||
|
|
||||||
|
exec "$JAVACMD" "$@"
|
94
gradlew.bat
vendored
Normal file
94
gradlew.bat
vendored
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
@rem
|
||||||
|
@rem Copyright 2015 the original author or authors.
|
||||||
|
@rem
|
||||||
|
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@rem you may not use this file except in compliance with the License.
|
||||||
|
@rem You may obtain a copy of the License at
|
||||||
|
@rem
|
||||||
|
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@rem
|
||||||
|
@rem Unless required by applicable law or agreed to in writing, software
|
||||||
|
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@rem See the License for the specific language governing permissions and
|
||||||
|
@rem limitations under the License.
|
||||||
|
@rem
|
||||||
|
@rem SPDX-License-Identifier: Apache-2.0
|
||||||
|
@rem
|
||||||
|
|
||||||
|
@if "%DEBUG%"=="" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%"=="" set DIRNAME=.
|
||||||
|
@rem This is normally unused
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||||
|
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if %ERRORLEVEL% equ 0 goto execute
|
||||||
|
|
||||||
|
echo. 1>&2
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||||
|
echo. 1>&2
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto execute
|
||||||
|
|
||||||
|
echo. 1>&2
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||||
|
echo. 1>&2
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
set EXIT_CODE=%ERRORLEVEL%
|
||||||
|
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||||
|
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||||
|
exit /b %EXIT_CODE%
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
BIN
img/LOGO.png
BIN
img/LOGO.png
Binary file not shown.
Before Width: | Height: | Size: 14 KiB |
35
pom.xml
35
pom.xml
|
@ -1,35 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
|
|
||||||
<groupId>net.artelnatif</groupId>
|
|
||||||
<artifactId>nicko-parent</artifactId>
|
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
<name>Nicko</name>
|
|
||||||
<packaging>pom</packaging>
|
|
||||||
|
|
||||||
<modules>
|
|
||||||
<module>core</module>
|
|
||||||
<module>dist</module>
|
|
||||||
<module>v1_13_R1</module>
|
|
||||||
<module>v1_13_R2</module>
|
|
||||||
<module>v1_14_R1</module>
|
|
||||||
<module>v1_15_R1</module>
|
|
||||||
<module>v1_16_R1</module>
|
|
||||||
<module>v1_16_R2</module>
|
|
||||||
<module>v1_16_R3</module>
|
|
||||||
<module>v1_17_R1</module>
|
|
||||||
<module>v1_18_R1</module>
|
|
||||||
<module>v1_18_R2</module>
|
|
||||||
<module>v1_19_R1</module>
|
|
||||||
<module>v1_19_R2</module>
|
|
||||||
<module>v1_19_R3</module>
|
|
||||||
</modules>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<maven.compiler.source>11</maven.compiler.source>
|
|
||||||
<maven.compiler.target>11</maven.compiler.target>
|
|
||||||
</properties>
|
|
||||||
</project>
|
|
2
settings.gradle.kts
Normal file
2
settings.gradle.kts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
rootProject.name = "nicko"
|
||||||
|
|
176
src/main/java/xyz/ineanto/nicko/Nicko.java
Normal file
176
src/main/java/xyz/ineanto/nicko/Nicko.java
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
package xyz.ineanto.nicko;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.utility.MinecraftVersion;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
import xyz.ineanto.nicko.appearance.random.RandomNameFetcher;
|
||||||
|
import xyz.ineanto.nicko.command.NickoCommand;
|
||||||
|
import xyz.ineanto.nicko.config.Configuration;
|
||||||
|
import xyz.ineanto.nicko.config.ConfigurationManager;
|
||||||
|
import xyz.ineanto.nicko.event.PlayerJoinListener;
|
||||||
|
import xyz.ineanto.nicko.event.PlayerQuitListener;
|
||||||
|
import xyz.ineanto.nicko.language.CustomLanguage;
|
||||||
|
import xyz.ineanto.nicko.language.Language;
|
||||||
|
import xyz.ineanto.nicko.migration.ConfigurationMigrator;
|
||||||
|
import xyz.ineanto.nicko.migration.CustomLocaleMigrator;
|
||||||
|
import xyz.ineanto.nicko.mojang.MojangAPI;
|
||||||
|
import xyz.ineanto.nicko.placeholder.NickoExpansion;
|
||||||
|
import xyz.ineanto.nicko.storage.PlayerDataStore;
|
||||||
|
import xyz.ineanto.nicko.storage.json.JSONStorage;
|
||||||
|
import xyz.ineanto.nicko.storage.map.MapCache;
|
||||||
|
import xyz.ineanto.nicko.storage.name.PlayerNameStore;
|
||||||
|
import xyz.xenondevs.invui.InvUI;
|
||||||
|
import xyz.xenondevs.invui.gui.structure.Structure;
|
||||||
|
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
||||||
|
import xyz.xenondevs.invui.item.impl.SimpleItem;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class Nicko extends JavaPlugin {
|
||||||
|
private static Nicko plugin;
|
||||||
|
|
||||||
|
private MojangAPI mojangAPI;
|
||||||
|
private PlayerDataStore dataStore;
|
||||||
|
private ConfigurationManager configurationManager;
|
||||||
|
private Configuration configuration;
|
||||||
|
private CustomLanguage customLanguage;
|
||||||
|
private PlayerNameStore nameStore;
|
||||||
|
private RandomNameFetcher nameFetcher;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable() {
|
||||||
|
plugin = this;
|
||||||
|
|
||||||
|
configurationManager = new ConfigurationManager(getDataFolder());
|
||||||
|
configurationManager.saveDefaultConfig();
|
||||||
|
|
||||||
|
dataStore = new PlayerDataStore(mojangAPI, getNickoConfig());
|
||||||
|
|
||||||
|
if (!MinecraftVersion.v1_21_5.atOrAbove()) {
|
||||||
|
getLogger().severe("This version (" + MinecraftVersion.getCurrentVersion().getVersion() + ") is not supported by Nicko!");
|
||||||
|
getLogger().severe("As of version 1.2.0, Nicko only supports the latest Minecraft version. (Currently 1.21.5)");
|
||||||
|
dataStore.getStorage().setError(true);
|
||||||
|
Bukkit.getPluginManager().disablePlugin(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Bukkit.getOnlineMode()) {
|
||||||
|
getLogger().warning("Nicko has not been tested using offline mode!");
|
||||||
|
getLogger().warning("Issues regarding Nicko being used in offline mode will be ignored for now.");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Class.forName("io.papermc.paper.threadedregions.RegionizedServerInitEvent");
|
||||||
|
getLogger().warning("Nicko has not been tested against Folia and might not work at all!");
|
||||||
|
getLogger().warning("Issues regarding Nicko on Folia will be ignored for now.");
|
||||||
|
} catch (ClassNotFoundException ignored) { }
|
||||||
|
|
||||||
|
getLogger().info("Loading persistence...");
|
||||||
|
if (!dataStore.getStorage().getProvider().init()) {
|
||||||
|
getLogger().severe("Couldn't connect to distant persistence, falling back on local persistence.");
|
||||||
|
final JSONStorage storage = new JSONStorage();
|
||||||
|
storage.getProvider().init();
|
||||||
|
dataStore.setStorage(storage);
|
||||||
|
}
|
||||||
|
|
||||||
|
getLogger().info("Loading cache...");
|
||||||
|
if (!dataStore.getCache().getProvider().init()) {
|
||||||
|
getLogger().severe("Couldn't connect to distant cache, falling back on local cache.");
|
||||||
|
final MapCache cache = new MapCache();
|
||||||
|
cache.getProvider().init();
|
||||||
|
dataStore.setCache(cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
nameStore = new PlayerNameStore();
|
||||||
|
mojangAPI = new MojangAPI();
|
||||||
|
nameFetcher = new RandomNameFetcher(this);
|
||||||
|
|
||||||
|
new ConfigurationMigrator(this).migrate();
|
||||||
|
InvUI.getInstance().setPlugin(this);
|
||||||
|
|
||||||
|
if (configuration.isCustomLocale()) {
|
||||||
|
try {
|
||||||
|
CustomLanguage.dumpIntoFile(Language.ENGLISH);
|
||||||
|
customLanguage = new CustomLanguage();
|
||||||
|
new CustomLocaleMigrator(this, customLanguage).migrate();
|
||||||
|
getLogger().info("Successfully loaded the custom locale.");
|
||||||
|
} catch (IOException e) {
|
||||||
|
getLogger().severe("Failed to load the custom locale!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
registerCommand("nicko", new NickoCommand());
|
||||||
|
|
||||||
|
Structure.addGlobalIngredient('#', new SimpleItem(new ItemBuilder(Material.AIR)));
|
||||||
|
Structure.addGlobalIngredient('%', new SimpleItem(new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE).setDisplayName(" ")));
|
||||||
|
|
||||||
|
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
|
||||||
|
getLogger().info("Enabling PlaceHolderAPI support...");
|
||||||
|
new NickoExpansion(this).register();
|
||||||
|
}
|
||||||
|
|
||||||
|
getServer().getPluginManager().registerEvents(new PlayerJoinListener(), this);
|
||||||
|
getServer().getPluginManager().registerEvents(new PlayerQuitListener(), this);
|
||||||
|
|
||||||
|
getLogger().info("Nicko has been enabled.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisable() {
|
||||||
|
if (!getDataStore().getStorage().isError()) {
|
||||||
|
Bukkit.getOnlinePlayers().forEach(player -> dataStore.saveData(player));
|
||||||
|
if (!dataStore.getStorage().getProvider().close()) {
|
||||||
|
getLogger().severe("Failed to close persistence!");
|
||||||
|
} else {
|
||||||
|
getLogger().info("Persistence closed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nameStore.clearStoredNames();
|
||||||
|
getLogger().info("Nicko (Bukkit) has been disabled.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Nicko getInstance() {
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Configuration getNickoConfig() {
|
||||||
|
try {
|
||||||
|
if (configuration == null) {
|
||||||
|
configuration = configurationManager.load();
|
||||||
|
getLogger().info("Configuration file loaded.");
|
||||||
|
}
|
||||||
|
return configuration;
|
||||||
|
} catch (IOException e) {
|
||||||
|
getLogger().severe("Failed to load the configuration file!");
|
||||||
|
getLogger().severe("It may be have been generated with an older version of Nicko.");
|
||||||
|
getLogger().severe("Delete the configuration and restart the server please :)");
|
||||||
|
getLogger().severe("(" + e.getMessage() + ")");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public RandomNameFetcher getNameFetcher() {
|
||||||
|
return nameFetcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlayerDataStore getDataStore() {
|
||||||
|
return dataStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigurationManager getConfigurationManager() {
|
||||||
|
return configurationManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlayerNameStore getNameStore() {
|
||||||
|
return nameStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MojangAPI getMojangAPI() {
|
||||||
|
return mojangAPI;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CustomLanguage getCustomLocale() {
|
||||||
|
return customLanguage;
|
||||||
|
}
|
||||||
|
}
|
35
src/main/java/xyz/ineanto/nicko/appearance/ActionResult.java
Normal file
35
src/main/java/xyz/ineanto/nicko/appearance/ActionResult.java
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
package xyz.ineanto.nicko.appearance;
|
||||||
|
|
||||||
|
public class ActionResult {
|
||||||
|
private final String errorKey;
|
||||||
|
private boolean error = false;
|
||||||
|
|
||||||
|
public static ActionResult ok() {
|
||||||
|
return new ActionResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ActionResult error() {
|
||||||
|
return new ActionResult(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ActionResult error(String errorMessage) {
|
||||||
|
return new ActionResult(errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ActionResult() {
|
||||||
|
this.errorKey = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ActionResult(String errorMessage) {
|
||||||
|
this.errorKey = errorMessage;
|
||||||
|
this.error = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isError() {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getErrorKey() {
|
||||||
|
return errorKey;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package xyz.ineanto.nicko.appearance;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public record Appearance(
|
||||||
|
@Nullable String name,
|
||||||
|
@Nullable String skin
|
||||||
|
) {}
|
|
@ -0,0 +1,70 @@
|
||||||
|
package xyz.ineanto.nicko.appearance;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import xyz.ineanto.nicko.Nicko;
|
||||||
|
import xyz.ineanto.nicko.event.custom.PlayerDisguiseEvent;
|
||||||
|
import xyz.ineanto.nicko.event.custom.PlayerResetDisguiseEvent;
|
||||||
|
import xyz.ineanto.nicko.packet.PacketSender;
|
||||||
|
import xyz.ineanto.nicko.packet.PaperPacketSender;
|
||||||
|
import xyz.ineanto.nicko.profile.NickoProfile;
|
||||||
|
import xyz.ineanto.nicko.storage.PlayerDataStore;
|
||||||
|
import xyz.ineanto.nicko.storage.name.PlayerNameStore;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class AppearanceManager {
|
||||||
|
private final Nicko instance = Nicko.getInstance();
|
||||||
|
private final PlayerDataStore dataStore = instance.getDataStore();
|
||||||
|
private final PlayerNameStore nameStore = instance.getNameStore();
|
||||||
|
private final PacketSender packetSender;
|
||||||
|
|
||||||
|
private final Player player;
|
||||||
|
|
||||||
|
public AppearanceManager(Player player) {
|
||||||
|
this.player = player;
|
||||||
|
this.packetSender = new PaperPacketSender(player, getNickoProfile());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionResult reset() {
|
||||||
|
final NickoProfile profile = getNickoProfile();
|
||||||
|
|
||||||
|
// Call the event.
|
||||||
|
final PlayerResetDisguiseEvent event = new PlayerResetDisguiseEvent(player);
|
||||||
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
|
|
||||||
|
profile.setName(null);
|
||||||
|
profile.setSkin(null);
|
||||||
|
dataStore.getCache().cache(player.getUniqueId(), profile);
|
||||||
|
|
||||||
|
return ActionResult.error();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionResult update(boolean skinChange) {
|
||||||
|
final NickoProfile profile = getNickoProfile();
|
||||||
|
final String displayName = profile.getName() == null ? player.getName() : profile.getName();
|
||||||
|
|
||||||
|
final ActionResult result = packetSender.updatePlayerProfile(displayName);
|
||||||
|
|
||||||
|
if (skinChange) {
|
||||||
|
final ActionResult propertiesUpdateResult = packetSender.updatePlayerProfileProperties();
|
||||||
|
|
||||||
|
if (propertiesUpdateResult.isError()) {
|
||||||
|
return reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call the event.
|
||||||
|
final PlayerDisguiseEvent event = new PlayerDisguiseEvent(player, profile.getSkin(), profile.getName());
|
||||||
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
|
|
||||||
|
packetSender.sendEntityMetadataUpdate();
|
||||||
|
packetSender.sendTabListUpdate(displayName);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private NickoProfile getNickoProfile() {
|
||||||
|
final Optional<NickoProfile> optionalProfile = dataStore.getData(player.getUniqueId());
|
||||||
|
return optionalProfile.orElse(NickoProfile.EMPTY_PROFILE.clone());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package xyz.ineanto.nicko.appearance.random;
|
||||||
|
|
||||||
|
import xyz.ineanto.nicko.Nicko;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class RandomNameFetcher {
|
||||||
|
private final Nicko instance;
|
||||||
|
|
||||||
|
public RandomNameFetcher(Nicko instance) {
|
||||||
|
this.instance = instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRandomUsername() {
|
||||||
|
final InputStream resource = instance.getResource("names.txt");
|
||||||
|
final List<List<String>> records = new ArrayList<>();
|
||||||
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(resource))) {
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
final String[] values = line.split("\n");
|
||||||
|
records.add(Arrays.asList(values));
|
||||||
|
}
|
||||||
|
return records.get(new Random().nextInt(records.size() - 1)).getFirst();
|
||||||
|
} catch (IOException e) {
|
||||||
|
instance.getLogger().severe("Unable to fetch random names.");
|
||||||
|
return "Ineanto";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
69
src/main/java/xyz/ineanto/nicko/command/NickoCommand.java
Normal file
69
src/main/java/xyz/ineanto/nicko/command/NickoCommand.java
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
package xyz.ineanto.nicko.command;
|
||||||
|
|
||||||
|
import io.papermc.paper.command.brigadier.BasicCommand;
|
||||||
|
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||||
|
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jspecify.annotations.Nullable;
|
||||||
|
import xyz.ineanto.nicko.Nicko;
|
||||||
|
import xyz.ineanto.nicko.config.Configuration;
|
||||||
|
import xyz.ineanto.nicko.gui.HomeGUI;
|
||||||
|
import xyz.ineanto.nicko.language.Language;
|
||||||
|
import xyz.ineanto.nicko.language.PlayerLanguage;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@SuppressWarnings("UnstableApiUsage")
|
||||||
|
public class NickoCommand implements BasicCommand {
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSourceStack stack, String[] args) {
|
||||||
|
final Entity executor = stack.getExecutor();
|
||||||
|
final Player player = (Player) executor;
|
||||||
|
final PlayerLanguage playerLanguage = new PlayerLanguage(player);
|
||||||
|
|
||||||
|
if (player == null) { return; }
|
||||||
|
|
||||||
|
if (args.length >= 1 && args[0].equalsIgnoreCase("about")) {
|
||||||
|
final Component firstAboutMessage = MiniMessage.miniMessage().deserialize(
|
||||||
|
"<prefix> <dark_gray>(© Ineanto 2023-2025) </dark_gray><gray>v<version></gray> ",
|
||||||
|
Placeholder.component("prefix", playerLanguage.getPrefixComponent()),
|
||||||
|
Placeholder.unparsed("version", Nicko.getInstance().getPluginMeta().getVersion())
|
||||||
|
);
|
||||||
|
|
||||||
|
final Component secondAboutMessage = MiniMessage.miniMessage().deserialize(
|
||||||
|
"<gradient:#01a97c:#8ffd54>Configuration</gradient> <gray>v<configversion></gray>, <gradient:#01a97c:#8ffd54>I18N</gradient> <gray><i18nversion></gray>",
|
||||||
|
Placeholder.component("prefix", playerLanguage.getPrefixComponent()),
|
||||||
|
Placeholder.unparsed("configversion", Configuration.VERSION.toString()),
|
||||||
|
Placeholder.unparsed("i18nversion", Language.VERSION.toString())
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
player.sendMessage(firstAboutMessage);
|
||||||
|
player.sendMessage(secondAboutMessage);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
new HomeGUI(player).open();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canUse(CommandSender sender) {
|
||||||
|
return sender instanceof Player && sender.isOp() || sender.hasPermission(permission());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<String> suggest(CommandSourceStack commandSourceStack, String[] args) {
|
||||||
|
return List.of("about");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String permission() {
|
||||||
|
return "nicko.use";
|
||||||
|
}
|
||||||
|
}
|
54
src/main/java/xyz/ineanto/nicko/config/Configuration.java
Normal file
54
src/main/java/xyz/ineanto/nicko/config/Configuration.java
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
package xyz.ineanto.nicko.config;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import xyz.ineanto.nicko.version.Version;
|
||||||
|
|
||||||
|
public class Configuration {
|
||||||
|
public static final Version VERSION = new Version(1, 2, 0);
|
||||||
|
public static final Configuration DEFAULT = new Configuration(VERSION.toString(),
|
||||||
|
DefaultDataSources.SQL_EMPTY,
|
||||||
|
DefaultDataSources.REDIS_EMPTY,
|
||||||
|
false);
|
||||||
|
|
||||||
|
private final transient Version versionObject;
|
||||||
|
|
||||||
|
@JsonProperty("version")
|
||||||
|
private final String version;
|
||||||
|
@JsonProperty("sql")
|
||||||
|
private final SQLDataSourceConfiguration sqlConfiguration;
|
||||||
|
@JsonProperty("redis")
|
||||||
|
private final DataSourceConfiguration redisConfiguration;
|
||||||
|
@JsonProperty("customLocale")
|
||||||
|
private final Boolean customLocale;
|
||||||
|
|
||||||
|
public Configuration(@JsonProperty("version") String version,
|
||||||
|
@JsonProperty("sql") SQLDataSourceConfiguration sqlConfiguration,
|
||||||
|
@JsonProperty("redis") DataSourceConfiguration redisConfiguration,
|
||||||
|
@JsonProperty("customLocale") Boolean customLocale) {
|
||||||
|
this.version = version;
|
||||||
|
this.versionObject = Version.fromString(version);
|
||||||
|
this.sqlConfiguration = sqlConfiguration;
|
||||||
|
this.redisConfiguration = redisConfiguration;
|
||||||
|
this.customLocale = customLocale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Version getVersionObject() {
|
||||||
|
return versionObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SQLDataSourceConfiguration getSqlConfiguration() {
|
||||||
|
return sqlConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataSourceConfiguration getRedisConfiguration() {
|
||||||
|
return redisConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean isCustomLocale() {
|
||||||
|
return customLocale;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package net.artelnatif.nicko.config;
|
package xyz.ineanto.nicko.config;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
@ -7,16 +7,23 @@ import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.StandardCopyOption;
|
import java.nio.file.StandardCopyOption;
|
||||||
import java.util.logging.Logger;
|
import java.time.Instant;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
public class ConfigurationManager {
|
public class ConfigurationManager {
|
||||||
private final Logger logger = Logger.getLogger("ConfigurationManager");
|
|
||||||
private final ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
|
private final ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
|
||||||
private final File file;
|
private final File file;
|
||||||
|
private final File backupFile;
|
||||||
|
|
||||||
public ConfigurationManager(File directory) {
|
public ConfigurationManager(File directory) {
|
||||||
|
final String date = Instant.now()
|
||||||
|
.atZone(ZoneId.systemDefault())
|
||||||
|
.format(DateTimeFormatter.ofPattern("dd-MM-yyyy"));
|
||||||
this.file = new File(directory, "config.yml");
|
this.file = new File(directory, "config.yml");
|
||||||
|
this.backupFile = new File(directory, "config.old-" + date + ".yml");
|
||||||
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||||
|
mapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save(Configuration configuration) throws IOException {
|
public void save(Configuration configuration) throws IOException {
|
||||||
|
@ -31,7 +38,6 @@ public class ConfigurationManager {
|
||||||
try {
|
try {
|
||||||
final InputStream input = getClass().getResourceAsStream("/config.yml");
|
final InputStream input = getClass().getResourceAsStream("/config.yml");
|
||||||
if (input != null) {
|
if (input != null) {
|
||||||
logger.info("Saved default configuration as config.yml");
|
|
||||||
Files.createDirectories(file.getParentFile().toPath());
|
Files.createDirectories(file.getParentFile().toPath());
|
||||||
Files.createFile(file.toPath());
|
Files.createFile(file.toPath());
|
||||||
Files.copy(input, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
Files.copy(input, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
@ -47,4 +53,12 @@ public class ConfigurationManager {
|
||||||
return mapper.readValue(reader, Configuration.class);
|
return mapper.readValue(reader, Configuration.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public File getFile() {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getBackupFile() {
|
||||||
|
return backupFile;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package xyz.ineanto.nicko.config;
|
||||||
|
|
||||||
|
public class DataSourceConfiguration {
|
||||||
|
private final boolean enabled;
|
||||||
|
private final String address;
|
||||||
|
private final Integer port;
|
||||||
|
private final String username;
|
||||||
|
private final String password;
|
||||||
|
|
||||||
|
public DataSourceConfiguration(boolean enabled, String address, Integer port, String username, String password) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
this.address = address;
|
||||||
|
this.port = port;
|
||||||
|
this.username = username;
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataSourceConfiguration() { this(false, "", 0, "", ""); }
|
||||||
|
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAddress() {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getPort() {
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "DataSourceConfiguration{" +
|
||||||
|
"enabled=" + enabled +
|
||||||
|
", address='" + address + '\'' +
|
||||||
|
", port=" + port +
|
||||||
|
", username='" + username + '\'' +
|
||||||
|
", password='" + password + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package xyz.ineanto.nicko.config;
|
||||||
|
|
||||||
|
public class DefaultDataSources {
|
||||||
|
public static final DataSourceConfiguration REDIS_EMPTY = new DataSourceConfiguration(false, "127.0.0.1", 6379, "", "");
|
||||||
|
public static final SQLDataSourceConfiguration MARIADB_EMPTY = new SQLDataSourceConfiguration(false, "127.0.0.1", 3306, "root", "", true);
|
||||||
|
public static final SQLDataSourceConfiguration SQL_EMPTY = new SQLDataSourceConfiguration(false, "127.0.0.1", 3306, "root", "", false);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package xyz.ineanto.nicko.config;
|
||||||
|
|
||||||
|
public class SQLDataSourceConfiguration extends DataSourceConfiguration {
|
||||||
|
private final boolean mariadb;
|
||||||
|
|
||||||
|
public SQLDataSourceConfiguration() { this(false, "", 0, "", "", true); }
|
||||||
|
|
||||||
|
public SQLDataSourceConfiguration(boolean enabled, String address, Integer port, String username, String password, boolean mariadb) {
|
||||||
|
super(enabled, address, port, username, password);
|
||||||
|
this.mariadb = mariadb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMariadb() {
|
||||||
|
return mariadb;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
package xyz.ineanto.nicko.event;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
|
import xyz.ineanto.nicko.Nicko;
|
||||||
|
import xyz.ineanto.nicko.appearance.ActionResult;
|
||||||
|
import xyz.ineanto.nicko.appearance.AppearanceManager;
|
||||||
|
import xyz.ineanto.nicko.gui.PlayerCheckGUI;
|
||||||
|
import xyz.ineanto.nicko.gui.PlayerCheckGUIData;
|
||||||
|
import xyz.ineanto.nicko.language.LanguageKey;
|
||||||
|
import xyz.ineanto.nicko.language.PlayerLanguage;
|
||||||
|
import xyz.ineanto.nicko.profile.NickoProfile;
|
||||||
|
import xyz.ineanto.nicko.storage.PlayerDataStore;
|
||||||
|
import xyz.ineanto.nicko.storage.name.PlayerNameStore;
|
||||||
|
import xyz.xenondevs.invui.window.Window;
|
||||||
|
import xyz.xenondevs.invui.window.WindowManager;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class PlayerJoinListener implements Listener {
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
|
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
|
final Player player = event.getPlayer();
|
||||||
|
final Nicko instance = Nicko.getInstance();
|
||||||
|
final PlayerLanguage playerLanguage = new PlayerLanguage(player);
|
||||||
|
final PlayerNameStore nameStore = instance.getNameStore();
|
||||||
|
final PlayerDataStore dataStore = instance.getDataStore();
|
||||||
|
nameStore.storeName(player);
|
||||||
|
|
||||||
|
final Optional<NickoProfile> optionalProfile = dataStore.getData(player.getUniqueId());
|
||||||
|
optionalProfile.ifPresentOrElse(profile -> {
|
||||||
|
// Random Skin on connection feature
|
||||||
|
if (profile.isRandomSkin()) {
|
||||||
|
final String name = instance.getNameFetcher().getRandomUsername();
|
||||||
|
final String skin = instance.getNameFetcher().getRandomUsername();
|
||||||
|
profile.setName(name);
|
||||||
|
profile.setSkin(skin);
|
||||||
|
dataStore.updateCache(player.getUniqueId(), profile);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (profile.hasData()) {
|
||||||
|
final AppearanceManager appearanceManager = new AppearanceManager(player);
|
||||||
|
final boolean needsASkinChange = profile.getSkin() != null && !profile.getSkin().equals(player.getName());
|
||||||
|
final ActionResult actionResult = appearanceManager.update(needsASkinChange);
|
||||||
|
if (!actionResult.isError()) {
|
||||||
|
player.sendMessage(playerLanguage.translateWithWhoosh(LanguageKey.Event.Appearance.Restore.OK));
|
||||||
|
} else {
|
||||||
|
player.sendMessage(
|
||||||
|
playerLanguage.translateWithOops(LanguageKey.Event.Appearance.Restore.ERROR,
|
||||||
|
playerLanguage.translate(actionResult.getErrorKey(), false)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, () -> instance.getLogger().warning("Failed to load data for " + player.getName()));
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked") final ArrayList<UUID> viewers = (ArrayList<UUID>) PlayerCheckGUIData.VIEWERS.clone();
|
||||||
|
viewers.forEach(uuid -> {
|
||||||
|
final Player windowWatcher = Bukkit.getPlayer(uuid);
|
||||||
|
final Window openWindow = WindowManager.getInstance().getOpenWindow(windowWatcher);
|
||||||
|
if (openWindow != null) {
|
||||||
|
final PlayerCheckGUI gui = new PlayerCheckGUI(windowWatcher, Bukkit.getOnlinePlayers());
|
||||||
|
openWindow.close();
|
||||||
|
gui.open();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package xyz.ineanto.nicko.event;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
|
import xyz.ineanto.nicko.Nicko;
|
||||||
|
import xyz.ineanto.nicko.appearance.ActionResult;
|
||||||
|
import xyz.ineanto.nicko.gui.PlayerCheckGUI;
|
||||||
|
import xyz.ineanto.nicko.gui.PlayerCheckGUIData;
|
||||||
|
import xyz.xenondevs.invui.window.Window;
|
||||||
|
import xyz.xenondevs.invui.window.WindowManager;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class PlayerQuitListener implements Listener {
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
|
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||||
|
final Player player = event.getPlayer();
|
||||||
|
final ActionResult result = Nicko.getInstance().getDataStore().saveData(player);
|
||||||
|
if (result.isError()) {
|
||||||
|
Nicko.getInstance().getLogger().warning("Failed to save data for " + player.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a dirty way to do it but could be worse tbh
|
||||||
|
@SuppressWarnings("unchecked") final ArrayList<UUID> viewers = (ArrayList<UUID>) PlayerCheckGUIData.VIEWERS.clone();
|
||||||
|
viewers.forEach(uuid -> {
|
||||||
|
final Player windowWatcher = Bukkit.getPlayer(uuid);
|
||||||
|
final Window openWindow = WindowManager.getInstance().getOpenWindow(windowWatcher);
|
||||||
|
if (openWindow != null) {
|
||||||
|
final List<? extends Player> playersWithoutOffline = Bukkit.getOnlinePlayers()
|
||||||
|
.stream()
|
||||||
|
.filter(online -> online.getUniqueId() != player.getUniqueId()).collect(Collectors.toList());
|
||||||
|
final PlayerCheckGUI gui = new PlayerCheckGUI(windowWatcher, playersWithoutOffline);
|
||||||
|
openWindow.close();
|
||||||
|
gui.open();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package xyz.ineanto.nicko.event.custom;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.Cancellable;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class PlayerDisguiseEvent extends Event implements Cancellable {
|
||||||
|
private static final HandlerList HANDLERS_LIST = new HandlerList();
|
||||||
|
private boolean isCancelled;
|
||||||
|
private final Player player;
|
||||||
|
private final String skin, name;
|
||||||
|
|
||||||
|
public PlayerDisguiseEvent(Player player, String skin, String name) {
|
||||||
|
this.player = player;
|
||||||
|
this.skin = skin;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCancelled() {
|
||||||
|
return isCancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCancelled(boolean isCancelled) {
|
||||||
|
this.isCancelled = isCancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull HandlerList getHandlers() {
|
||||||
|
return HANDLERS_LIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Player getPlayer() {
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSkin() {
|
||||||
|
return skin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package xyz.ineanto.nicko.event.custom;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.Cancellable;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class PlayerResetDisguiseEvent extends Event implements Cancellable {
|
||||||
|
private static final HandlerList HANDLERS_LIST = new HandlerList();
|
||||||
|
private boolean isCancelled;
|
||||||
|
private final Player player;
|
||||||
|
|
||||||
|
public PlayerResetDisguiseEvent(Player player) {
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCancelled() {
|
||||||
|
return isCancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCancelled(boolean isCancelled) {
|
||||||
|
this.isCancelled = isCancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull HandlerList getHandlers() {
|
||||||
|
return HANDLERS_LIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Player getPlayer() {
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
}
|
49
src/main/java/xyz/ineanto/nicko/gui/AdminGUI.java
Normal file
49
src/main/java/xyz/ineanto/nicko/gui/AdminGUI.java
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
package xyz.ineanto.nicko.gui;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import xyz.ineanto.nicko.gui.items.admin.ManageCacheItem;
|
||||||
|
import xyz.ineanto.nicko.gui.items.admin.ManagePlayerItem;
|
||||||
|
import xyz.ineanto.nicko.gui.items.common.GoBackItem;
|
||||||
|
import xyz.ineanto.nicko.language.LanguageKey;
|
||||||
|
import xyz.ineanto.nicko.language.PlayerLanguage;
|
||||||
|
import xyz.xenondevs.invui.gui.Gui;
|
||||||
|
import xyz.xenondevs.invui.window.Window;
|
||||||
|
|
||||||
|
public class AdminGUI {
|
||||||
|
private final Player player;
|
||||||
|
private final Gui gui;
|
||||||
|
private final String title;
|
||||||
|
|
||||||
|
public AdminGUI(Player player) {
|
||||||
|
final PlayerLanguage playerLanguage = new PlayerLanguage(player);
|
||||||
|
this.title = playerLanguage.translate(LanguageKey.GUI.Titles.ADMIN, false);
|
||||||
|
|
||||||
|
final HomeGUI parent = new HomeGUI(player);
|
||||||
|
final GoBackItem backItem = new GoBackItem(player);
|
||||||
|
final ManagePlayerItem managePlayerItem = new ManagePlayerItem(playerLanguage, player);
|
||||||
|
|
||||||
|
this.gui = Gui.normal()
|
||||||
|
.setStructure(
|
||||||
|
"# # # # # # # # #",
|
||||||
|
"# # # S # C # # #",
|
||||||
|
"B # # # # # # # #"
|
||||||
|
)
|
||||||
|
.addIngredient('S', new ManageCacheItem(playerLanguage))
|
||||||
|
.addIngredient('C', managePlayerItem.get())
|
||||||
|
.addIngredient('B', backItem.get(parent.getGUI(), parent.getTitle()))
|
||||||
|
.build();
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Gui getGUI() {
|
||||||
|
return gui;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void open() {
|
||||||
|
Window.single().setGui(gui).setTitle(title).open(player);
|
||||||
|
}
|
||||||
|
}
|
54
src/main/java/xyz/ineanto/nicko/gui/CacheManagementGUI.java
Normal file
54
src/main/java/xyz/ineanto/nicko/gui/CacheManagementGUI.java
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
package xyz.ineanto.nicko.gui;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import xyz.ineanto.nicko.gui.items.admin.cache.CacheStatisticsItem;
|
||||||
|
import xyz.ineanto.nicko.gui.items.admin.cache.InvalidateCacheItem;
|
||||||
|
import xyz.ineanto.nicko.gui.items.admin.cache.InvalidateSkinItem;
|
||||||
|
import xyz.ineanto.nicko.gui.items.common.GoBackItem;
|
||||||
|
import xyz.ineanto.nicko.language.PlayerLanguage;
|
||||||
|
import xyz.ineanto.nicko.language.LanguageKey;
|
||||||
|
import xyz.xenondevs.invui.gui.Gui;
|
||||||
|
import xyz.xenondevs.invui.window.Window;
|
||||||
|
|
||||||
|
public class CacheManagementGUI {
|
||||||
|
private final Player player;
|
||||||
|
private final Gui gui;
|
||||||
|
private final String title;
|
||||||
|
|
||||||
|
public CacheManagementGUI(Player player) {
|
||||||
|
final PlayerLanguage playerLanguage = new PlayerLanguage(player);
|
||||||
|
this.title = playerLanguage.translate(LanguageKey.GUI.Titles.CACHE, false);
|
||||||
|
|
||||||
|
final AdminGUI parent = new AdminGUI(player);
|
||||||
|
final GoBackItem backItem = new GoBackItem(player);
|
||||||
|
|
||||||
|
final CacheStatisticsItem cacheStatisticsItem = new CacheStatisticsItem(player);
|
||||||
|
final InvalidateCacheItem invalidateCacheItem = new InvalidateCacheItem(player);
|
||||||
|
final InvalidateSkinItem invalidateSkinItem = new InvalidateSkinItem(player);
|
||||||
|
|
||||||
|
this.gui = Gui.normal()
|
||||||
|
.setStructure(
|
||||||
|
"# # # # # # # # #",
|
||||||
|
"# # # S C E # # #",
|
||||||
|
"B # # # # # # # #"
|
||||||
|
)
|
||||||
|
.addIngredient('B', backItem.get(parent.getGUI(), parent.getTitle()))
|
||||||
|
.addIngredient('S', cacheStatisticsItem.get())
|
||||||
|
.addIngredient('C', invalidateCacheItem.get())
|
||||||
|
.addIngredient('E', invalidateSkinItem.get())
|
||||||
|
.build();
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Gui getGUI() {
|
||||||
|
return gui;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void open() {
|
||||||
|
Window.single().setGui(gui).setTitle(title).open(player);
|
||||||
|
}
|
||||||
|
}
|
42
src/main/java/xyz/ineanto/nicko/gui/ChoiceGUI.java
Normal file
42
src/main/java/xyz/ineanto/nicko/gui/ChoiceGUI.java
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
package xyz.ineanto.nicko.gui;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import xyz.ineanto.nicko.gui.items.common.choice.CancelItem;
|
||||||
|
import xyz.ineanto.nicko.gui.items.common.choice.ChoiceCallback;
|
||||||
|
import xyz.ineanto.nicko.gui.items.common.choice.ConfirmItem;
|
||||||
|
import xyz.ineanto.nicko.language.PlayerLanguage;
|
||||||
|
import xyz.ineanto.nicko.language.LanguageKey;
|
||||||
|
import xyz.xenondevs.invui.gui.Gui;
|
||||||
|
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
||||||
|
import xyz.xenondevs.invui.item.impl.SimpleItem;
|
||||||
|
import xyz.xenondevs.invui.window.Window;
|
||||||
|
|
||||||
|
public class ChoiceGUI {
|
||||||
|
private final Player player;
|
||||||
|
private final Gui gui;
|
||||||
|
private final String title;
|
||||||
|
|
||||||
|
public ChoiceGUI(Player player, ChoiceCallback callback) {
|
||||||
|
final PlayerLanguage playerLanguage = new PlayerLanguage(player);
|
||||||
|
final ConfirmItem confirmItem = new ConfirmItem(player, callback);
|
||||||
|
final CancelItem cancelItem = new CancelItem(player, callback);
|
||||||
|
|
||||||
|
this.title = playerLanguage.translate(LanguageKey.GUI.Titles.CONFIRM, false);
|
||||||
|
this.gui = Gui.normal()
|
||||||
|
.setStructure(
|
||||||
|
"@ @ @ @ % & & & &",
|
||||||
|
"@ @ @ @ I & & & &",
|
||||||
|
"@ @ @ @ % & & & &"
|
||||||
|
)
|
||||||
|
.addIngredient('@', confirmItem.get())
|
||||||
|
.addIngredient('&', cancelItem.get())
|
||||||
|
.addIngredient('I', new SimpleItem(playerLanguage.translateItem(new ItemBuilder(Material.PAPER), LanguageKey.GUI.Choice.CHOOSE)))
|
||||||
|
.build();
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void open() {
|
||||||
|
Window.single().setGui(gui).setTitle(title).open(player);
|
||||||
|
}
|
||||||
|
}
|
84
src/main/java/xyz/ineanto/nicko/gui/FavoritesGUI.java
Normal file
84
src/main/java/xyz/ineanto/nicko/gui/FavoritesGUI.java
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
package xyz.ineanto.nicko.gui;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import xyz.ineanto.nicko.Nicko;
|
||||||
|
import xyz.ineanto.nicko.appearance.Appearance;
|
||||||
|
import xyz.ineanto.nicko.gui.items.common.GoBackItem;
|
||||||
|
import xyz.ineanto.nicko.gui.items.common.ScrollDownItem;
|
||||||
|
import xyz.ineanto.nicko.gui.items.common.ScrollUpItem;
|
||||||
|
import xyz.ineanto.nicko.gui.items.favorites.FavoriteAddItem;
|
||||||
|
import xyz.ineanto.nicko.gui.items.favorites.FavoriteAppearanceEntryItem;
|
||||||
|
import xyz.ineanto.nicko.gui.items.favorites.FavoriteRemoveItem;
|
||||||
|
import xyz.ineanto.nicko.language.LanguageKey;
|
||||||
|
import xyz.ineanto.nicko.language.PlayerLanguage;
|
||||||
|
import xyz.ineanto.nicko.profile.NickoProfile;
|
||||||
|
import xyz.xenondevs.invui.gui.Gui;
|
||||||
|
import xyz.xenondevs.invui.gui.ScrollGui;
|
||||||
|
import xyz.xenondevs.invui.gui.structure.Markers;
|
||||||
|
import xyz.xenondevs.invui.item.Item;
|
||||||
|
import xyz.xenondevs.invui.window.Window;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class FavoritesGUI {
|
||||||
|
private final Player player;
|
||||||
|
private final Gui gui;
|
||||||
|
private final String title;
|
||||||
|
|
||||||
|
public FavoritesGUI(Player player) {
|
||||||
|
final PlayerLanguage playerLanguage = new PlayerLanguage(player);
|
||||||
|
this.title = playerLanguage.translate(LanguageKey.GUI.Titles.FAVORITES, false);
|
||||||
|
|
||||||
|
final HomeGUI parent = new HomeGUI(player);
|
||||||
|
final GoBackItem backItem = new GoBackItem(player);
|
||||||
|
final ScrollUpItem scrollUpItem = new ScrollUpItem(playerLanguage);
|
||||||
|
final ScrollDownItem scrollDownItem = new ScrollDownItem(playerLanguage);
|
||||||
|
|
||||||
|
final FavoriteAddItem favoriteAddItem = new FavoriteAddItem(player);
|
||||||
|
final FavoriteRemoveItem favoriteRemoveItem = new FavoriteRemoveItem(playerLanguage);
|
||||||
|
|
||||||
|
final NickoProfile profile = Nicko.getInstance().getDataStore().getData(player.getUniqueId()).orElse(NickoProfile.EMPTY_PROFILE);
|
||||||
|
final List<Appearance> favorites = profile.getFavorites();
|
||||||
|
List<Item> items;
|
||||||
|
|
||||||
|
if (favorites == null || favorites.isEmpty()) {
|
||||||
|
items = Collections.emptyList();
|
||||||
|
} else {
|
||||||
|
items = favorites.stream()
|
||||||
|
.map((appearance) -> new FavoriteAppearanceEntryItem(player, appearance).get())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
gui = ScrollGui.items(guiItemBuilder -> {
|
||||||
|
guiItemBuilder.setStructure(
|
||||||
|
"x x x x x x x x U",
|
||||||
|
"x x x x x x x x #",
|
||||||
|
"x x x x x x x x #",
|
||||||
|
"x x x x x x x x #",
|
||||||
|
"x x x x x x x x D",
|
||||||
|
"% % % A B R % % %");
|
||||||
|
guiItemBuilder.addIngredient('x', Markers.CONTENT_LIST_SLOT_HORIZONTAL);
|
||||||
|
guiItemBuilder.addIngredient('U', scrollUpItem);
|
||||||
|
guiItemBuilder.addIngredient('D', scrollDownItem);
|
||||||
|
guiItemBuilder.addIngredient('B', backItem.get(parent.getGUI(), parent.getTitle()));
|
||||||
|
guiItemBuilder.addIngredient('A', favoriteAddItem.get());
|
||||||
|
guiItemBuilder.addIngredient('R', favoriteRemoveItem.get());
|
||||||
|
guiItemBuilder.setContent(items);
|
||||||
|
});
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Gui getGUI() {
|
||||||
|
return gui;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void open() {
|
||||||
|
Window.single().setGui(gui).setTitle(title).open(player);
|
||||||
|
}
|
||||||
|
}
|
67
src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java
Normal file
67
src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
package xyz.ineanto.nicko.gui;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import xyz.ineanto.nicko.gui.items.appearance.ChangeBothItem;
|
||||||
|
import xyz.ineanto.nicko.gui.items.appearance.ChangeNameItem;
|
||||||
|
import xyz.ineanto.nicko.gui.items.appearance.ChangeSkinItem;
|
||||||
|
import xyz.ineanto.nicko.gui.items.home.*;
|
||||||
|
import xyz.ineanto.nicko.language.PlayerLanguage;
|
||||||
|
import xyz.ineanto.nicko.language.LanguageKey;
|
||||||
|
import xyz.xenondevs.invui.gui.Gui;
|
||||||
|
import xyz.xenondevs.invui.window.Window;
|
||||||
|
|
||||||
|
public class HomeGUI {
|
||||||
|
private final Player player;
|
||||||
|
private final Gui gui;
|
||||||
|
private final String title;
|
||||||
|
|
||||||
|
public HomeGUI(Player player) {
|
||||||
|
final String[] dynamicStructure = new String[]{
|
||||||
|
"# # # # D # # # #",
|
||||||
|
"A # # N B S # # #",
|
||||||
|
"E P # # F # # # R"};
|
||||||
|
|
||||||
|
if (!player.isOp() || !player.hasPermission("nicko.admin")) {
|
||||||
|
dynamicStructure[2] = dynamicStructure[2].replace("A", "#");
|
||||||
|
}
|
||||||
|
|
||||||
|
final PlayerLanguage playerLanguage = new PlayerLanguage(player);
|
||||||
|
this.title = playerLanguage.translate(LanguageKey.GUI.Titles.HOME, false);
|
||||||
|
|
||||||
|
final ExitItem exitItem = new ExitItem(player);
|
||||||
|
final ResetItem resetItem = new ResetItem(player);
|
||||||
|
final ChangeNameItem changeNameItem = new ChangeNameItem(player);
|
||||||
|
final ChangeBothItem changeBothItem = new ChangeBothItem(player);
|
||||||
|
final ChangeSkinItem changeSkinItem = new ChangeSkinItem(player);
|
||||||
|
final SettingsAccessItem settingsAccessItem = new SettingsAccessItem(player);
|
||||||
|
final AdminAccessItem adminAccessItem = new AdminAccessItem(player);
|
||||||
|
final RandomSkinItem randomSkinItem = new RandomSkinItem(player);
|
||||||
|
final FavoritesItem favoritesItem = new FavoritesItem(player);
|
||||||
|
|
||||||
|
this.gui = Gui.normal()
|
||||||
|
.setStructure(dynamicStructure)
|
||||||
|
.addIngredient('E', exitItem.get())
|
||||||
|
.addIngredient('R', resetItem.get())
|
||||||
|
.addIngredient('N', changeNameItem.get())
|
||||||
|
.addIngredient('B', changeBothItem.get())
|
||||||
|
.addIngredient('S', changeSkinItem.get())
|
||||||
|
.addIngredient('P', settingsAccessItem.get())
|
||||||
|
.addIngredient('A', adminAccessItem.get())
|
||||||
|
.addIngredient('D', randomSkinItem.get())
|
||||||
|
.addIngredient('F', favoritesItem.get())
|
||||||
|
.build();
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Gui getGUI() {
|
||||||
|
return gui;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void open() {
|
||||||
|
Window.single().setGui(gui).setTitle(title).open(player);
|
||||||
|
}
|
||||||
|
}
|
69
src/main/java/xyz/ineanto/nicko/gui/InvalidateSkinGUI.java
Normal file
69
src/main/java/xyz/ineanto/nicko/gui/InvalidateSkinGUI.java
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
package xyz.ineanto.nicko.gui;
|
||||||
|
|
||||||
|
import xyz.ineanto.nicko.gui.items.common.GoBackItem;
|
||||||
|
import xyz.ineanto.nicko.gui.items.common.ScrollUpItem;
|
||||||
|
import xyz.ineanto.nicko.language.PlayerLanguage;
|
||||||
|
import xyz.ineanto.nicko.language.LanguageKey;
|
||||||
|
import xyz.ineanto.nicko.mojang.MojangSkin;
|
||||||
|
import xyz.xenondevs.invui.gui.Gui;
|
||||||
|
import xyz.xenondevs.invui.gui.ScrollGui;
|
||||||
|
import xyz.xenondevs.invui.gui.structure.Markers;
|
||||||
|
import xyz.xenondevs.invui.item.Item;
|
||||||
|
import xyz.ineanto.nicko.Nicko;
|
||||||
|
import xyz.ineanto.nicko.gui.items.admin.cache.CacheEntryItem;
|
||||||
|
import xyz.ineanto.nicko.gui.items.common.ScrollDownItem;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import xyz.xenondevs.invui.window.Window;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class InvalidateSkinGUI {
|
||||||
|
private final Player player;
|
||||||
|
private final Gui gui;
|
||||||
|
private final String title;
|
||||||
|
|
||||||
|
public InvalidateSkinGUI(Player player) {
|
||||||
|
final PlayerLanguage playerLanguage = new PlayerLanguage(player);
|
||||||
|
this.title = playerLanguage.translate(LanguageKey.GUI.Titles.INVALIDATE_SKIN, false);
|
||||||
|
|
||||||
|
final ConcurrentMap<String, Optional<MojangSkin>> skins = Nicko.getInstance().getMojangAPI().getSkinCache().asMap();
|
||||||
|
final List<String> loadedSkins = skins.entrySet().stream()
|
||||||
|
.filter(entry -> entry.getValue().isPresent())
|
||||||
|
.map(Map.Entry::getKey)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
final List<Item> items = loadedSkins.stream()
|
||||||
|
.map(uuid -> new CacheEntryItem(playerLanguage, uuid))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
final CacheManagementGUI parent = new CacheManagementGUI(player);
|
||||||
|
final ScrollUpItem scrollUpItem = new ScrollUpItem(playerLanguage);
|
||||||
|
final ScrollDownItem scrollDownItem = new ScrollDownItem(playerLanguage);
|
||||||
|
final GoBackItem backItem = new GoBackItem(player);
|
||||||
|
|
||||||
|
gui = ScrollGui.items(guiItemBuilder -> {
|
||||||
|
guiItemBuilder.setStructure(
|
||||||
|
"x x x x x x x x U",
|
||||||
|
"x x x x x x x x #",
|
||||||
|
"x x x x x x x x #",
|
||||||
|
"x x x x x x x x #",
|
||||||
|
"x x x x x x x x D",
|
||||||
|
"B % % % % % % % %");
|
||||||
|
guiItemBuilder.addIngredient('x', Markers.CONTENT_LIST_SLOT_HORIZONTAL);
|
||||||
|
guiItemBuilder.addIngredient('U', scrollUpItem);
|
||||||
|
guiItemBuilder.addIngredient('D', scrollDownItem);
|
||||||
|
guiItemBuilder.addIngredient('B', backItem.get(parent.getGUI(), parent.getTitle()));
|
||||||
|
guiItemBuilder.setContent(items);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void open() {
|
||||||
|
Window.single().setGui(gui).setTitle(title).open(player);
|
||||||
|
}
|
||||||
|
}
|
68
src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java
Normal file
68
src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
package xyz.ineanto.nicko.gui;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import xyz.ineanto.nicko.gui.items.admin.check.PlayerInformationItem;
|
||||||
|
import xyz.ineanto.nicko.gui.items.common.GoBackItem;
|
||||||
|
import xyz.ineanto.nicko.gui.items.common.ScrollDownItem;
|
||||||
|
import xyz.ineanto.nicko.gui.items.common.ScrollUpItem;
|
||||||
|
import xyz.ineanto.nicko.language.PlayerLanguage;
|
||||||
|
import xyz.ineanto.nicko.language.LanguageKey;
|
||||||
|
import xyz.xenondevs.invui.gui.Gui;
|
||||||
|
import xyz.xenondevs.invui.gui.ScrollGui;
|
||||||
|
import xyz.xenondevs.invui.gui.structure.Markers;
|
||||||
|
import xyz.xenondevs.invui.item.Item;
|
||||||
|
import xyz.xenondevs.invui.window.Window;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class PlayerCheckGUI {
|
||||||
|
private final Player player;
|
||||||
|
private final Gui gui;
|
||||||
|
private final String title;
|
||||||
|
|
||||||
|
public PlayerCheckGUI(Player player, Collection<? extends Player> players) {
|
||||||
|
final PlayerLanguage playerLanguage = new PlayerLanguage(player);
|
||||||
|
this.title = playerLanguage.translate(LanguageKey.GUI.Titles.CHECK, false);
|
||||||
|
|
||||||
|
final List<Item> items = players.stream()
|
||||||
|
.map(Entity::getUniqueId)
|
||||||
|
.map(Bukkit::getPlayer)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.map(mappedPlayer -> new PlayerInformationItem(playerLanguage, mappedPlayer))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
final AdminGUI parent = new AdminGUI(player);
|
||||||
|
final GoBackItem backItem = new GoBackItem(player);
|
||||||
|
final ScrollUpItem scrollUpItem = new ScrollUpItem(playerLanguage);
|
||||||
|
final ScrollDownItem scrollDownItem = new ScrollDownItem(playerLanguage);
|
||||||
|
|
||||||
|
gui = ScrollGui.items(guiItemBuilder -> {
|
||||||
|
guiItemBuilder.setStructure(
|
||||||
|
"x x x x x x x x U",
|
||||||
|
"x x x x x x x x #",
|
||||||
|
"x x x x x x x x #",
|
||||||
|
"x x x x x x x x #",
|
||||||
|
"x x x x x x x x D",
|
||||||
|
"B % % % % % % % %");
|
||||||
|
guiItemBuilder.addIngredient('x', Markers.CONTENT_LIST_SLOT_HORIZONTAL);
|
||||||
|
guiItemBuilder.addIngredient('U', scrollUpItem);
|
||||||
|
guiItemBuilder.addIngredient('D', scrollDownItem);
|
||||||
|
guiItemBuilder.addIngredient('B', backItem.get(parent.getGUI(), parent.getTitle()));
|
||||||
|
guiItemBuilder.setContent(items);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void open() {
|
||||||
|
final Window.Builder.Normal.Single window = Window.single().setGui(gui).setTitle(title);
|
||||||
|
window.addOpenHandler(() -> PlayerCheckGUIData.VIEWERS.add(player.getUniqueId()));
|
||||||
|
window.addCloseHandler(() -> PlayerCheckGUIData.VIEWERS.remove(player.getUniqueId()));
|
||||||
|
window.open(player);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package xyz.ineanto.nicko.gui;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class PlayerCheckGUIData {
|
||||||
|
public static final ArrayList<UUID> VIEWERS = new ArrayList<>();
|
||||||
|
}
|
44
src/main/java/xyz/ineanto/nicko/gui/SettingsGUI.java
Normal file
44
src/main/java/xyz/ineanto/nicko/gui/SettingsGUI.java
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
package xyz.ineanto.nicko.gui;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import xyz.ineanto.nicko.gui.items.common.GoBackItem;
|
||||||
|
import xyz.ineanto.nicko.gui.items.settings.LanguageCyclingItem;
|
||||||
|
import xyz.ineanto.nicko.gui.items.settings.RandomSkinCyclingItem;
|
||||||
|
import xyz.ineanto.nicko.language.PlayerLanguage;
|
||||||
|
import xyz.ineanto.nicko.language.LanguageKey;
|
||||||
|
import xyz.xenondevs.invui.gui.Gui;
|
||||||
|
import xyz.xenondevs.invui.window.Window;
|
||||||
|
|
||||||
|
public class SettingsGUI {
|
||||||
|
private final Player player;
|
||||||
|
private final Gui gui;
|
||||||
|
private final String title;
|
||||||
|
|
||||||
|
public SettingsGUI(Player player) {
|
||||||
|
final String[] dynamicStructure = new String[]{
|
||||||
|
"# # # # # # # # #",
|
||||||
|
"# # # L # R # # #",
|
||||||
|
"B # # # # # # # #"
|
||||||
|
};
|
||||||
|
|
||||||
|
final PlayerLanguage playerLanguage = new PlayerLanguage(player);
|
||||||
|
this.title = playerLanguage.translate(LanguageKey.GUI.Titles.SETTINGS, false);
|
||||||
|
|
||||||
|
final HomeGUI parent = new HomeGUI(player);
|
||||||
|
final LanguageCyclingItem languageItem = new LanguageCyclingItem(player);
|
||||||
|
final RandomSkinCyclingItem skinItem = new RandomSkinCyclingItem(player);
|
||||||
|
final GoBackItem backItem = new GoBackItem(player);
|
||||||
|
|
||||||
|
this.gui = Gui.normal()
|
||||||
|
.setStructure(dynamicStructure)
|
||||||
|
.addIngredient('B', backItem.get(parent.getGUI(), parent.getTitle()))
|
||||||
|
.addIngredient('L', languageItem.get())
|
||||||
|
.addIngredient('R', skinItem.get())
|
||||||
|
.build();
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void open() {
|
||||||
|
Window.single().setGui(gui).setTitle(title).open(player);
|
||||||
|
}
|
||||||
|
}
|
22
src/main/java/xyz/ineanto/nicko/gui/items/ItemDefaults.java
Normal file
22
src/main/java/xyz/ineanto/nicko/gui/items/ItemDefaults.java
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
package xyz.ineanto.nicko.gui.items;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import xyz.ineanto.nicko.language.PlayerLanguage;
|
||||||
|
import xyz.ineanto.nicko.language.LanguageKey;
|
||||||
|
import xyz.xenondevs.invui.item.builder.AbstractItemBuilder;
|
||||||
|
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
||||||
|
import xyz.xenondevs.invui.item.builder.SkullBuilder;
|
||||||
|
|
||||||
|
public class ItemDefaults {
|
||||||
|
public static AbstractItemBuilder<?> getErrorSkullItem(PlayerLanguage playerLanguage, String key, Object... args) {
|
||||||
|
// "Missing Value" (Valve's signature missing texture) Texture Value
|
||||||
|
final SkullBuilder.HeadTexture headTexture = new SkullBuilder.HeadTexture("eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNjNmZTU5YjJhMWQyYmYzMjcwNDA2OGVmYzg2MGM3NWY5MjEyYzIzMTBiNDNkMDdjNGJiYTRiNGViMjM0ZTY4NCJ9fX0=");
|
||||||
|
final SkullBuilder builder = new SkullBuilder(headTexture);
|
||||||
|
return playerLanguage.translateItem(builder, key, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AbstractItemBuilder<?> getUnavailableItem(PlayerLanguage playerLanguage) {
|
||||||
|
final ItemBuilder builder = new ItemBuilder(Material.RED_TERRACOTTA);
|
||||||
|
return playerLanguage.translateItem(builder, LanguageKey.GUI.UNAVAILABLE);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package xyz.ineanto.nicko.gui.items.admin;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.inventory.ClickType;
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import xyz.ineanto.nicko.gui.CacheManagementGUI;
|
||||||
|
import xyz.ineanto.nicko.language.LanguageKey;
|
||||||
|
import xyz.ineanto.nicko.language.PlayerLanguage;
|
||||||
|
import xyz.xenondevs.invui.item.builder.AbstractItemBuilder;
|
||||||
|
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
||||||
|
import xyz.xenondevs.invui.item.builder.SkullBuilder;
|
||||||
|
import xyz.xenondevs.invui.item.impl.AsyncItem;
|
||||||
|
import xyz.xenondevs.invui.item.impl.SuppliedItem;
|
||||||
|
import xyz.xenondevs.invui.util.MojangApiUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class ManageCacheItem extends AsyncItem {
|
||||||
|
public ManageCacheItem(PlayerLanguage playerLanguage) {
|
||||||
|
super(new SuppliedItem(() -> {
|
||||||
|
final ItemBuilder builder = new ItemBuilder(Material.PAINTING);
|
||||||
|
return playerLanguage.translateItem(builder, LanguageKey.GUI.LOADING);
|
||||||
|
}, (_ -> true)).getItemProvider(),
|
||||||
|
() -> {
|
||||||
|
AbstractItemBuilder<?> builder;
|
||||||
|
|
||||||
|
try {
|
||||||
|
builder = new SkullBuilder("Notch");
|
||||||
|
} catch (MojangApiUtils.MojangApiException | IOException e) {
|
||||||
|
builder = new ItemBuilder(Material.PLAYER_HEAD);
|
||||||
|
}
|
||||||
|
|
||||||
|
return playerLanguage.translateItem(builder, LanguageKey.GUI.Admin.MANAGE_CACHE);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {
|
||||||
|
if (clickType.isLeftClick() || clickType.isRightClick()) {
|
||||||
|
event.getView().close();
|
||||||
|
new CacheManagementGUI(player).open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package xyz.ineanto.nicko.gui.items.admin;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import xyz.ineanto.nicko.gui.PlayerCheckGUI;
|
||||||
|
import xyz.ineanto.nicko.language.PlayerLanguage;
|
||||||
|
import xyz.ineanto.nicko.language.LanguageKey;
|
||||||
|
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
||||||
|
import xyz.xenondevs.invui.item.impl.SuppliedItem;
|
||||||
|
|
||||||
|
public class ManagePlayerItem {
|
||||||
|
private final Player player;
|
||||||
|
private final PlayerLanguage playerLanguage;
|
||||||
|
|
||||||
|
public ManagePlayerItem(PlayerLanguage playerLanguage, Player player) {
|
||||||
|
this.playerLanguage = playerLanguage;
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SuppliedItem get() {
|
||||||
|
return new SuppliedItem(() -> {
|
||||||
|
final ItemBuilder builder = new ItemBuilder(Material.WRITABLE_BOOK);
|
||||||
|
return playerLanguage.translateItem(builder, LanguageKey.GUI.Admin.MANAGE_PLAYER);
|
||||||
|
}, _ -> {
|
||||||
|
new PlayerCheckGUI(player, Bukkit.getOnlinePlayers()).open();
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
72
src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java
vendored
Normal file
72
src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java
vendored
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
package xyz.ineanto.nicko.gui.items.admin.cache;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.inventory.ClickType;
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import xyz.ineanto.nicko.Nicko;
|
||||||
|
import xyz.ineanto.nicko.gui.ChoiceGUI;
|
||||||
|
import xyz.ineanto.nicko.gui.InvalidateSkinGUI;
|
||||||
|
import xyz.ineanto.nicko.gui.items.ItemDefaults;
|
||||||
|
import xyz.ineanto.nicko.gui.items.common.choice.ChoiceCallback;
|
||||||
|
import xyz.ineanto.nicko.language.LanguageKey;
|
||||||
|
import xyz.ineanto.nicko.language.PlayerLanguage;
|
||||||
|
import xyz.ineanto.nicko.mojang.MojangAPI;
|
||||||
|
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
||||||
|
import xyz.xenondevs.invui.item.builder.SkullBuilder;
|
||||||
|
import xyz.xenondevs.invui.item.impl.AsyncItem;
|
||||||
|
import xyz.xenondevs.invui.item.impl.SuppliedItem;
|
||||||
|
import xyz.xenondevs.invui.util.MojangApiUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class CacheEntryItem extends AsyncItem {
|
||||||
|
private final String name;
|
||||||
|
private final String uuid;
|
||||||
|
private final MojangAPI mojangAPI = Nicko.getInstance().getMojangAPI();
|
||||||
|
private final PlayerLanguage playerLanguage;
|
||||||
|
|
||||||
|
public CacheEntryItem(PlayerLanguage playerLanguage, String uuid) {
|
||||||
|
super(new SuppliedItem(() -> {
|
||||||
|
final ItemBuilder builder = new ItemBuilder(Material.PAINTING);
|
||||||
|
return playerLanguage.translateItem(builder, LanguageKey.GUI.LOADING);
|
||||||
|
}, (_ -> true)).getItemProvider(),
|
||||||
|
() -> {
|
||||||
|
final String dashedUuid = uuid.replaceAll("(.{8})(.{4})(.{4})(.{4})(.+)", "$1-$2-$3-$4-$5");
|
||||||
|
final UUID uuidObject = UUID.fromString(dashedUuid);
|
||||||
|
try {
|
||||||
|
final SkullBuilder skull = new SkullBuilder(uuidObject);
|
||||||
|
return playerLanguage.translateItem(skull, LanguageKey.GUI.Admin.Cache.ENTRY, Nicko.getInstance().getMojangAPI().getUUIDName(uuid));
|
||||||
|
} catch (MojangApiUtils.MojangApiException | IOException e) {
|
||||||
|
Nicko.getInstance().getLogger().warning("Unable to get Head texture for specified UUID (" + uuid + ")! (GUI/Cache/Entry)");
|
||||||
|
return ItemDefaults.getErrorSkullItem(playerLanguage, LanguageKey.GUI.Admin.Cache.ENTRY, Nicko.getInstance().getMojangAPI().getUUIDName(uuid));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.playerLanguage = playerLanguage;
|
||||||
|
this.uuid = uuid;
|
||||||
|
this.name = mojangAPI.getUUIDName(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleClick(@NotNull ClickType click, @NotNull Player player, @NotNull InventoryClickEvent event) {
|
||||||
|
if (click.isLeftClick() || click.isRightClick()) {
|
||||||
|
event.getView().close();
|
||||||
|
new ChoiceGUI(player, new ChoiceCallback() {
|
||||||
|
@Override
|
||||||
|
public void onConfirm() {
|
||||||
|
player.sendMessage(playerLanguage.translate(LanguageKey.Event.Admin.Cache.INVALIDATE_ENTRY, true, name));
|
||||||
|
player.playSound(player.getLocation(), Sound.BLOCK_WOODEN_BUTTON_CLICK_ON, 1, 1f);
|
||||||
|
mojangAPI.eraseFromCache(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancel() {
|
||||||
|
new InvalidateSkinGUI(player).open();
|
||||||
|
}
|
||||||
|
}).open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
35
src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheStatisticsItem.java
vendored
Normal file
35
src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheStatisticsItem.java
vendored
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
package xyz.ineanto.nicko.gui.items.admin.cache;
|
||||||
|
|
||||||
|
import com.google.common.cache.CacheStats;
|
||||||
|
import com.google.common.cache.LoadingCache;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import xyz.ineanto.nicko.Nicko;
|
||||||
|
import xyz.ineanto.nicko.language.PlayerLanguage;
|
||||||
|
import xyz.ineanto.nicko.language.LanguageKey;
|
||||||
|
import xyz.ineanto.nicko.mojang.MojangSkin;
|
||||||
|
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
||||||
|
import xyz.xenondevs.invui.item.impl.SuppliedItem;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class CacheStatisticsItem {
|
||||||
|
private final PlayerLanguage playerLanguage;
|
||||||
|
|
||||||
|
public CacheStatisticsItem(Player player) {
|
||||||
|
this.playerLanguage = new PlayerLanguage(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SuppliedItem get() {
|
||||||
|
return new SuppliedItem(() -> {
|
||||||
|
final ItemBuilder builder = new ItemBuilder(Material.BOOK);
|
||||||
|
final LoadingCache<String, Optional<MojangSkin>> cache = Nicko.getInstance().getMojangAPI().getSkinCache();
|
||||||
|
final CacheStats stats = cache.stats();
|
||||||
|
|
||||||
|
return playerLanguage.translateItem(builder, LanguageKey.GUI.Admin.Cache.STATISTICS,
|
||||||
|
stats.requestCount(),
|
||||||
|
Math.round(cache.size())
|
||||||
|
);
|
||||||
|
}, (event) -> true);
|
||||||
|
}
|
||||||
|
}
|
39
src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java
vendored
Normal file
39
src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java
vendored
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
package xyz.ineanto.nicko.gui.items.admin.cache;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.inventory.ClickType;
|
||||||
|
import xyz.ineanto.nicko.Nicko;
|
||||||
|
import xyz.ineanto.nicko.language.PlayerLanguage;
|
||||||
|
import xyz.ineanto.nicko.language.LanguageKey;
|
||||||
|
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
||||||
|
import xyz.xenondevs.invui.item.impl.SuppliedItem;
|
||||||
|
|
||||||
|
public class InvalidateCacheItem {
|
||||||
|
private final PlayerLanguage playerLanguage;
|
||||||
|
|
||||||
|
public InvalidateCacheItem(Player player) {
|
||||||
|
this.playerLanguage = new PlayerLanguage(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SuppliedItem get() {
|
||||||
|
return new SuppliedItem(() -> {
|
||||||
|
final ItemBuilder builder = new ItemBuilder(Material.TNT);
|
||||||
|
return playerLanguage.translateItem(builder, LanguageKey.GUI.Admin.Cache.INVALIDATE_CACHE);
|
||||||
|
}, (click) -> {
|
||||||
|
final ClickType clickType = click.getClickType();
|
||||||
|
if (clickType.isLeftClick() || clickType.isRightClick()) {
|
||||||
|
click.getEvent().getView().close();
|
||||||
|
|
||||||
|
final Player player = click.getPlayer();
|
||||||
|
final PlayerLanguage playerLanguage = new PlayerLanguage(player);
|
||||||
|
player.sendMessage(playerLanguage.translateWithWhoosh(LanguageKey.Event.Admin.Cache.INVALIDATE_CACHE));
|
||||||
|
player.playSound(player.getLocation(), Sound.BLOCK_WOODEN_BUTTON_CLICK_ON, 1, 1f);
|
||||||
|
Nicko.getInstance().getMojangAPI().getSkinCache().invalidateAll();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
33
src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateSkinItem.java
vendored
Normal file
33
src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateSkinItem.java
vendored
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
package xyz.ineanto.nicko.gui.items.admin.cache;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.inventory.ClickType;
|
||||||
|
import xyz.ineanto.nicko.gui.InvalidateSkinGUI;
|
||||||
|
import xyz.ineanto.nicko.language.PlayerLanguage;
|
||||||
|
import xyz.ineanto.nicko.language.LanguageKey;
|
||||||
|
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
||||||
|
import xyz.xenondevs.invui.item.impl.SuppliedItem;
|
||||||
|
|
||||||
|
public class InvalidateSkinItem {
|
||||||
|
private final PlayerLanguage playerLanguage;
|
||||||
|
|
||||||
|
public InvalidateSkinItem(Player player) {
|
||||||
|
this.playerLanguage = new PlayerLanguage(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SuppliedItem get() {
|
||||||
|
return new SuppliedItem(() -> {
|
||||||
|
final ItemBuilder builder = new ItemBuilder(Material.PAPER);
|
||||||
|
return playerLanguage.translateItem(builder, LanguageKey.GUI.Admin.Cache.INVALIDATE_SKIN);
|
||||||
|
}, (click) -> {
|
||||||
|
final ClickType clickType = click.getClickType();
|
||||||
|
if (clickType.isLeftClick() || clickType.isRightClick()) {
|
||||||
|
click.getEvent().getView().close();
|
||||||
|
new InvalidateSkinGUI(click.getPlayer()).open();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue