Compare commits
244 Commits
Author | SHA1 | Date |
---|---|---|
ME1312 | d1cb53e0f5 | |
ME1312 | 903b8a98d3 | |
ME1312 | f7f42c8ba9 | |
ME1312 | ad24b0deb3 | |
ME1312 | 78f50e77b2 | |
ME1312 | c511ded3d4 | |
ME1312 | b5cddeb892 | |
ME1312 | 7d9fabd2b9 | |
ME1312 | b23aa18661 | |
ME1312 | ba80e0a16a | |
ME1312 | ecf76a97de | |
ME1312 | 01456fd964 | |
ME1312 | c90dbc8e3f | |
ME1312 | e02093ab2f | |
ME1312 | 8a5a0cdc4b | |
ME1312 | cf07e86a09 | |
ME1312 | d8463e25c5 | |
ME1312 | cb6d30c882 | |
ME1312 | c5377f7f13 | |
ME1312 | 36f2821524 | |
ME1312 | 41dd2d69d0 | |
ME1312 | 307ac43df0 | |
ME1312 | 1521acfc51 | |
ME1312 | ce262c62f0 | |
ME1312 | e4300e76e2 | |
ME1312 | 7d9de9bf6e | |
ME1312 | 249b0a4fab | |
ME1312 | 6fc8732003 | |
ME1312 | b7c89d26d5 | |
ME1312 | a4d9f46084 | |
ME1312 | 58ae08db1e | |
ME1312 | f6ce5c92fb | |
ME1312 | 7433fc04a8 | |
ME1312 | 5454590874 | |
ME1312 | 3e78536d08 | |
ME1312 | 8a18b6f5d1 | |
ME1312 | c5573801c4 | |
ME1312 | 80d2557631 | |
ME1312 | 9999cbe39e | |
ME1312 | 6d457200fe | |
ME1312 | 0c5a89608b | |
ME1312 | 7d9f4f86d3 | |
ME1312 | 508c2f7627 | |
ME1312 | 7179911d4c | |
ME1312 | aef7a164e6 | |
ME1312 | a0b8df47ac | |
ME1312 | c137906fcd | |
ME1312 | 92151d75d0 | |
ME1312 | 86471491bd | |
ME1312 | 3e074e365d | |
ME1312 | 16c373b336 | |
ME1312 | 5d3664cbc7 | |
ME1312 | a3896eccd4 | |
ME1312 | 594ba30c64 | |
ME1312 | 9bf1bb0710 | |
ME1312 | 6890b94b16 | |
ME1312 | 52fd155b5f | |
ME1312 | 16b170df1e | |
ME1312 | 5263f9d018 | |
ME1312 | ef1c593607 | |
ME1312 | 394c4b238b | |
ME1312 | ee82ec32a3 | |
ME1312 | 1427ff04e1 | |
ME1312 | d3f3f194d0 | |
ME1312 | 668fccccfe | |
ME1312 | a86571a136 | |
ME1312 | 9c54dfd2b4 | |
ME1312 | 81d2d8b14e | |
ME1312 | 1533987bf5 | |
ME1312 | ff709ba314 | |
ME1312 | dfabbcf4ad | |
ME1312 | 0a6fdb337f | |
ME1312 | 1fff679005 | |
ME1312 | 7d6396ec1c | |
ME1312 | 517074f2b3 | |
ME1312 | 2c7175e558 | |
ME1312 | f5a3575e54 | |
ME1312 | 89f2d646a5 | |
ME1312 | 2a9c74f601 | |
ME1312 | 910b504af8 | |
ME1312 | de0e9a676d | |
ME1312 | b6a66cfb3b | |
ME1312 | 51e83f4fb0 | |
ME1312 | 34c9effa6f | |
ME1312 | bb592da15b | |
ME1312 | f5c8ade961 | |
ME1312 | b707f2cc0c | |
ME1312 | ba6af4d66d | |
ME1312 | ee59429e1d | |
ME1312 | b2b80036d7 | |
ME1312 | 4d081f6e4f | |
ME1312 | e1de6636f0 | |
ME1312 | 42a73c8372 | |
ME1312 | c6a354fe84 | |
ME1312 | 6258256081 | |
ME1312 | ce38355c91 | |
ME1312 | d0177ce055 | |
ME1312 | 5898371780 | |
ME1312 | 0ac4238dc8 | |
ME1312 | 18953046b8 | |
ME1312 | ff82fd5151 | |
ME1312 | eba5e6a7d1 | |
ME1312 | 746c51e8fa | |
ME1312 | 23a434054f | |
ME1312 | b188f0d4af | |
ME1312 | a9b0afb40a | |
ME1312 | a992ec7c52 | |
ME1312 | 620db38e9b | |
ME1312 | 1c010ea9b2 | |
ME1312 | 98e487b44e | |
ME1312 | 15a4f109a4 | |
ME1312 | 2beec3ae7a | |
ME1312 | f90a54e636 | |
ME1312 | 59d3404abf | |
ME1312 | 91fe4e74ed | |
ME1312 | 811d65b68a | |
ME1312 | 5732237477 | |
ME1312 | d244e6a5b7 | |
ME1312 | 2cb783326a | |
ME1312 | 76e11f0a0d | |
ME1312 | 4e66461848 | |
ME1312 | 3dea3b67d0 | |
ME1312 | 25fff82af6 | |
ME1312 | e090815b37 | |
ME1312 | b0340b498e | |
ME1312 | 6d32f1b6a0 | |
ME1312 | bfff48a9ec | |
ME1312 | 4debf94fd6 | |
ME1312 | 2c29182ca5 | |
ME1312 | 9af8dd02ce | |
ME1312 | ea9eec9aa8 | |
ME1312 | 08b56fc823 | |
ME1312 | fe4f19e713 | |
ME1312 | c261be2215 | |
ME1312 | 2841bdf061 | |
ME1312 | bcd7f4f3c3 | |
ME1312 | 80da5f7b27 | |
ME1312 | 4ea69298a3 | |
ME1312 | 4cfe1b4285 | |
ME1312 | 20ab75530a | |
ME1312 | 8d21771857 | |
ME1312 | c0197759f4 | |
ME1312 | 34b406e3ae | |
ME1312 | 96a3cf797e | |
ME1312 | c62363bdef | |
ME1312 | 489b25f48d | |
ME1312 | 0136419960 | |
ME1312 | 29dbd107c0 | |
ME1312 | fa82e0ab96 | |
ME1312 | d3e6d3e579 | |
ME1312 | 6e60138a79 | |
ME1312 | e9c0075144 | |
ME1312 | fa77eeeab0 | |
ME1312 | 443e3c2d44 | |
ME1312 | d43aae8486 | |
ME1312 | b68fa0fec1 | |
ME1312 | 26490dc140 | |
ME1312 | b18f047d53 | |
ME1312 | 83041a1f3f | |
ME1312 | efc12e0649 | |
ME1312 | 891913dbe3 | |
ME1312 | f2f196dc79 | |
ME1312 | fcc87117dd | |
ME1312 | 2975ab05f4 | |
ME1312 | 0d052e0774 | |
ME1312 | dacb3aa541 | |
ME1312 | 5ad6b49de7 | |
ME1312 | 69fad5221c | |
ME1312 | 1564eaaaf9 | |
ME1312 | db8aff55f6 | |
ME1312 | ec2d75d0f6 | |
ME1312 | d76d0347e5 | |
ME1312 | 928c40addc | |
ME1312 | 312d010585 | |
ME1312 | d8ea0cee66 | |
ME1312 | 89856a19b8 | |
ME1312 | 0812ff3ade | |
ME1312 | 0e8bae4187 | |
ME1312 | 3fc249cf07 | |
ME1312 | 9d01f46c16 | |
ME1312 | bb0dd55c95 | |
ME1312 | caf8ee793d | |
ME1312 | 65a5b7d0c9 | |
ME1312 | d2c7512257 | |
ME1312 | 4ba0489d9d | |
ME1312 | bb975413a5 | |
ME1312 | 207393cfec | |
ME1312 | 11f92f2559 | |
ME1312 | 7a4d28b113 | |
ME1312 | d39d875e2b | |
ME1312 | eb8261531d | |
ME1312 | 6e116763c1 | |
ME1312 | 51d3c31220 | |
ME1312 | 73c402fc53 | |
ME1312 | 35c80bba80 | |
ME1312 | 611b59f2c8 | |
ME1312 | bfcb076cfd | |
ME1312 | b7639ae3dc | |
ME1312 | a5c5a532a0 | |
ME1312 | 27806b91f9 | |
ME1312 | 17b63c1e6e | |
ME1312 | bccbfb39c9 | |
ME1312 | 81d37b8b1e | |
ME1312 | 3ff2459258 | |
ME1312 | c6d611836c | |
ME1312 | 0e19122d9c | |
ME1312 | 30dd28547f | |
ME1312 | ecdc25b520 | |
ME1312 | 9dedc3b90d | |
ME1312 | 3af2087f19 | |
ME1312 | 03ece299d3 | |
ME1312 | be8f87d17c | |
ME1312 | 96a0624b28 | |
ME1312 | 071e0bceab | |
ME1312 | 08e3e202e3 | |
ME1312 | 49036b8943 | |
ME1312 | 8514ea5c26 | |
ME1312 | b808a62fcb | |
ME1312 | 463ae054a6 | |
ME1312 | 185b6b84bb | |
ME1312 | 61ee89cfe3 | |
ME1312 | 9ef878ba12 | |
ME1312 | 7059b5cad7 | |
ME1312 | 2a939117ac | |
ME1312 | 504dc7bac4 | |
ME1312 | 1952e7b940 | |
ME1312 | 4923b7111f | |
ME1312 | f8d597f513 | |
ME1312 | 776183510e | |
ME1312 | 472c83f975 | |
ME1312 | df029e3a7e | |
ME1312 | 7f23668623 | |
ME1312 | 2c41c40213 | |
ME1312 | 09c8c4665b | |
ME1312 | 6debb5b605 | |
ME1312 | 3dab84c0eb | |
ME1312 | 463861744c | |
ME1312 | 935a59bb34 | |
ME1312 | afa34f4993 | |
ME1312 | d81e93b583 | |
ME1312 | 2bf26a1b74 | |
ME1312 | 6131790245 | |
ME1312 | 024dde444c | |
ME1312 | 975a12f3b6 |
|
@ -1,63 +0,0 @@
|
||||||
###############################################################################
|
|
||||||
# Set default behavior to automatically normalize line endings.
|
|
||||||
###############################################################################
|
|
||||||
* text=auto
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# Set default behavior for command prompt diff.
|
|
||||||
#
|
|
||||||
# This is need for earlier builds of msysgit that does not have it on by
|
|
||||||
# default for csharp files.
|
|
||||||
# Note: This is only used by command line
|
|
||||||
###############################################################################
|
|
||||||
#*.cs diff=csharp
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# Set the merge driver for project and solution files
|
|
||||||
#
|
|
||||||
# Merging from the command prompt will add diff markers to the files if there
|
|
||||||
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
|
||||||
# the diff markers are never inserted). Diff markers may cause the following
|
|
||||||
# file extensions to fail to load in VS. An alternative would be to treat
|
|
||||||
# these files as binary and thus will always conflict and require user
|
|
||||||
# intervention with every merge. To do so, just uncomment the entries below
|
|
||||||
###############################################################################
|
|
||||||
#*.sln merge=binary
|
|
||||||
#*.csproj merge=binary
|
|
||||||
#*.vbproj merge=binary
|
|
||||||
#*.vcxproj merge=binary
|
|
||||||
#*.vcproj merge=binary
|
|
||||||
#*.dbproj merge=binary
|
|
||||||
#*.fsproj merge=binary
|
|
||||||
#*.lsproj merge=binary
|
|
||||||
#*.wixproj merge=binary
|
|
||||||
#*.modelproj merge=binary
|
|
||||||
#*.sqlproj merge=binary
|
|
||||||
#*.wwaproj merge=binary
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# behavior for image files
|
|
||||||
#
|
|
||||||
# image files are treated as binary by default.
|
|
||||||
###############################################################################
|
|
||||||
#*.jpg binary
|
|
||||||
#*.png binary
|
|
||||||
#*.gif binary
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# diff behavior for common document formats
|
|
||||||
#
|
|
||||||
# Convert binary document formats to text before diffing them. This feature
|
|
||||||
# is only available from the command line. Turn it on by uncommenting the
|
|
||||||
# entries below.
|
|
||||||
###############################################################################
|
|
||||||
#*.doc diff=astextplain
|
|
||||||
#*.DOC diff=astextplain
|
|
||||||
#*.docx diff=astextplain
|
|
||||||
#*.DOCX diff=astextplain
|
|
||||||
#*.dot diff=astextplain
|
|
||||||
#*.DOT diff=astextplain
|
|
||||||
#*.pdf diff=astextplain
|
|
||||||
#*.PDF diff=astextplain
|
|
||||||
#*.rtf diff=astextplain
|
|
||||||
#*.RTF diff=astextplain
|
|
|
@ -11,7 +11,7 @@ Paste in the version information from the SubServers app in question here. To ge
|
||||||
Here you can write about what happened that shouldn't have. If you have any errors in your console related to what happened, you should also paste those here.
|
Here you can write about what happened that shouldn't have. If you have any errors in your console related to what happened, you should also paste those here.
|
||||||
|
|
||||||
### How It Happened
|
### How It Happened
|
||||||
Tell us step-by-step how to recreate the problem. This step is vital for us to determine whether or not the problem happens to everyone else too.
|
Tell us step-by-step how to recreate the problem. This step is vital for us to determine whether the problem happens to everyone else too.
|
||||||
|
|
||||||
### Additional Information
|
### Additional Information
|
||||||
Here you can provide any extra details you may think useful for solving the problem.
|
Here you can provide any extra details you may think useful for solving the problem.
|
||||||
|
|
|
@ -1,48 +1,17 @@
|
||||||
# SubServers 2 Ignored Files
|
# Hide System and IDE Generated Files
|
||||||
|
|
||||||
*.iml
|
|
||||||
|
|
||||||
# User-specific files
|
|
||||||
*.suo
|
|
||||||
*.user
|
|
||||||
*.userosscache
|
|
||||||
*.sln.docstates
|
|
||||||
*.userprefs
|
|
||||||
|
|
||||||
## Directory-based project format:
|
|
||||||
.idea/
|
|
||||||
|
|
||||||
## File-based project format:
|
|
||||||
*.ipr
|
|
||||||
*.iws
|
|
||||||
|
|
||||||
# IntelliJ
|
|
||||||
/out/
|
/out/
|
||||||
|
.idea/
|
||||||
# mpeltonen/sbt-idea plugin
|
*.iml
|
||||||
.idea_modules/
|
|
||||||
|
|
||||||
# JIRA plugin
|
|
||||||
atlassian-ide-plugin.xml
|
|
||||||
|
|
||||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
|
||||||
com_crashlytics_export_strings.xml
|
|
||||||
crashlytics.properties
|
|
||||||
crashlytics-build.properties
|
|
||||||
|
|
||||||
# Hide Unfinished Project Files
|
|
||||||
/SubServers.Client/Windows/
|
|
||||||
/Artifacts/SubServers.Web.jar
|
|
||||||
/SubServers.Velocity/
|
|
||||||
/SubServers.Web/
|
|
||||||
|
|
||||||
# Hide Others
|
|
||||||
/Artifacts/-Maven/
|
|
||||||
/Artifacts/-History/
|
|
||||||
/Artifacts/-Icon/
|
|
||||||
/Artifacts/*.jar
|
|
||||||
/Javadoc/
|
|
||||||
/SubServers.Test/
|
|
||||||
/build.ant
|
|
||||||
/build.log
|
|
||||||
.DS_STORE
|
.DS_STORE
|
||||||
|
|
||||||
|
# Hide Unfinished Projects
|
||||||
|
/SubServers.Test/
|
||||||
|
|
||||||
|
# Hide Compiled Artifacts
|
||||||
|
/Artifacts/*
|
||||||
|
/BungeeCord/
|
||||||
|
/Javadoc/
|
||||||
|
|
||||||
|
# Show Interpreted Artifacts
|
||||||
|
!/Artifacts/Download/
|
||||||
|
!/Artifacts/SubServers.Patcher.sh
|
||||||
|
|
|
@ -321,14 +321,14 @@
|
||||||
switch (a.attr("href").toLowerCase()) {
|
switch (a.attr("href").toLowerCase()) {
|
||||||
case "%adfly_app_download%":
|
case "%adfly_app_download%":
|
||||||
if (hash.hasOwnProperty("build")) {
|
if (hash.hasOwnProperty("build")) {
|
||||||
a.attr("href", "https://adf.ly/18562515/https://src.me1312.net/maven/net/ME1312/SubServers/" + hash.app.replace(/^(.+?)\.([^.]*)$/, '$1') + "/" + hash.build + "/" + hash.app.replace(/^(.+?)\.([^.]*)$/, '$1') + "-" + hash.build + ".jar");
|
a.attr("href", "https://adf.ly/18562515/https://dev.me1312.net/maven/net/ME1312/SubServers/" + hash.app.replace(/^(.+?)\.([^.]*)$/, '$1') + "/" + hash.build + "/" + hash.app.replace(/^(.+?)\.([^.]*)$/, '$1') + "-" + hash.build + ".jar");
|
||||||
} else {
|
} else {
|
||||||
a.attr("href", "https://adf.ly/18562515/https://raw.githubusercontent.com/ME1312/SubServers-2/" + hash.commit.toLowerCase() + "/Artifacts/" + hash.app);
|
a.attr("href", "https://adf.ly/18562515/https://raw.githubusercontent.com/ME1312/SubServers-2/" + hash.commit.toLowerCase() + "/Artifacts/" + hash.app);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "%app_download%":
|
case "%app_download%":
|
||||||
if (hash.hasOwnProperty("build")) {
|
if (hash.hasOwnProperty("build")) {
|
||||||
a.attr("href", "https://src.me1312.net/maven/net/ME1312/SubServers/" + hash.app.replace(/^(.+?)\.([^.]*)$/, '$1') + "/" + hash.build + "/" + hash.app.replace(/^(.+?)\.([^.]*)$/, '$1') + "-" + hash.build + ".jar");
|
a.attr("href", "https://dev.me1312.net/maven/net/ME1312/SubServers/" + hash.app.replace(/^(.+?)\.([^.]*)$/, '$1') + "/" + hash.build + "/" + hash.app.replace(/^(.+?)\.([^.]*)$/, '$1') + "-" + hash.build + ".jar");
|
||||||
} else {
|
} else {
|
||||||
a.attr("href", "https://raw.githubusercontent.com/ME1312/SubServers-2/" + hash.commit.toLowerCase() + "/Artifacts/" + hash.app);
|
a.attr("href", "https://raw.githubusercontent.com/ME1312/SubServers-2/" + hash.commit.toLowerCase() + "/Artifacts/" + hash.app);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ if [ $__RETURN -eq 0 ]
|
||||||
rm -Rf LICENSE
|
rm -Rf LICENSE
|
||||||
fi
|
fi
|
||||||
if [ -f "META-INF/MANIFEST.MF" ]; then
|
if [ -f "META-INF/MANIFEST.MF" ]; then
|
||||||
cat META-INF/MANIFEST.MF | sed -e "/^\s*$/d" -e "/^Main-Class:.*$/d" -e "/^Implementation-Title:.*$/d" -e "/^Specification-Title:.*$/d" -e "/^Build-Jdk:.*$/d" -e "/^Created-By:.*$/d" -e "/^Built-By:.*$/d" > ../MANIFEST.MF
|
cat META-INF/MANIFEST.MF | sed 's/\r$//' | sed ':a;N;$!ba;s/\n //g' | sed -e "/^\s*$/d" -e "/^Main-Class:.*$/d" -e "/^Implementation-Title:.*$/d" -e "/^Specification-Title:.*$/d" -e "/^Build-Jdk:.*$/d" -e "/^Created-By:.*$/d" -e "/^Built-By:.*$/d" > ../MANIFEST.MF
|
||||||
else
|
else
|
||||||
printf "Manifest-Version: 1.0\n" > ../MANIFEST.MF
|
printf "Manifest-Version: 1.0\n" > ../MANIFEST.MF
|
||||||
fi
|
fi
|
||||||
|
@ -67,8 +67,8 @@ if [ $__RETURN -eq 0 ]
|
||||||
then
|
then
|
||||||
echo ">> Writing Changes..."
|
echo ">> Writing Changes..."
|
||||||
if [ -f "META-INF/MANIFEST.MF" ]
|
if [ -f "META-INF/MANIFEST.MF" ]
|
||||||
then
|
then # (Read File) (Convert to LF) (Rejoin Split Lines) (Omit Empty, Duplicate, and Unnecessary Properties)
|
||||||
cat META-INF/MANIFEST.MF | sed -e "/^\s*$/d" -e "/^Manifest-Version:.*$/d" -e "/^Class-Path:.*$/d" -e "/^Build-Jdk:.*$/d" -e "/^Created-By:.*$/d" -e "/^Built-By:.*$/d" >> ../MANIFEST.MF
|
cat META-INF/MANIFEST.MF | sed 's/\r$//' | sed ':a;N;$!ba;s/\n //g' | sed -e "/^\s*$/d" -e "/^Manifest-Version:.*$/d" -e "/^Class-Path:.*$/d" -e "/^Build-Jdk:.*$/d" -e "/^Created-By:.*$/d" -e "/^Built-By:.*$/d" >> ../MANIFEST.MF
|
||||||
else
|
else
|
||||||
if [ ! -d "META-INF" ]; then
|
if [ ! -d "META-INF" ]; then
|
||||||
mkdir META-INF
|
mkdir META-INF
|
||||||
|
@ -79,13 +79,13 @@ if [ $__RETURN -eq 0 ]
|
||||||
fi
|
fi
|
||||||
yes | cp -rf . ../Patched.jar
|
yes | cp -rf . ../Patched.jar
|
||||||
cd ../
|
cd ../
|
||||||
printf "Built-By: SubServers.Bungee.Patcher\n" >> MANIFEST.MF
|
printf "Built-By: SubServers.Patcher\n" >> MANIFEST.MF
|
||||||
cp -f MANIFEST.MF Patched.jar/META-INF
|
cp -f MANIFEST.MF Patched.jar/META-INF
|
||||||
if [ -f "Patched.jar/bungee.yml" ]; then
|
if [ -f "Patched.jar/bungee.yml" ]; then
|
||||||
rm -Rf Patched.jar/bungee.yml
|
rm -Rf Patched.jar/bungee.yml
|
||||||
fi
|
fi
|
||||||
if [ ! -f "MODIFICATIONS" ]; then
|
if [ ! -f "MODIFICATIONS" ]; then
|
||||||
printf "# SubServers.Bungee.Patcher generated difference list (may be empty if git is not installed)\n#\n" > MODIFICATIONS
|
printf "# SubServers.Patcher generated difference list (may be empty if git is not installed)\n#\n" > MODIFICATIONS
|
||||||
fi
|
fi
|
||||||
printf "@ `date`\n> git --no-pager diff --no-index --name-status SubServers.Patcher/Original.jar SubServers.Patcher/Patched.jar\n" >> MODIFICATIONS
|
printf "@ `date`\n> git --no-pager diff --no-index --name-status SubServers.Patcher/Original.jar SubServers.Patcher/Patched.jar\n" >> MODIFICATIONS
|
||||||
git --no-pager diff --no-index --name-status Original.jar Patched.jar | sed -e "s/\tOriginal.jar\//\t\//" -e "s/\tPatched.jar\//\t\//" >> MODIFICATIONS
|
git --no-pager diff --no-index --name-status Original.jar Patched.jar | sed -e "s/\tOriginal.jar\//\t\//" -e "s/\tPatched.jar\//\t\//" >> MODIFICATIONS
|
||||||
|
|
2
LICENSE
2
LICENSE
|
@ -186,7 +186,7 @@
|
||||||
same "printed page" as the copyright notice for easier
|
same "printed page" as the copyright notice for easier
|
||||||
identification within third-party archives.
|
identification within third-party archives.
|
||||||
|
|
||||||
Copyright (C) 2015-2019 ME1312
|
Copyright (C) 2015-2023 ME1312
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
|
22
README.md
22
README.md
|
@ -1,6 +1,6 @@
|
||||||
# ![https://s3.postimg.cc/dikyxlz5v/Sub_Banner.png](https://s3.postimg.cc/dikyxlz5v/Sub_Banner.png)
|
# ![https://s3.postimg.cc/dikyxlz5v/Sub_Banner.png](https://s3.postimg.cc/dikyxlz5v/Sub_Banner.png)
|
||||||
[![Build Status](https://src.me1312.net/jenkins/job/SubServers%20Platform/badge/icon)](https://src.me1312.net/jenkins/job/SubServers%20Platform/)
|
[![Build Status](https://dev.me1312.net/jenkins/job/SubServers%20Platform/badge/icon)](https://dev.me1312.net/jenkins/job/SubServers%20Platform/)
|
||||||
[![Release Verison](https://img.shields.io/github/release/ME1312/SubServers-2/all.svg)](https://github.com/ME1312/SubServers-2/releases) [![Snapshot Verison](https://img.shields.io/badge/dynamic/xml.svg?label=snapshot&url=https%3A%2F%2Fsrc.me1312.net%2Fmaven%2Fnet%2FME1312%2FSubServers%2FSubServers.Bungee%2Fmaven-metadata.xml&query=%2F%2Fversioning%2Frelease&colorB=blue)](https://src.me1312.net/jenkins/job/SubServers%20Platform/) [![Discord](https://img.shields.io/discord/526520424880930867.svg)](https://discord.gg/VZ8YJqz)<br><br>
|
[![Release Verison](https://img.shields.io/github/release/ME1312/SubServers-2/all.svg)](https://github.com/ME1312/SubServers-2/releases) [![Snapshot Verison](https://img.shields.io/badge/dynamic/xml.svg?label=snapshot&url=https%3A%2F%2Fdev.me1312.net%2Fmaven%2Fnet%2FME1312%2FSubServers%2FSubServers.Bungee%2Fmaven-metadata.xml&query=%2F%2Fversioning%2Frelease&colorB=blue)](https://dev.me1312.net/jenkins/job/SubServers%20Platform/) [![Discord](https://img.shields.io/discord/526520424880930867.svg)](https://discord.gg/zWupnVn)<br><br>
|
||||||
SubServers 2 is a rewrite of SubServers, the Server Management Platform.<br>
|
SubServers 2 is a rewrite of SubServers, the Server Management Platform.<br>
|
||||||
> [https://www.spigotmc.org/resources/subservers-bungee.11264/](https://www.spigotmc.org/resources/subservers-bungee.11264/)<br>
|
> [https://www.spigotmc.org/resources/subservers-bungee.11264/](https://www.spigotmc.org/resources/subservers-bungee.11264/)<br>
|
||||||
> [https://www.spigotmc.org/resources/subservers-host.38833/](https://www.spigotmc.org/resources/subservers-host.38833/)<br>
|
> [https://www.spigotmc.org/resources/subservers-host.38833/](https://www.spigotmc.org/resources/subservers-host.38833/)<br>
|
||||||
|
@ -12,22 +12,26 @@ SubServers 2 is a rewrite of SubServers, the Server Management Platform.<br>
|
||||||
These are some quick links for common resources of SubServers 2.
|
These are some quick links for common resources of SubServers 2.
|
||||||
|
|
||||||
### How to Install
|
### How to Install
|
||||||
> [https://github.com/ME1312/SubServers-2/wiki/Install](https://github.com/ME1312/SubServers-2/wiki/Install)
|
> [https://github.com/ME1312/SubServers-2/wiki/Install](https://github.com/ME1312/SubServers-2/wiki/Installation)
|
||||||
|
|
||||||
### Snapshot Downloads
|
### Snapshot Downloads
|
||||||
> [https://src.me1312.net/jenkins/job/SubServers Platform](https://src.me1312.net/jenkins/job/SubServers%20Platform)
|
> [https://dev.me1312.net/jenkins/job/SubServers Platform](https://dev.me1312.net/jenkins/job/SubServers%20Platform)
|
||||||
|
|
||||||
### Javadocs for Developers
|
### Javadocs for Developers
|
||||||
> [https://src.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Bungee/](https://src.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Bungee/)<br>
|
> [https://dev.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Bungee](https://dev.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Bungee)<br>
|
||||||
> [https://src.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Host/](https://src.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Host/)<br>
|
> [https://dev.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Bungee.Common](https://dev.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Bungee.Common)<br>
|
||||||
> [https://src.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Sync/](https://src.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Sync/)<br>
|
> [https://dev.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Host](https://dev.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Host)<br>
|
||||||
> [https://src.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Client.Bukkit/](https://src.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Client.Bukkit/)<br>
|
> [https://dev.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Sync](https://dev.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Sync)<br>
|
||||||
> [https://src.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Client.Sponge/](https://src.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Client.Sponge/)
|
> [https://dev.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Sync.Velocity](https://dev.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Sync.Velocity)<br>
|
||||||
|
> [https://dev.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Client.Bukkit](https://dev.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Client.Bukkit)<br>
|
||||||
|
> [https://dev.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Client.Common](https://dev.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Client.Common)<br>
|
||||||
|
> [https://dev.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Client.Sponge](https://dev.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Client.Sponge)
|
||||||
|
|
||||||
### Stats for nerds
|
### Stats for nerds
|
||||||
> [https://bstats.org/plugin/bungeecord/SubServers_Bungee](https://bstats.org/plugin/bungeecord/SubServers%202)<br>
|
> [https://bstats.org/plugin/bungeecord/SubServers_Bungee](https://bstats.org/plugin/bungeecord/SubServers%202)<br>
|
||||||
> [https://bstats.org/plugin/other/SubServers_Host](https://bstats.org/plugin/other/SubServers%20Host)<br>
|
> [https://bstats.org/plugin/other/SubServers_Host](https://bstats.org/plugin/other/SubServers%20Host)<br>
|
||||||
> [https://bstats.org/plugin/bungeecord/SubServers_Sync](https://bstats.org/plugin/bungeecord/SubServers%20Sync)<br>
|
> [https://bstats.org/plugin/bungeecord/SubServers_Sync](https://bstats.org/plugin/bungeecord/SubServers%20Sync)<br>
|
||||||
|
> [https://bstats.org/plugin/velocity/SubServers_Sync](https://bstats.org/plugin/velocity/SubServers%20Sync)<br>
|
||||||
> [https://bstats.org/plugin/bungeecord/SubServers_Console](https://bstats.org/plugin/bungeecord/SubServers%20Console)<br>
|
> [https://bstats.org/plugin/bungeecord/SubServers_Console](https://bstats.org/plugin/bungeecord/SubServers%20Console)<br>
|
||||||
> [https://bstats.org/plugin/bukkit/SubServers_Client](https://bstats.org/plugin/bukkit/SubServers%20Client)<br>
|
> [https://bstats.org/plugin/bukkit/SubServers_Client](https://bstats.org/plugin/bukkit/SubServers%20Client)<br>
|
||||||
> [https://bstats.org/plugin/sponge/SubServers_Client](https://bstats.org/plugin/sponge/SubServers%20Client)
|
> [https://bstats.org/plugin/sponge/SubServers_Client](https://bstats.org/plugin/sponge/SubServers%20Client)
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
<?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.ME1312.SubServers</groupId>
|
||||||
|
<artifactId>SubServers.Bungee.Common</artifactId>
|
||||||
|
<version>-PLACEHOLDER</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>md_5-repo</id>
|
||||||
|
<url>http://repo.md-5.net/content/repositories/snapshots/</url>
|
||||||
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<id>me1312-repo</id>
|
||||||
|
<url>https://dev.me1312.net/maven</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.md_5</groupId>
|
||||||
|
<artifactId>bungeecord-internal</artifactId>
|
||||||
|
<version>1.15-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.ME1312.Galaxi</groupId>
|
||||||
|
<artifactId>GalaxiBase</artifactId>
|
||||||
|
<version>23w51a</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<directory>../../out/compile/target/SubServers.Bungee.Common</directory>
|
||||||
|
<sourceDirectory>src</sourceDirectory>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src</directory>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/*.java</exclude>
|
||||||
|
</excludes>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.7.0</version>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-antrun-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>process-resources</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>run</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<tasks>
|
||||||
|
<mkdir dir="${project.build.directory}" />
|
||||||
|
<copy file="${basedir}/../../LICENSE" todir="${project.build.directory}/classes" />
|
||||||
|
</tasks>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>3.2.0</version>
|
||||||
|
<configuration>
|
||||||
|
<finalName>SubServers.Bungee.Common</finalName>
|
||||||
|
<outputDirectory>../../Artifacts/Maven</outputDirectory>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>generate-sources</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>javadoc</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<windowtitle>SubServers.Bungee.Common</windowtitle>
|
||||||
|
<doctitle>SubServers.Bungee.Common ${project.version}</doctitle>
|
||||||
|
<show>protected</show>
|
||||||
|
<destDir>./</destDir>
|
||||||
|
<outputDirectory>${basedir}/../../Javadoc/SubServers.Bungee.Common</outputDirectory>
|
||||||
|
<reportOutputDirectory>${basedir}/../../Javadoc/SubServers.Bungee.Common</reportOutputDirectory>
|
||||||
|
<additionalOptions>-Xdoclint:none</additionalOptions>
|
||||||
|
<links>
|
||||||
|
<link>https://dev.me1312.net/jenkins/job/GalaxiEngine/javadoc/GalaxiBase/</link>
|
||||||
|
<link>https://ci.md-5.net/job/BungeeCord/ws/api/target/apidocs/</link>
|
||||||
|
</links>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -0,0 +1,137 @@
|
||||||
|
package net.ME1312.SubServers.Bungee;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
|
import net.ME1312.Galaxi.Library.Version.Version;
|
||||||
|
import net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
import net.md_5.bungee.api.config.ServerInfo;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SubAPI BungeeCord Common Class
|
||||||
|
*/
|
||||||
|
public interface BungeeAPI {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the SubAPI BungeeCord Common Methods
|
||||||
|
*
|
||||||
|
* @return SubAPI BungeeCord Common
|
||||||
|
*/
|
||||||
|
static BungeeAPI getInstance() {
|
||||||
|
return ((BungeeCommon) ProxyServer.getInstance()).api.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the BungeeCommon Internals
|
||||||
|
*
|
||||||
|
* @deprecated Use BungeeAPI Methods when available
|
||||||
|
* @return BungeeCommon Internals
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
BungeeCommon getInternals();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of players on this network across all known proxies
|
||||||
|
*
|
||||||
|
* @return Remote Player Collection
|
||||||
|
*/
|
||||||
|
int getRemotePlayerCount();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get players on this server across all known proxies
|
||||||
|
*
|
||||||
|
* @param server Server to search
|
||||||
|
* @return Remote Player Map
|
||||||
|
*/
|
||||||
|
Map<UUID, ? extends RemotePlayer> getRemotePlayers(ServerInfo server);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get players on this network across all known proxies
|
||||||
|
*
|
||||||
|
* @return Remote Player Map
|
||||||
|
*/
|
||||||
|
Map<UUID, ? extends RemotePlayer> getRemotePlayers();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a player on this network by searching across all known proxies
|
||||||
|
*
|
||||||
|
* @param name Player name
|
||||||
|
* @return Remote Player
|
||||||
|
*/
|
||||||
|
RemotePlayer getRemotePlayer(String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a player on this network by searching across all known proxies
|
||||||
|
*
|
||||||
|
* @param id Player UUID
|
||||||
|
* @return Remote Player
|
||||||
|
*/
|
||||||
|
RemotePlayer getRemotePlayer(UUID id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current SubServers Lang Channels
|
||||||
|
*
|
||||||
|
* @return SubServers Lang Channel list
|
||||||
|
*/
|
||||||
|
Collection<String> getLangChannels();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets values from the SubServers Lang
|
||||||
|
*
|
||||||
|
* @param channel Lang Channel
|
||||||
|
* @return Lang Value
|
||||||
|
*/
|
||||||
|
Map<String, String> getLang(String channel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a value from the SubServers Lang
|
||||||
|
*
|
||||||
|
* @param channel Lang Channel
|
||||||
|
* @param key Key
|
||||||
|
* @return Lang Values
|
||||||
|
*/
|
||||||
|
default String getLang(String channel, String key) {
|
||||||
|
Util.nullpo(channel, key);
|
||||||
|
return getLang(channel).get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the Runtime Directory
|
||||||
|
*
|
||||||
|
* @return Directory
|
||||||
|
*/
|
||||||
|
File getRuntimeDirectory();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the SubServers Version
|
||||||
|
*
|
||||||
|
* @return SubServers Version
|
||||||
|
*/
|
||||||
|
Version getWrapperVersion();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the SubServers Build Version
|
||||||
|
*
|
||||||
|
* @return SubServers Build Version (or null if unsigned)
|
||||||
|
*/
|
||||||
|
Version getWrapperBuild();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the BungeeCord Version
|
||||||
|
*
|
||||||
|
* @return BungeeCord Version
|
||||||
|
*/
|
||||||
|
Version getProxyVersion();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an array of compatible Minecraft Versions
|
||||||
|
*
|
||||||
|
* @return Minecraft Versions
|
||||||
|
*/
|
||||||
|
Version[] getGameVersion();
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
package net.ME1312.SubServers.Bungee;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
|
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
import net.md_5.bungee.BungeeCord;
|
||||||
|
import net.md_5.bungee.api.config.ServerInfo;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BungeeCord Common Layout Class
|
||||||
|
*/
|
||||||
|
public abstract class BungeeCommon extends BungeeCord {
|
||||||
|
private static BungeeCommon instance;
|
||||||
|
final Supplier<BungeeAPI> api;
|
||||||
|
protected final Collection<Channel> listeners;
|
||||||
|
|
||||||
|
protected BungeeCommon(Supplier<BungeeAPI> api) throws Exception {
|
||||||
|
listeners= Util.reflect(BungeeCord.class.getDeclaredField("listeners"), this);
|
||||||
|
this.api = api;
|
||||||
|
instance = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the name from BungeeCord's original signature (for determining which fork is being used)
|
||||||
|
*
|
||||||
|
* @return BungeeCord Software Name
|
||||||
|
*/
|
||||||
|
public abstract String getBungeeName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Waterfall's getServersCopy()
|
||||||
|
*
|
||||||
|
* @return Server Map Copy
|
||||||
|
*/
|
||||||
|
public abstract Map<String, ServerInfo> getServersCopy();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the ProxyServer Common Object
|
||||||
|
*
|
||||||
|
* @return ProxyServer Common
|
||||||
|
*/
|
||||||
|
public static BungeeCommon getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package net.ME1312.SubServers.Bungee.Library.Compatibility;
|
||||||
|
|
||||||
|
import net.ME1312.SubServers.Bungee.BungeeCommon;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.logging.Handler;
|
||||||
|
import java.util.logging.LogRecord;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logger Compatibility Class
|
||||||
|
*/
|
||||||
|
public class Logger {
|
||||||
|
private static final HashMap<String, java.util.logging.Logger> existing = new HashMap<String, java.util.logging.Logger>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a logger
|
||||||
|
*
|
||||||
|
* @param prefix Prefix
|
||||||
|
* @return Logger
|
||||||
|
*/
|
||||||
|
public static java.util.logging.Logger get(String prefix) {
|
||||||
|
if (!existing.containsKey(prefix)) {
|
||||||
|
java.util.logging.Logger log = java.util.logging.Logger.getAnonymousLogger();
|
||||||
|
log.setUseParentHandlers(false);
|
||||||
|
log.addHandler(new Handler() {
|
||||||
|
@Override
|
||||||
|
public void publish(LogRecord record) {
|
||||||
|
BungeeCommon.getInstance().getLogger().log(record.getLevel(), prefix + " > " + record.getMessage(), record.getParameters());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flush() {}
|
||||||
|
public void close() {}
|
||||||
|
});
|
||||||
|
existing.put(prefix, log);
|
||||||
|
}
|
||||||
|
return existing.get(prefix);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package net.ME1312.SubServers.Bungee.Library.Compatibility;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.chat.BaseComponent;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.function.IntConsumer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RemotePlayer Static Implementation Layout Class
|
||||||
|
*/
|
||||||
|
public abstract class RPSI {
|
||||||
|
protected static RPSI instance;
|
||||||
|
protected RPSI() {
|
||||||
|
if (instance == null) instance = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends messages to this player
|
||||||
|
*
|
||||||
|
* @param players Players to send to
|
||||||
|
* @param messages Messages to send
|
||||||
|
* @param response Success Status
|
||||||
|
*/
|
||||||
|
protected abstract void sendMessage(UUID[] players, String[] messages, IntConsumer response);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends messages to this player
|
||||||
|
*
|
||||||
|
* @param players Players to send to
|
||||||
|
* @param messages Messages to send
|
||||||
|
* @param response Success Status
|
||||||
|
*/
|
||||||
|
protected abstract void sendMessage(UUID[] players, BaseComponent[][] messages, IntConsumer response);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transfers this player to another server
|
||||||
|
*
|
||||||
|
* @param players Players to send to
|
||||||
|
* @param server Target server
|
||||||
|
* @param response Success Status
|
||||||
|
*/
|
||||||
|
protected abstract void transfer(UUID[] players, String server, IntConsumer response);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnects this player from the network
|
||||||
|
*
|
||||||
|
* @param players Players to send to
|
||||||
|
* @param reason Disconnect Reason
|
||||||
|
* @param response Success status
|
||||||
|
*/
|
||||||
|
protected abstract void disconnect(UUID[] players, String reason, IntConsumer response);
|
||||||
|
}
|
|
@ -0,0 +1,460 @@
|
||||||
|
package net.ME1312.SubServers.Bungee.Library.Compatibility;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.chat.BaseComponent;
|
||||||
|
import net.md_5.bungee.api.config.ServerInfo;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.function.IntConsumer;
|
||||||
|
|
||||||
|
import static net.ME1312.SubServers.Bungee.Library.Compatibility.RPSI.instance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RemotePlayer Layout Class
|
||||||
|
*/
|
||||||
|
public interface RemotePlayer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Local Player
|
||||||
|
*
|
||||||
|
* @return Local Player (or null when not local)
|
||||||
|
*/
|
||||||
|
ProxiedPlayer get();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the UUID of this player.
|
||||||
|
*
|
||||||
|
* @return the UUID
|
||||||
|
*/
|
||||||
|
UUID getUniqueId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the unique name of this player.
|
||||||
|
*
|
||||||
|
* @return the player's username
|
||||||
|
*/
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the remote address of this connection.
|
||||||
|
*
|
||||||
|
* @return the remote address
|
||||||
|
*/
|
||||||
|
InetSocketAddress getAddress();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the name of the proxy this player is connected to.
|
||||||
|
*
|
||||||
|
* @return the name of the proxy this player is connected to
|
||||||
|
*/
|
||||||
|
String getProxyName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the name of the server this player is connected to.
|
||||||
|
*
|
||||||
|
* @return the name of the server this player is connected to
|
||||||
|
*/
|
||||||
|
String getServerName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the server this player is connected to.
|
||||||
|
*
|
||||||
|
* @return the server this player is connected to
|
||||||
|
*/
|
||||||
|
ServerInfo getServer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends messages to all players
|
||||||
|
*
|
||||||
|
* @param messages Messages to send
|
||||||
|
*/
|
||||||
|
static void broadcastMessage(String... messages) {
|
||||||
|
broadcastMessage(messages, i -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a message to all players
|
||||||
|
*
|
||||||
|
* @param message Message to send
|
||||||
|
* @param response Success Status
|
||||||
|
*/
|
||||||
|
static void broadcastMessage(String message, IntConsumer response) {
|
||||||
|
broadcastMessage(new String[]{ message }, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends messages to all players
|
||||||
|
*
|
||||||
|
* @param messages Messages to send
|
||||||
|
* @param response Success Status
|
||||||
|
*/
|
||||||
|
static void broadcastMessage(String[] messages, IntConsumer response) {
|
||||||
|
sendMessage(null, messages, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends messages to this player
|
||||||
|
*
|
||||||
|
* @param messages Messages to send
|
||||||
|
*/
|
||||||
|
default void sendMessage(String... messages) {
|
||||||
|
sendMessage(messages, i -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a message to this player
|
||||||
|
*
|
||||||
|
* @param message Message to send
|
||||||
|
* @param response Success Status
|
||||||
|
*/
|
||||||
|
default void sendMessage(String message, IntConsumer response) {
|
||||||
|
sendMessage(new String[]{ message }, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends messages to this player
|
||||||
|
*
|
||||||
|
* @param messages Messages to send
|
||||||
|
* @param response Success Status
|
||||||
|
*/
|
||||||
|
default void sendMessage(String[] messages, IntConsumer response) {
|
||||||
|
sendMessage(new UUID[]{ getUniqueId() }, messages, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends messages to these players
|
||||||
|
*
|
||||||
|
* @param players Players to select
|
||||||
|
* @param messages Messages to send
|
||||||
|
*/
|
||||||
|
static void sendMessage(UUID[] players, String... messages) {
|
||||||
|
sendMessage(players, messages, i -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a message to these players
|
||||||
|
*
|
||||||
|
* @param players Players to select
|
||||||
|
* @param message Message to send
|
||||||
|
* @param response Success Status
|
||||||
|
*/
|
||||||
|
static void sendMessage(UUID[] players, String message, IntConsumer response) {
|
||||||
|
sendMessage(players, new String[]{ message }, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends messages to these players
|
||||||
|
*
|
||||||
|
* @param players Players to select
|
||||||
|
* @param messages Messages to send
|
||||||
|
* @param response Success Status
|
||||||
|
*/
|
||||||
|
static void sendMessage(UUID[] players, String[] messages, IntConsumer response) {
|
||||||
|
instance.sendMessage(players, messages, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a message to all players
|
||||||
|
*
|
||||||
|
* @param message Message to send
|
||||||
|
*/
|
||||||
|
static void broadcastMessage(BaseComponent... message) {
|
||||||
|
broadcastMessage(message, i -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a message to all players
|
||||||
|
*
|
||||||
|
* @param message Message to send
|
||||||
|
* @param response Success Status
|
||||||
|
*/
|
||||||
|
static void broadcastMessage(BaseComponent message, IntConsumer response) {
|
||||||
|
broadcastMessage(new BaseComponent[]{ message }, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a messages to all players
|
||||||
|
*
|
||||||
|
* @param message Message to send
|
||||||
|
* @param response Success Status
|
||||||
|
*/
|
||||||
|
static void broadcastMessage(BaseComponent[] message, IntConsumer response) {
|
||||||
|
broadcastMessage(new BaseComponent[][]{ message }, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends messages to all players
|
||||||
|
*
|
||||||
|
* @param messages Messages to send
|
||||||
|
*/
|
||||||
|
static void broadcastMessage(BaseComponent[]... messages) {
|
||||||
|
broadcastMessage(messages, i -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends messages to all players
|
||||||
|
*
|
||||||
|
* @param messages Messages to send
|
||||||
|
* @param response Success Status
|
||||||
|
*/
|
||||||
|
static void broadcastMessage(BaseComponent[][] messages, IntConsumer response) {
|
||||||
|
sendMessage(null, messages, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a message to this player
|
||||||
|
*
|
||||||
|
* @param message Message to send
|
||||||
|
*/
|
||||||
|
default void sendMessage(BaseComponent... message) {
|
||||||
|
sendMessage(message, i -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a message to this player
|
||||||
|
*
|
||||||
|
* @param message Message to send
|
||||||
|
* @param response Success Status
|
||||||
|
*/
|
||||||
|
default void sendMessage(BaseComponent message, IntConsumer response) {
|
||||||
|
sendMessage(new BaseComponent[]{ message }, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a message to this player
|
||||||
|
*
|
||||||
|
* @param message Message to send
|
||||||
|
* @param response Success Status
|
||||||
|
*/
|
||||||
|
default void sendMessage(BaseComponent[] message, IntConsumer response) {
|
||||||
|
sendMessage(new BaseComponent[][]{ message }, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends messages to this player
|
||||||
|
*
|
||||||
|
* @param messages Messages to send
|
||||||
|
*/
|
||||||
|
default void sendMessage(BaseComponent[]... messages) {
|
||||||
|
sendMessage(messages, i -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends messages to this player
|
||||||
|
*
|
||||||
|
* @param messages Messages to send
|
||||||
|
* @param response Success Status
|
||||||
|
*/
|
||||||
|
default void sendMessage(BaseComponent[][] messages, IntConsumer response) {
|
||||||
|
sendMessage(new UUID[]{ getUniqueId() }, messages, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a message to these players
|
||||||
|
*
|
||||||
|
* @param players Players to select
|
||||||
|
* @param message Message to send
|
||||||
|
*/
|
||||||
|
static void sendMessage(UUID[] players, BaseComponent... message) {
|
||||||
|
sendMessage(players, message, i -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a message to these players
|
||||||
|
*
|
||||||
|
* @param players Players to select
|
||||||
|
* @param message Message to send
|
||||||
|
* @param response Success Status
|
||||||
|
*/
|
||||||
|
static void sendMessage(UUID[] players, BaseComponent message, IntConsumer response) {
|
||||||
|
sendMessage(players, new BaseComponent[]{ message }, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a message to these players
|
||||||
|
*
|
||||||
|
* @param players Players to select
|
||||||
|
* @param message Message to send
|
||||||
|
* @param response Success Status
|
||||||
|
*/
|
||||||
|
static void sendMessage(UUID[] players, BaseComponent[] message, IntConsumer response) {
|
||||||
|
sendMessage(players, new BaseComponent[][]{ message }, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends messages to these players
|
||||||
|
*
|
||||||
|
* @param players Players to select
|
||||||
|
* @param messages Messages to send
|
||||||
|
*/
|
||||||
|
static void sendMessage(UUID[] players, BaseComponent[]... messages) {
|
||||||
|
sendMessage(players, messages, i -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends messages to these players
|
||||||
|
*
|
||||||
|
* @param players Players to select
|
||||||
|
* @param messages Message to send
|
||||||
|
* @param response Success Status
|
||||||
|
*/
|
||||||
|
static void sendMessage(UUID[] players, BaseComponent[][] messages, IntConsumer response) {
|
||||||
|
instance.sendMessage(players, messages, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transfers this player to another server
|
||||||
|
*
|
||||||
|
* @param server Target server
|
||||||
|
*/
|
||||||
|
default void transfer(String server) {
|
||||||
|
transfer(server, i -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transfers this player to another server
|
||||||
|
*
|
||||||
|
* @param server Target server
|
||||||
|
* @param response Success status
|
||||||
|
*/
|
||||||
|
default void transfer(String server, IntConsumer response) {
|
||||||
|
transfer(new UUID[]{ getUniqueId() }, server, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transfers these players to another server
|
||||||
|
*
|
||||||
|
* @param players Players to select
|
||||||
|
* @param server Target server
|
||||||
|
*/
|
||||||
|
static void transfer(UUID[] players, String server) {
|
||||||
|
transfer(players, server, i -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transfers these players to another server
|
||||||
|
*
|
||||||
|
* @param players Players to select
|
||||||
|
* @param server Target server
|
||||||
|
* @param response Success status
|
||||||
|
*/
|
||||||
|
static void transfer(UUID[] players, String server, IntConsumer response) {
|
||||||
|
instance.transfer(players, server, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transfers this player to another server
|
||||||
|
*
|
||||||
|
* @param server Target server
|
||||||
|
*/
|
||||||
|
default void transfer(ServerInfo server) {
|
||||||
|
transfer(server, i -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transfers this player to another server
|
||||||
|
*
|
||||||
|
* @param server Target server
|
||||||
|
* @param response Success status
|
||||||
|
*/
|
||||||
|
default void transfer(ServerInfo server, IntConsumer response) {
|
||||||
|
transfer(new UUID[]{ getUniqueId() }, server, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transfers these players to another server
|
||||||
|
*
|
||||||
|
* @param players Players to select
|
||||||
|
* @param server Target server
|
||||||
|
*/
|
||||||
|
static void transfer(UUID[] players, ServerInfo server) {
|
||||||
|
transfer(players, server, i -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transfers these players to another server
|
||||||
|
*
|
||||||
|
* @param players Players to select
|
||||||
|
* @param server Target server
|
||||||
|
* @param response Success status
|
||||||
|
*/
|
||||||
|
static void transfer(UUID[] players, ServerInfo server, IntConsumer response) {
|
||||||
|
instance.transfer(players, server.getName(), response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnects this player from the network
|
||||||
|
*/
|
||||||
|
default void disconnect() {
|
||||||
|
disconnect((String) null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnects this player from the network
|
||||||
|
*
|
||||||
|
* @param response Success status
|
||||||
|
*/
|
||||||
|
default void disconnect(IntConsumer response) {
|
||||||
|
disconnect((String) null, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnects this player from the network
|
||||||
|
*
|
||||||
|
* @param reason Disconnect Reason
|
||||||
|
*/
|
||||||
|
default void disconnect(String reason) {
|
||||||
|
disconnect(reason, i -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnects this player from the network
|
||||||
|
*
|
||||||
|
* @param reason Disconnect Reason
|
||||||
|
* @param response Success status
|
||||||
|
*/
|
||||||
|
default void disconnect(String reason, IntConsumer response) {
|
||||||
|
disconnect(new UUID[]{ getUniqueId() }, reason, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnects these players from the network
|
||||||
|
*
|
||||||
|
* @param players Players to select
|
||||||
|
*/
|
||||||
|
static void disconnect(UUID... players) {
|
||||||
|
disconnect(players, (String) null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnects these players from the network
|
||||||
|
*
|
||||||
|
* @param players Players to select
|
||||||
|
* @param response Success status
|
||||||
|
*/
|
||||||
|
static void disconnect(UUID[] players, IntConsumer response) {
|
||||||
|
disconnect(players, null, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnects these players from the network
|
||||||
|
*
|
||||||
|
* @param players Players to select
|
||||||
|
* @param reason Disconnect Reason
|
||||||
|
*/
|
||||||
|
static void disconnect(UUID[] players, String reason) {
|
||||||
|
disconnect(players, reason, i -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnects these players from the network
|
||||||
|
*
|
||||||
|
* @param players Players to select
|
||||||
|
* @param reason Disconnect Reason
|
||||||
|
* @param response Success status
|
||||||
|
*/
|
||||||
|
static void disconnect(UUID[] players, String reason, IntConsumer response) {
|
||||||
|
instance.disconnect(players, reason, response);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package net.ME1312.SubServers.Bungee.Library.Fallback;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.config.ServerInfo;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fallback Server Inspector Layout Class
|
||||||
|
*/
|
||||||
|
public interface FallbackInspector {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inspect a fallback server and modify its confidence score
|
||||||
|
*
|
||||||
|
* @param player Player that requested (may be null)
|
||||||
|
* @param server Server to inspect
|
||||||
|
* @return A Positive Value to add points, a Negative Value to subtract points, a Null Value to invalidate the server, or a Zero Value to do nothing
|
||||||
|
*/
|
||||||
|
Double inspect(ProxiedPlayer player, ServerInfo server);
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
package net.ME1312.SubServers.Bungee.Library.Fallback;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.chat.BaseComponent;
|
||||||
|
import net.md_5.bungee.api.config.ServerInfo;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fallback Player State Class
|
||||||
|
*/
|
||||||
|
public class FallbackState {
|
||||||
|
public final UUID player;
|
||||||
|
public final LinkedList<String> names;
|
||||||
|
public final LinkedList<ServerInfo> servers;
|
||||||
|
public final BaseComponent[] reason;
|
||||||
|
private Map<String, ServerInfo> map;
|
||||||
|
private Timer finish;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smart Fallback State Container
|
||||||
|
*
|
||||||
|
* @param player Player
|
||||||
|
* @param servers Fallback Servers
|
||||||
|
* @param reason Original Disconnect Reason
|
||||||
|
*/
|
||||||
|
public FallbackState(UUID player, Map<String, ServerInfo> servers, BaseComponent... reason) {
|
||||||
|
this.player = player;
|
||||||
|
this.map = servers;
|
||||||
|
this.names = new LinkedList<>(servers.keySet());
|
||||||
|
this.servers = new LinkedList<>(servers.values());
|
||||||
|
this.reason = reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <i>Use</i> a server
|
||||||
|
*
|
||||||
|
* @param name Server name to remove
|
||||||
|
*/
|
||||||
|
public void remove(String name) {
|
||||||
|
servers.remove(map.get(name));
|
||||||
|
names.remove(name);
|
||||||
|
map.remove(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <i>Use</i> a server
|
||||||
|
*
|
||||||
|
* @param server Server to remove
|
||||||
|
*/
|
||||||
|
public void remove(ServerInfo server) {
|
||||||
|
map.remove(server.getName());
|
||||||
|
names.remove(server.getName());
|
||||||
|
servers.remove(server);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finish the process
|
||||||
|
*
|
||||||
|
* @param callback Finishing callback
|
||||||
|
* @param delay Delay for determining stability
|
||||||
|
*/
|
||||||
|
public void done(Runnable callback, long delay) {
|
||||||
|
if (finish != null) finish.cancel();
|
||||||
|
(finish = new Timer("SubServers.Bungee::Fallback_Limbo_Timer(" + player + ')')).schedule(new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (callback != null) callback.run();
|
||||||
|
finish.cancel();
|
||||||
|
}
|
||||||
|
}, delay);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,209 @@
|
||||||
|
package net.ME1312.SubServers.Bungee.Library.Fallback;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
|
import net.ME1312.Galaxi.Library.Try;
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
|
import net.ME1312.SubServers.Bungee.BungeeCommon;
|
||||||
|
|
||||||
|
import net.md_5.bungee.UserConnection;
|
||||||
|
import net.md_5.bungee.api.AbstractReconnectHandler;
|
||||||
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
import net.md_5.bungee.api.ReconnectHandler;
|
||||||
|
import net.md_5.bungee.api.config.ListenerInfo;
|
||||||
|
import net.md_5.bungee.api.config.ServerInfo;
|
||||||
|
import net.md_5.bungee.api.connection.PendingConnection;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smart Fallback Handler Class
|
||||||
|
*/
|
||||||
|
public class SmartFallback implements ReconnectHandler {
|
||||||
|
private static List<FallbackInspector> inspectors = new CopyOnWriteArrayList<FallbackInspector>();
|
||||||
|
private static ReconnectHandler reconnect;
|
||||||
|
public static boolean dns_forward = false;
|
||||||
|
|
||||||
|
public SmartFallback(ObjectMap<String> settings) {
|
||||||
|
dns_forward = settings.getBoolean("DNS-Forward", false);
|
||||||
|
if (reconnect == null && settings.getBoolean("Reconnect", false))
|
||||||
|
reconnect = Try.all.get(() -> Util.reflect(ProxyServer.getInstance().getPluginManager().getPlugin("reconnect_yaml").getClass().getClassLoader().loadClass("net.md_5.bungee.module.reconnect.yaml.YamlReconnectHandler").getConstructor()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServerInfo getServer(ProxiedPlayer player) {
|
||||||
|
return getServer(player, player instanceof UserConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ServerInfo getServer(ProxiedPlayer player, boolean queue) {
|
||||||
|
ServerInfo override;
|
||||||
|
if ((override = getForcedHost(player.getPendingConnection())) != null
|
||||||
|
|| (override = getDNS(player.getPendingConnection())) != null) {
|
||||||
|
if (queue) ((UserConnection) player).setServerJoinQueue(new LinkedList<>());
|
||||||
|
return override;
|
||||||
|
} else {
|
||||||
|
Map<String, ServerInfo> fallbacks = getFallbackServers(player.getPendingConnection().getListener(), player);
|
||||||
|
|
||||||
|
if ((override = getReconnectServer(player)) != null || !fallbacks.isEmpty()) {
|
||||||
|
if (queue) ((UserConnection) player).setServerJoinQueue(new LinkedList<>(fallbacks.keySet()));
|
||||||
|
return (override != null)? override : new LinkedList<>(fallbacks.values()).getFirst();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grabs the Forced Host Server for this connection
|
||||||
|
*
|
||||||
|
* @see AbstractReconnectHandler#getForcedHost(PendingConnection) Essentially the same method, but more ambigous
|
||||||
|
* @param connection Connection to check
|
||||||
|
* @return Forced Host Server (or null if there is none)
|
||||||
|
*/
|
||||||
|
public static ServerInfo getForcedHost(PendingConnection connection) {
|
||||||
|
if (connection.getVirtualHost() == null) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
String forced = connection.getListener().getForcedHosts().get(connection.getVirtualHost().getHostString());
|
||||||
|
//if (forced == null && con.getListener().isForceDefault()) { // This is the part of the method that made it ambiguous
|
||||||
|
// forced = con.getListener().getDefaultServer(); // Aside from that, everything else was fine
|
||||||
|
//} // :(
|
||||||
|
|
||||||
|
return ProxyServer.getInstance().getServerInfo(forced);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grabs the Server that a connection's DNS matches
|
||||||
|
*
|
||||||
|
* @param connection Connection to check
|
||||||
|
* @return DNS Forward Server
|
||||||
|
*/
|
||||||
|
public static ServerInfo getDNS(PendingConnection connection) {
|
||||||
|
if (connection.getVirtualHost() == null || !dns_forward) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
Map.Entry<String, ServerInfo> server = null;
|
||||||
|
String dns = connection.getVirtualHost().getHostString().toLowerCase();
|
||||||
|
for (Map.Entry<String, ServerInfo> s : ((BungeeCommon) ProxyServer.getInstance()).getServersCopy().entrySet()) {
|
||||||
|
if (dns.startsWith(s.getKey().toLowerCase() + '.'))
|
||||||
|
if (server == null || server.getKey().length() < s.getKey().length())
|
||||||
|
server = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (server == null)?null:server.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grabs the Server that a player was last connected to
|
||||||
|
*
|
||||||
|
* @param player Player
|
||||||
|
* @return Reconnect Server
|
||||||
|
*/
|
||||||
|
public static ServerInfo getReconnectServer(ProxiedPlayer player) {
|
||||||
|
if (reconnect == null) {
|
||||||
|
return null;
|
||||||
|
} else try {
|
||||||
|
return Util.reflect(reconnect.getClass().getDeclaredMethod("getStoredServer", ProxiedPlayer.class), reconnect, player);
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a <i>smart</i> sorted map of fallback servers using a generated confidence score
|
||||||
|
*
|
||||||
|
* @param listener Listener to grab fallback servers from
|
||||||
|
* @return Fallback Server Map (with legacy bungee case-sensitive keys)
|
||||||
|
*/
|
||||||
|
public static Map<String, ServerInfo> getFallbackServers(ListenerInfo listener) {
|
||||||
|
return getFallbackServers(listener, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a <i>smart</i> sorted map of fallback servers using a generated confidence score
|
||||||
|
*
|
||||||
|
* @param listener Listener to grab fallback servers from
|
||||||
|
* @param player Player that is requesting fallback servers
|
||||||
|
* @return Fallback Server Map (with legacy bungee case-sensitive keys)
|
||||||
|
*/
|
||||||
|
public static Map<String, ServerInfo> getFallbackServers(ListenerInfo listener, ProxiedPlayer player) {
|
||||||
|
TreeMap<Double, List<ServerInfo>> score = new TreeMap<Double, List<ServerInfo>>(Collections.reverseOrder());
|
||||||
|
for (String name : listener.getServerPriority()) {
|
||||||
|
ServerInfo server = ProxyServer.getInstance().getServerInfo(name);
|
||||||
|
if (server != null) {
|
||||||
|
boolean valid = true;
|
||||||
|
double confidence = 0;
|
||||||
|
|
||||||
|
List<FallbackInspector> inspectors = new ArrayList<FallbackInspector>();
|
||||||
|
inspectors.addAll(SmartFallback.inspectors);
|
||||||
|
for (FallbackInspector inspector : inspectors) try {
|
||||||
|
Double response = inspector.inspect(player, server);
|
||||||
|
if (response == null) {
|
||||||
|
valid = false;
|
||||||
|
} else {
|
||||||
|
confidence += response;
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
new InvocationTargetException(e, "Exception while running inspecting fallback server: " + server.getName()).printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid) {
|
||||||
|
List<ServerInfo> servers = (score.containsKey(confidence))?score.get(confidence):new LinkedList<ServerInfo>();
|
||||||
|
servers.add(server);
|
||||||
|
score.put(confidence, servers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Random random = new Random();
|
||||||
|
LinkedHashMap<String, ServerInfo> map = new LinkedHashMap<String, ServerInfo>();
|
||||||
|
for (List<ServerInfo> servers : score.values()) {
|
||||||
|
while (!servers.isEmpty()) {
|
||||||
|
ServerInfo next = servers.get(random.nextInt(servers.size()));
|
||||||
|
map.put(next.getName(), next);
|
||||||
|
servers.remove(next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a Fallback Server Inspector
|
||||||
|
*
|
||||||
|
* @param inspector Inspector
|
||||||
|
*/
|
||||||
|
public static void addInspector(FallbackInspector inspector) {
|
||||||
|
Util.nullpo(inspector);
|
||||||
|
inspectors.add(inspector);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a Fallback Server Inspector
|
||||||
|
*
|
||||||
|
* @param inspector Inspector
|
||||||
|
*/
|
||||||
|
public static void removeInspector(FallbackInspector inspector) {
|
||||||
|
Util.nullpo(inspector);
|
||||||
|
Try.all.run(() -> inspectors.remove(inspector));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setServer(ProxiedPlayer player) {
|
||||||
|
if (reconnect != null) reconnect.setServer(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void save() {
|
||||||
|
if (reconnect != null) reconnect.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
if (reconnect != null) reconnect.close();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,909 @@
|
||||||
|
package net.ME1312.SubServers.Bungee.Library;
|
||||||
|
|
||||||
|
import net.ME1312.SubServers.Bungee.BungeeAPI;
|
||||||
|
import net.ME1312.SubServers.Bungee.BungeeCommon;
|
||||||
|
|
||||||
|
import gnu.trove.map.hash.TIntObjectHashMap;
|
||||||
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
import net.md_5.bungee.api.plugin.Plugin;
|
||||||
|
import net.md_5.bungee.config.Configuration;
|
||||||
|
import net.md_5.bungee.config.ConfigurationProvider;
|
||||||
|
import net.md_5.bungee.config.YamlConfiguration;
|
||||||
|
import net.md_5.bungee.protocol.ProtocolConstants;
|
||||||
|
|
||||||
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
|
import java.io.*;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.zip.GZIPOutputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SubServers BStats Metrics Implementation
|
||||||
|
*/
|
||||||
|
public class Metrics {
|
||||||
|
|
||||||
|
private final Plugin plugin;
|
||||||
|
|
||||||
|
private final MetricsBase metricsBase;
|
||||||
|
|
||||||
|
private boolean enabled;
|
||||||
|
|
||||||
|
private String serverUUID;
|
||||||
|
|
||||||
|
private boolean logErrors = false;
|
||||||
|
|
||||||
|
private boolean logSentData;
|
||||||
|
|
||||||
|
private boolean logResponseStatusText;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Metrics instance.
|
||||||
|
*
|
||||||
|
* @param plugin Your plugin instance.
|
||||||
|
* @param serviceId The id of the service. It can be found at <a
|
||||||
|
* href="https://bstats.org/what-is-my-plugin-id">What is my plugin id?</a>
|
||||||
|
*/
|
||||||
|
public Metrics(Plugin plugin, int serviceId) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
try {
|
||||||
|
loadConfig();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// Failed to load configuration
|
||||||
|
plugin.getLogger().log(Level.WARNING, "Failed to load bStats config!", e);
|
||||||
|
metricsBase = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
metricsBase =
|
||||||
|
new MetricsBase(
|
||||||
|
"bungeecord",
|
||||||
|
serverUUID,
|
||||||
|
serviceId,
|
||||||
|
enabled,
|
||||||
|
this::appendPlatformData,
|
||||||
|
this::appendServiceData,
|
||||||
|
null,
|
||||||
|
() -> true,
|
||||||
|
(message, error) -> this.plugin.getLogger().log(Level.WARNING, message, error),
|
||||||
|
(message) -> this.plugin.getLogger().log(Level.INFO, message),
|
||||||
|
logErrors,
|
||||||
|
logSentData,
|
||||||
|
logResponseStatusText);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Loads the bStats configuration. */
|
||||||
|
private void loadConfig() throws IOException {
|
||||||
|
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
|
||||||
|
bStatsFolder.mkdirs();
|
||||||
|
File configFile = new File(bStatsFolder, "config.yml");
|
||||||
|
if (!configFile.exists()) {
|
||||||
|
writeFile(
|
||||||
|
configFile,
|
||||||
|
"# bStats (https://bStats.org) collects some basic information for plugin authors, like how",
|
||||||
|
"# many people use their plugin and their total player count. It's recommended to keep bStats",
|
||||||
|
"# enabled, but if you're not comfortable with this, you can turn this setting off. There is no",
|
||||||
|
"# performance penalty associated with having metrics enabled, and data sent to bStats is fully",
|
||||||
|
"# anonymous.",
|
||||||
|
"enabled: true",
|
||||||
|
"serverUuid: \"" + UUID.randomUUID() + "\"",
|
||||||
|
"logFailedRequests: false",
|
||||||
|
"logSentData: false",
|
||||||
|
"logResponseStatusText: false");
|
||||||
|
}
|
||||||
|
Configuration configuration =
|
||||||
|
ConfigurationProvider.getProvider(YamlConfiguration.class).load(configFile);
|
||||||
|
// Load configuration
|
||||||
|
enabled = configuration.getBoolean("enabled", true);
|
||||||
|
serverUUID = configuration.getString("serverUuid");
|
||||||
|
logErrors = configuration.getBoolean("logFailedRequests", false);
|
||||||
|
logSentData = configuration.getBoolean("logSentData", false);
|
||||||
|
logResponseStatusText = configuration.getBoolean("logResponseStatusText", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeFile(File file, String... lines) throws IOException {
|
||||||
|
try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file))) {
|
||||||
|
for (String line : lines) {
|
||||||
|
bufferedWriter.write(line);
|
||||||
|
bufferedWriter.newLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final AdvancedPie PLAYER_VERSIONS;
|
||||||
|
static {
|
||||||
|
final int[] PROTOCOL_VERSIONS;
|
||||||
|
final String[] PROTOCOL_NAMES;
|
||||||
|
{
|
||||||
|
TIntObjectHashMap<String> protocols = new TIntObjectHashMap<String>();
|
||||||
|
try {
|
||||||
|
for (Field f : ProtocolConstants.class.getDeclaredFields()) {
|
||||||
|
int fm = f.getModifiers();
|
||||||
|
if (Modifier.isPublic(fm) && Modifier.isStatic(fm) && Modifier.isFinal(fm) && f.getType() == int.class && f.getName().startsWith("MINECRAFT_")) {
|
||||||
|
protocols.put(f.getInt(null), f.getName().substring(10).replace('_', '.'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
PROTOCOL_VERSIONS = protocols.keys();
|
||||||
|
PROTOCOL_NAMES = new String[PROTOCOL_VERSIONS.length];
|
||||||
|
|
||||||
|
Arrays.sort(PROTOCOL_VERSIONS);
|
||||||
|
for (int i = 0; i < PROTOCOL_VERSIONS.length; ++i) {
|
||||||
|
PROTOCOL_NAMES[i] = protocols.get(PROTOCOL_VERSIONS[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PLAYER_VERSIONS = new AdvancedPie("player_versions", () -> {
|
||||||
|
int[] players = new int[PROTOCOL_VERSIONS.length];
|
||||||
|
for (ProxiedPlayer player : ProxyServer.getInstance().getPlayers()) {
|
||||||
|
int i = Arrays.binarySearch(PROTOCOL_VERSIONS, player.getPendingConnection().getVersion());
|
||||||
|
if (i != -1) {
|
||||||
|
++players[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HashMap<String, Integer> map = new HashMap<String, Integer>();
|
||||||
|
for (int i = 0; i < PROTOCOL_NAMES.length; ++i) if (players[i] != 0) {
|
||||||
|
map.put(PROTOCOL_NAMES[i], players[i]);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add subservers platform information as custom charts
|
||||||
|
*/
|
||||||
|
public Metrics addPlatformCharts() {
|
||||||
|
return addCustomChart(new SimplePie("subservers_version", () -> BungeeAPI.getInstance().getWrapperVersion().toString())).addCustomChart(PLAYER_VERSIONS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a custom chart.
|
||||||
|
*
|
||||||
|
* @param chart The chart to add.
|
||||||
|
*/
|
||||||
|
public Metrics addCustomChart(CustomChart chart) {
|
||||||
|
metricsBase.addCustomChart(chart);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendPlatformData(JsonObjectBuilder builder) {
|
||||||
|
builder.appendField("playerAmount", plugin.getProxy().getOnlineCount());
|
||||||
|
builder.appendField("managedServers", ((BungeeCommon) plugin.getProxy()).getServersCopy().size());
|
||||||
|
builder.appendField("onlineMode", plugin.getProxy().getConfig().isOnlineMode() ? 1 : 0);
|
||||||
|
builder.appendField("bungeecordVersion", plugin.getProxy().getVersion());
|
||||||
|
builder.appendField("javaVersion", System.getProperty("java.version"));
|
||||||
|
builder.appendField("osName", System.getProperty("os.name"));
|
||||||
|
builder.appendField("osArch", System.getProperty("os.arch"));
|
||||||
|
builder.appendField("osVersion", System.getProperty("os.version"));
|
||||||
|
builder.appendField("coreCount", Runtime.getRuntime().availableProcessors());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendServiceData(JsonObjectBuilder builder) {
|
||||||
|
builder.appendField("pluginVersion", plugin.getDescription().getVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class MetricsBase {
|
||||||
|
|
||||||
|
/** The version of the Metrics class. */
|
||||||
|
public static final String METRICS_VERSION = "3.0.0";
|
||||||
|
|
||||||
|
private static final ScheduledExecutorService scheduler =
|
||||||
|
Executors.newScheduledThreadPool(1, task -> new Thread(task, "bStats-Metrics"));
|
||||||
|
|
||||||
|
private static final String REPORT_URL = "https://bStats.org/api/v2/data/%s";
|
||||||
|
|
||||||
|
private final String platform;
|
||||||
|
|
||||||
|
private final String serverUuid;
|
||||||
|
|
||||||
|
private final int serviceId;
|
||||||
|
|
||||||
|
private final Consumer<JsonObjectBuilder> appendPlatformDataConsumer;
|
||||||
|
|
||||||
|
private final Consumer<JsonObjectBuilder> appendServiceDataConsumer;
|
||||||
|
|
||||||
|
private final Consumer<Runnable> submitTaskConsumer;
|
||||||
|
|
||||||
|
private final Supplier<Boolean> checkServiceEnabledSupplier;
|
||||||
|
|
||||||
|
private final BiConsumer<String, Throwable> errorLogger;
|
||||||
|
|
||||||
|
private final Consumer<String> infoLogger;
|
||||||
|
|
||||||
|
private final boolean logErrors;
|
||||||
|
|
||||||
|
private final boolean logSentData;
|
||||||
|
|
||||||
|
private final boolean logResponseStatusText;
|
||||||
|
|
||||||
|
private final Set<CustomChart> customCharts = new HashSet<>();
|
||||||
|
|
||||||
|
private final boolean enabled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new MetricsBase class instance.
|
||||||
|
*
|
||||||
|
* @param platform The platform of the service.
|
||||||
|
* @param serviceId The id of the service.
|
||||||
|
* @param serverUuid The server uuid.
|
||||||
|
* @param enabled Whether or not data sending is enabled.
|
||||||
|
* @param appendPlatformDataConsumer A consumer that receives a {@code JsonObjectBuilder} and
|
||||||
|
* appends all platform-specific data.
|
||||||
|
* @param appendServiceDataConsumer A consumer that receives a {@code JsonObjectBuilder} and
|
||||||
|
* appends all service-specific data.
|
||||||
|
* @param submitTaskConsumer A consumer that takes a runnable with the submit task. This can be
|
||||||
|
* used to delegate the data collection to a another thread to prevent errors caused by
|
||||||
|
* concurrency. Can be {@code null}.
|
||||||
|
* @param checkServiceEnabledSupplier A supplier to check if the service is still enabled.
|
||||||
|
* @param errorLogger A consumer that accepts log message and an error.
|
||||||
|
* @param infoLogger A consumer that accepts info log messages.
|
||||||
|
* @param logErrors Whether or not errors should be logged.
|
||||||
|
* @param logSentData Whether or not the sent data should be logged.
|
||||||
|
* @param logResponseStatusText Whether or not the response status text should be logged.
|
||||||
|
*/
|
||||||
|
public MetricsBase(
|
||||||
|
String platform,
|
||||||
|
String serverUuid,
|
||||||
|
int serviceId,
|
||||||
|
boolean enabled,
|
||||||
|
Consumer<JsonObjectBuilder> appendPlatformDataConsumer,
|
||||||
|
Consumer<JsonObjectBuilder> appendServiceDataConsumer,
|
||||||
|
Consumer<Runnable> submitTaskConsumer,
|
||||||
|
Supplier<Boolean> checkServiceEnabledSupplier,
|
||||||
|
BiConsumer<String, Throwable> errorLogger,
|
||||||
|
Consumer<String> infoLogger,
|
||||||
|
boolean logErrors,
|
||||||
|
boolean logSentData,
|
||||||
|
boolean logResponseStatusText) {
|
||||||
|
this.platform = platform;
|
||||||
|
this.serverUuid = serverUuid;
|
||||||
|
this.serviceId = serviceId;
|
||||||
|
this.enabled = enabled;
|
||||||
|
this.appendPlatformDataConsumer = appendPlatformDataConsumer;
|
||||||
|
this.appendServiceDataConsumer = appendServiceDataConsumer;
|
||||||
|
this.submitTaskConsumer = submitTaskConsumer;
|
||||||
|
this.checkServiceEnabledSupplier = checkServiceEnabledSupplier;
|
||||||
|
this.errorLogger = errorLogger;
|
||||||
|
this.infoLogger = infoLogger;
|
||||||
|
this.logErrors = logErrors;
|
||||||
|
this.logSentData = logSentData;
|
||||||
|
this.logResponseStatusText = logResponseStatusText;
|
||||||
|
checkRelocation();
|
||||||
|
if (enabled) {
|
||||||
|
// WARNING: Removing the option to opt-out will get your plugin banned from bStats
|
||||||
|
startSubmitting();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addCustomChart(CustomChart chart) {
|
||||||
|
this.customCharts.add(chart);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startSubmitting() {
|
||||||
|
final Runnable submitTask =
|
||||||
|
() -> {
|
||||||
|
if (!enabled || !checkServiceEnabledSupplier.get()) {
|
||||||
|
// Submitting data or service is disabled
|
||||||
|
scheduler.shutdown();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (submitTaskConsumer != null) {
|
||||||
|
submitTaskConsumer.accept(this::submitData);
|
||||||
|
} else {
|
||||||
|
this.submitData();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Many servers tend to restart at a fixed time at xx:00 which causes an uneven distribution
|
||||||
|
// of requests on the
|
||||||
|
// bStats backend. To circumvent this problem, we introduce some randomness into the initial
|
||||||
|
// and second delay.
|
||||||
|
// WARNING: You must not modify and part of this Metrics class, including the submit delay or
|
||||||
|
// frequency!
|
||||||
|
// WARNING: Modifying this code will get your plugin banned on bStats. Just don't do it!
|
||||||
|
long initialDelay = (long) (1000 * 60 * (3 + Math.random() * 3));
|
||||||
|
long secondDelay = (long) (1000 * 60 * (Math.random() * 30));
|
||||||
|
scheduler.schedule(submitTask, initialDelay, TimeUnit.MILLISECONDS);
|
||||||
|
scheduler.scheduleAtFixedRate(
|
||||||
|
submitTask, initialDelay + secondDelay, 1000 * 60 * 30, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void submitData() {
|
||||||
|
final JsonObjectBuilder baseJsonBuilder = new JsonObjectBuilder();
|
||||||
|
appendPlatformDataConsumer.accept(baseJsonBuilder);
|
||||||
|
final JsonObjectBuilder serviceJsonBuilder = new JsonObjectBuilder();
|
||||||
|
appendServiceDataConsumer.accept(serviceJsonBuilder);
|
||||||
|
JsonObjectBuilder.JsonObject[] chartData =
|
||||||
|
customCharts.stream()
|
||||||
|
.map(customChart -> customChart.getRequestJsonObject(errorLogger, logErrors))
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.toArray(JsonObjectBuilder.JsonObject[]::new);
|
||||||
|
serviceJsonBuilder.appendField("id", serviceId);
|
||||||
|
serviceJsonBuilder.appendField("customCharts", chartData);
|
||||||
|
baseJsonBuilder.appendField("service", serviceJsonBuilder.build());
|
||||||
|
baseJsonBuilder.appendField("serverUUID", serverUuid);
|
||||||
|
baseJsonBuilder.appendField("metricsVersion", METRICS_VERSION);
|
||||||
|
JsonObjectBuilder.JsonObject data = baseJsonBuilder.build();
|
||||||
|
scheduler.execute(
|
||||||
|
() -> {
|
||||||
|
try {
|
||||||
|
// Send the data
|
||||||
|
sendData(data);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Something went wrong! :(
|
||||||
|
if (logErrors) {
|
||||||
|
errorLogger.accept("Could not submit bStats metrics data", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendData(JsonObjectBuilder.JsonObject data) throws Exception {
|
||||||
|
if (logSentData) {
|
||||||
|
infoLogger.accept("Sent bStats metrics data: " + data.toString());
|
||||||
|
}
|
||||||
|
String url = String.format(REPORT_URL, platform);
|
||||||
|
HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();
|
||||||
|
// Compress the data to save bandwidth
|
||||||
|
byte[] compressedData = compress(data.toString());
|
||||||
|
connection.setRequestMethod("POST");
|
||||||
|
connection.addRequestProperty("Accept", "application/json");
|
||||||
|
connection.addRequestProperty("Connection", "close");
|
||||||
|
connection.addRequestProperty("Content-Encoding", "gzip");
|
||||||
|
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
|
||||||
|
connection.setRequestProperty("Content-Type", "application/json");
|
||||||
|
connection.setRequestProperty("User-Agent", "Metrics-Service/1");
|
||||||
|
connection.setDoOutput(true);
|
||||||
|
try (DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())) {
|
||||||
|
outputStream.write(compressedData);
|
||||||
|
}
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
try (BufferedReader bufferedReader =
|
||||||
|
new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
|
||||||
|
String line;
|
||||||
|
while ((line = bufferedReader.readLine()) != null) {
|
||||||
|
builder.append(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (logResponseStatusText) {
|
||||||
|
infoLogger.accept("Sent data to bStats and received response: " + builder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Checks that the class was properly relocated. */
|
||||||
|
private void checkRelocation() {
|
||||||
|
// You can use the property to disable the check in your test environment
|
||||||
|
if (System.getProperty("bstats.relocatecheck") == null
|
||||||
|
|| !System.getProperty("bstats.relocatecheck").equals("false")) {
|
||||||
|
// Maven's Relocate is clever and changes strings, too. So we have to use this little
|
||||||
|
// "trick" ... :D
|
||||||
|
final String defaultPackage =
|
||||||
|
new String(new byte[] {'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's'});
|
||||||
|
final String examplePackage =
|
||||||
|
new String(new byte[] {'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
|
||||||
|
// We want to make sure no one just copy & pastes the example and uses the wrong package
|
||||||
|
// names
|
||||||
|
if (MetricsBase.class.getPackage().getName().startsWith(defaultPackage)
|
||||||
|
|| MetricsBase.class.getPackage().getName().startsWith(examplePackage)) {
|
||||||
|
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gzips the given string.
|
||||||
|
*
|
||||||
|
* @param str The string to gzip.
|
||||||
|
* @return The gzipped string.
|
||||||
|
*/
|
||||||
|
private static byte[] compress(final String str) throws IOException {
|
||||||
|
if (str == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
try (GZIPOutputStream gzip = new GZIPOutputStream(outputStream)) {
|
||||||
|
gzip.write(str.getBytes(StandardCharsets.UTF_8));
|
||||||
|
}
|
||||||
|
return outputStream.toByteArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class DrilldownPie extends CustomChart {
|
||||||
|
|
||||||
|
private final Callable<Map<String, Map<String, Integer>>> callable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor.
|
||||||
|
*
|
||||||
|
* @param chartId The id of the chart.
|
||||||
|
* @param callable The callable which is used to request the chart data.
|
||||||
|
*/
|
||||||
|
public DrilldownPie(String chartId, Callable<Map<String, Map<String, Integer>>> callable) {
|
||||||
|
super(chartId);
|
||||||
|
this.callable = callable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||||
|
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
|
||||||
|
Map<String, Map<String, Integer>> map = callable.call();
|
||||||
|
if (map == null || map.isEmpty()) {
|
||||||
|
// Null = skip the chart
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
boolean reallyAllSkipped = true;
|
||||||
|
for (Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet()) {
|
||||||
|
JsonObjectBuilder valueBuilder = new JsonObjectBuilder();
|
||||||
|
boolean allSkipped = true;
|
||||||
|
for (Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet()) {
|
||||||
|
valueBuilder.appendField(valueEntry.getKey(), valueEntry.getValue());
|
||||||
|
allSkipped = false;
|
||||||
|
}
|
||||||
|
if (!allSkipped) {
|
||||||
|
reallyAllSkipped = false;
|
||||||
|
valuesBuilder.appendField(entryValues.getKey(), valueBuilder.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (reallyAllSkipped) {
|
||||||
|
// Null = skip the chart
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class AdvancedPie extends CustomChart {
|
||||||
|
|
||||||
|
private final Callable<Map<String, Integer>> callable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor.
|
||||||
|
*
|
||||||
|
* @param chartId The id of the chart.
|
||||||
|
* @param callable The callable which is used to request the chart data.
|
||||||
|
*/
|
||||||
|
public AdvancedPie(String chartId, Callable<Map<String, Integer>> callable) {
|
||||||
|
super(chartId);
|
||||||
|
this.callable = callable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||||
|
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
|
||||||
|
Map<String, Integer> map = callable.call();
|
||||||
|
if (map == null || map.isEmpty()) {
|
||||||
|
// Null = skip the chart
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
boolean allSkipped = true;
|
||||||
|
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||||
|
if (entry.getValue() == 0) {
|
||||||
|
// Skip this invalid
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
allSkipped = false;
|
||||||
|
valuesBuilder.appendField(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
if (allSkipped) {
|
||||||
|
// Null = skip the chart
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class MultiLineChart extends CustomChart {
|
||||||
|
|
||||||
|
private final Callable<Map<String, Integer>> callable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor.
|
||||||
|
*
|
||||||
|
* @param chartId The id of the chart.
|
||||||
|
* @param callable The callable which is used to request the chart data.
|
||||||
|
*/
|
||||||
|
public MultiLineChart(String chartId, Callable<Map<String, Integer>> callable) {
|
||||||
|
super(chartId);
|
||||||
|
this.callable = callable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||||
|
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
|
||||||
|
Map<String, Integer> map = callable.call();
|
||||||
|
if (map == null || map.isEmpty()) {
|
||||||
|
// Null = skip the chart
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
boolean allSkipped = true;
|
||||||
|
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||||
|
if (entry.getValue() == 0) {
|
||||||
|
// Skip this invalid
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
allSkipped = false;
|
||||||
|
valuesBuilder.appendField(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
if (allSkipped) {
|
||||||
|
// Null = skip the chart
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SimpleBarChart extends CustomChart {
|
||||||
|
|
||||||
|
private final Callable<Map<String, Integer>> callable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor.
|
||||||
|
*
|
||||||
|
* @param chartId The id of the chart.
|
||||||
|
* @param callable The callable which is used to request the chart data.
|
||||||
|
*/
|
||||||
|
public SimpleBarChart(String chartId, Callable<Map<String, Integer>> callable) {
|
||||||
|
super(chartId);
|
||||||
|
this.callable = callable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||||
|
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
|
||||||
|
Map<String, Integer> map = callable.call();
|
||||||
|
if (map == null || map.isEmpty()) {
|
||||||
|
// Null = skip the chart
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||||
|
valuesBuilder.appendField(entry.getKey(), new int[] {entry.getValue()});
|
||||||
|
}
|
||||||
|
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract static class CustomChart {
|
||||||
|
|
||||||
|
private final String chartId;
|
||||||
|
|
||||||
|
protected CustomChart(String chartId) {
|
||||||
|
if (chartId == null) {
|
||||||
|
throw new IllegalArgumentException("chartId must not be null");
|
||||||
|
}
|
||||||
|
this.chartId = chartId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonObjectBuilder.JsonObject getRequestJsonObject(
|
||||||
|
BiConsumer<String, Throwable> errorLogger, boolean logErrors) {
|
||||||
|
JsonObjectBuilder builder = new JsonObjectBuilder();
|
||||||
|
builder.appendField("chartId", chartId);
|
||||||
|
try {
|
||||||
|
JsonObjectBuilder.JsonObject data = getChartData();
|
||||||
|
if (data == null) {
|
||||||
|
// If the data is null we don't send the chart.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
builder.appendField("data", data);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
if (logErrors) {
|
||||||
|
errorLogger.accept("Failed to get data for custom chart with id " + chartId, t);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract JsonObjectBuilder.JsonObject getChartData() throws Exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SimplePie extends CustomChart {
|
||||||
|
|
||||||
|
private final Callable<String> callable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor.
|
||||||
|
*
|
||||||
|
* @param chartId The id of the chart.
|
||||||
|
* @param callable The callable which is used to request the chart data.
|
||||||
|
*/
|
||||||
|
public SimplePie(String chartId, Callable<String> callable) {
|
||||||
|
super(chartId);
|
||||||
|
this.callable = callable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||||
|
String value = callable.call();
|
||||||
|
if (value == null || value.isEmpty()) {
|
||||||
|
// Null = skip the chart
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new JsonObjectBuilder().appendField("value", value).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class AdvancedBarChart extends CustomChart {
|
||||||
|
|
||||||
|
private final Callable<Map<String, int[]>> callable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor.
|
||||||
|
*
|
||||||
|
* @param chartId The id of the chart.
|
||||||
|
* @param callable The callable which is used to request the chart data.
|
||||||
|
*/
|
||||||
|
public AdvancedBarChart(String chartId, Callable<Map<String, int[]>> callable) {
|
||||||
|
super(chartId);
|
||||||
|
this.callable = callable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||||
|
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
|
||||||
|
Map<String, int[]> map = callable.call();
|
||||||
|
if (map == null || map.isEmpty()) {
|
||||||
|
// Null = skip the chart
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
boolean allSkipped = true;
|
||||||
|
for (Map.Entry<String, int[]> entry : map.entrySet()) {
|
||||||
|
if (entry.getValue().length == 0) {
|
||||||
|
// Skip this invalid
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
allSkipped = false;
|
||||||
|
valuesBuilder.appendField(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
if (allSkipped) {
|
||||||
|
// Null = skip the chart
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SingleLineChart extends CustomChart {
|
||||||
|
|
||||||
|
private final Callable<Integer> callable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor.
|
||||||
|
*
|
||||||
|
* @param chartId The id of the chart.
|
||||||
|
* @param callable The callable which is used to request the chart data.
|
||||||
|
*/
|
||||||
|
public SingleLineChart(String chartId, Callable<Integer> callable) {
|
||||||
|
super(chartId);
|
||||||
|
this.callable = callable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||||
|
int value = callable.call();
|
||||||
|
if (value == 0) {
|
||||||
|
// Null = skip the chart
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new JsonObjectBuilder().appendField("value", value).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An extremely simple JSON builder.
|
||||||
|
*
|
||||||
|
* <p>While this class is neither feature-rich nor the most performant one, it's sufficient enough
|
||||||
|
* for its use-case.
|
||||||
|
*/
|
||||||
|
public static class JsonObjectBuilder {
|
||||||
|
|
||||||
|
private StringBuilder builder = new StringBuilder();
|
||||||
|
|
||||||
|
private boolean hasAtLeastOneField = false;
|
||||||
|
|
||||||
|
public JsonObjectBuilder() {
|
||||||
|
builder.append("{");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends a null field to the JSON.
|
||||||
|
*
|
||||||
|
* @param key The key of the field.
|
||||||
|
* @return A reference to this object.
|
||||||
|
*/
|
||||||
|
public JsonObjectBuilder appendNull(String key) {
|
||||||
|
appendFieldUnescaped(key, "null");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends a string field to the JSON.
|
||||||
|
*
|
||||||
|
* @param key The key of the field.
|
||||||
|
* @param value The value of the field.
|
||||||
|
* @return A reference to this object.
|
||||||
|
*/
|
||||||
|
public JsonObjectBuilder appendField(String key, String value) {
|
||||||
|
if (value == null) {
|
||||||
|
throw new IllegalArgumentException("JSON value must not be null");
|
||||||
|
}
|
||||||
|
appendFieldUnescaped(key, "\"" + escape(value) + "\"");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends an integer field to the JSON.
|
||||||
|
*
|
||||||
|
* @param key The key of the field.
|
||||||
|
* @param value The value of the field.
|
||||||
|
* @return A reference to this object.
|
||||||
|
*/
|
||||||
|
public JsonObjectBuilder appendField(String key, int value) {
|
||||||
|
appendFieldUnescaped(key, String.valueOf(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends an object to the JSON.
|
||||||
|
*
|
||||||
|
* @param key The key of the field.
|
||||||
|
* @param object The object.
|
||||||
|
* @return A reference to this object.
|
||||||
|
*/
|
||||||
|
public JsonObjectBuilder appendField(String key, JsonObject object) {
|
||||||
|
if (object == null) {
|
||||||
|
throw new IllegalArgumentException("JSON object must not be null");
|
||||||
|
}
|
||||||
|
appendFieldUnescaped(key, object.toString());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends a string array to the JSON.
|
||||||
|
*
|
||||||
|
* @param key The key of the field.
|
||||||
|
* @param values The string array.
|
||||||
|
* @return A reference to this object.
|
||||||
|
*/
|
||||||
|
public JsonObjectBuilder appendField(String key, String[] values) {
|
||||||
|
if (values == null) {
|
||||||
|
throw new IllegalArgumentException("JSON values must not be null");
|
||||||
|
}
|
||||||
|
String escapedValues =
|
||||||
|
Arrays.stream(values)
|
||||||
|
.map(value -> "\"" + escape(value) + "\"")
|
||||||
|
.collect(Collectors.joining(","));
|
||||||
|
appendFieldUnescaped(key, "[" + escapedValues + "]");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends an integer array to the JSON.
|
||||||
|
*
|
||||||
|
* @param key The key of the field.
|
||||||
|
* @param values The integer array.
|
||||||
|
* @return A reference to this object.
|
||||||
|
*/
|
||||||
|
public JsonObjectBuilder appendField(String key, int[] values) {
|
||||||
|
if (values == null) {
|
||||||
|
throw new IllegalArgumentException("JSON values must not be null");
|
||||||
|
}
|
||||||
|
String escapedValues =
|
||||||
|
Arrays.stream(values).mapToObj(String::valueOf).collect(Collectors.joining(","));
|
||||||
|
appendFieldUnescaped(key, "[" + escapedValues + "]");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends an object array to the JSON.
|
||||||
|
*
|
||||||
|
* @param key The key of the field.
|
||||||
|
* @param values The integer array.
|
||||||
|
* @return A reference to this object.
|
||||||
|
*/
|
||||||
|
public JsonObjectBuilder appendField(String key, JsonObject[] values) {
|
||||||
|
if (values == null) {
|
||||||
|
throw new IllegalArgumentException("JSON values must not be null");
|
||||||
|
}
|
||||||
|
String escapedValues =
|
||||||
|
Arrays.stream(values).map(JsonObject::toString).collect(Collectors.joining(","));
|
||||||
|
appendFieldUnescaped(key, "[" + escapedValues + "]");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends a field to the object.
|
||||||
|
*
|
||||||
|
* @param key The key of the field.
|
||||||
|
* @param escapedValue The escaped value of the field.
|
||||||
|
*/
|
||||||
|
private void appendFieldUnescaped(String key, String escapedValue) {
|
||||||
|
if (builder == null) {
|
||||||
|
throw new IllegalStateException("JSON has already been built");
|
||||||
|
}
|
||||||
|
if (key == null) {
|
||||||
|
throw new IllegalArgumentException("JSON key must not be null");
|
||||||
|
}
|
||||||
|
if (hasAtLeastOneField) {
|
||||||
|
builder.append(",");
|
||||||
|
}
|
||||||
|
builder.append("\"").append(escape(key)).append("\":").append(escapedValue);
|
||||||
|
hasAtLeastOneField = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the JSON string and invalidates this builder.
|
||||||
|
*
|
||||||
|
* @return The built JSON string.
|
||||||
|
*/
|
||||||
|
public JsonObject build() {
|
||||||
|
if (builder == null) {
|
||||||
|
throw new IllegalStateException("JSON has already been built");
|
||||||
|
}
|
||||||
|
JsonObject object = new JsonObject(builder.append("}").toString());
|
||||||
|
builder = null;
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escapes the given string like stated in https://www.ietf.org/rfc/rfc4627.txt.
|
||||||
|
*
|
||||||
|
* <p>This method escapes only the necessary characters '"', '\'. and '\u0000' - '\u001F'.
|
||||||
|
* Compact escapes are not used (e.g., '\n' is escaped as "\u000a" and not as "\n").
|
||||||
|
*
|
||||||
|
* @param value The value to escape.
|
||||||
|
* @return The escaped value.
|
||||||
|
*/
|
||||||
|
private static String escape(String value) {
|
||||||
|
final StringBuilder builder = new StringBuilder();
|
||||||
|
for (int i = 0; i < value.length(); i++) {
|
||||||
|
char c = value.charAt(i);
|
||||||
|
if (c == '"') {
|
||||||
|
builder.append("\\\"");
|
||||||
|
} else if (c == '\\') {
|
||||||
|
builder.append("\\\\");
|
||||||
|
} else if (c <= '\u000F') {
|
||||||
|
builder.append("\\u000").append(Integer.toHexString(c));
|
||||||
|
} else if (c <= '\u001F') {
|
||||||
|
builder.append("\\u00").append(Integer.toHexString(c));
|
||||||
|
} else {
|
||||||
|
builder.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A super simple representation of a JSON object.
|
||||||
|
*
|
||||||
|
* <p>This class only exists to make methods of the {@link JsonObjectBuilder} type-safe and not
|
||||||
|
* allow a raw string inputs for methods like {@link JsonObjectBuilder#appendField(String,
|
||||||
|
* JsonObject)}.
|
||||||
|
*/
|
||||||
|
public static class JsonObject {
|
||||||
|
|
||||||
|
private final String value;
|
||||||
|
|
||||||
|
private JsonObject(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,5 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
<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">
|
||||||
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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<groupId>net.ME1312.SubServers</groupId>
|
<groupId>net.ME1312.SubServers</groupId>
|
||||||
|
@ -16,7 +14,7 @@
|
||||||
</repository>
|
</repository>
|
||||||
<repository>
|
<repository>
|
||||||
<id>me1312-repo</id>
|
<id>me1312-repo</id>
|
||||||
<url>https://src.me1312.net/maven</url>
|
<url>https://dev.me1312.net/maven</url>
|
||||||
</repository>
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
|
|
||||||
|
@ -24,13 +22,19 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md_5</groupId>
|
<groupId>net.md_5</groupId>
|
||||||
<artifactId>bungeecord-internal</artifactId>
|
<artifactId>bungeecord-internal</artifactId>
|
||||||
<version>1.9-SNAPSHOT</version>
|
<version>1.15-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.msgpack</groupId>
|
<groupId>net.ME1312.SubServers</groupId>
|
||||||
<artifactId>msgpack-core</artifactId>
|
<artifactId>SubServers.Bungee.Common</artifactId>
|
||||||
<version>0.8.16</version>
|
<version>${project.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.ME1312.SubData</groupId>
|
||||||
|
<artifactId>Server</artifactId>
|
||||||
|
<version>23w08b</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -39,12 +43,6 @@
|
||||||
<version>1.1</version>
|
<version>1.1</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>com.imaginarycode.minecraft</groupId>
|
|
||||||
<artifactId>RedisBungee</artifactId>
|
|
||||||
<version>0.3.8-SNAPSHOT</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -73,6 +71,7 @@
|
||||||
<artifactId>maven-antrun-plugin</artifactId>
|
<artifactId>maven-antrun-plugin</artifactId>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
|
<id>process</id>
|
||||||
<phase>process-resources</phase>
|
<phase>process-resources</phase>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>run</goal>
|
<goal>run</goal>
|
||||||
|
@ -81,17 +80,42 @@
|
||||||
<tasks>
|
<tasks>
|
||||||
<mkdir dir="${project.build.directory}" />
|
<mkdir dir="${project.build.directory}" />
|
||||||
<copy file="${basedir}/../LICENSE" todir="${project.build.directory}/classes" />
|
<copy file="${basedir}/../LICENSE" todir="${project.build.directory}/classes" />
|
||||||
<copy file="${basedir}/../Artifacts/SubServers.Client.jar" tofile="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/client.jar" />
|
<mkdir dir="${basedir}/../Artifacts/Modulized" />
|
||||||
|
<copy file="${basedir}/../Artifacts/SubServers.Client.Universal.jar" tofile="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/client.jar" />
|
||||||
<mkdir dir="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/Templates" />
|
<mkdir dir="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/Templates" />
|
||||||
<zip basedir="${basedir}/../SubServers.Creator/src" destfile="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/Templates/forge.zip" includes="Forge/**" />
|
<zip basedir="${basedir}/../SubServers.Creator" destfile="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/Templates/forge.zip" includes="Forge/**" />
|
||||||
<zip basedir="${basedir}/../SubServers.Creator/src" destfile="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/Templates/spigot.zip" includes="Spigot/**" />
|
<zip basedir="${basedir}/../SubServers.Creator" destfile="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/Templates/purpur.zip" includes="Purpur/**" />
|
||||||
<zip basedir="${basedir}/../SubServers.Creator/src" destfile="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/Templates/sponge.zip" includes="Sponge/**" />
|
<zip basedir="${basedir}/../SubServers.Creator" destfile="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/Templates/spigot.zip" includes="Spigot/**" />
|
||||||
<zip basedir="${basedir}/../SubServers.Creator/src" destfile="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/Templates/vanilla.zip" includes="Vanilla/**" />
|
<zip basedir="${basedir}/../SubServers.Creator" destfile="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/Templates/sponge.zip" includes="Sponge/**" />
|
||||||
|
<zip basedir="${basedir}/../SubServers.Creator" destfile="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/Templates/vanilla.zip" includes="Vanilla/**" />
|
||||||
|
</tasks>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>verify</id>
|
||||||
|
<phase>verify</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>run</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<tasks> <!-- Dependency Stripped Jar for Testing -->
|
||||||
|
<jar destfile="${basedir}/../Artifacts/Modulized/SubServers.Bungee.jar" manifest="src/META-INF/MANIFEST.MOD.MF">
|
||||||
|
<zipfileset src="${basedir}/../Artifacts/SubServers.Bungee.jar" excludes="net/ME1312/Galaxi/** net/ME1312/SubData/**" />
|
||||||
|
</jar>
|
||||||
</tasks>
|
</tasks>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>3.2.0</version>
|
||||||
|
<configuration>
|
||||||
|
<finalName>SubServers.Bungee</finalName>
|
||||||
|
<outputDirectory>../Artifacts/Maven</outputDirectory>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-assembly-plugin</artifactId>
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
@ -102,9 +126,9 @@
|
||||||
<archive>
|
<archive>
|
||||||
<manifestFile>src/META-INF/MANIFEST.MF</manifestFile>
|
<manifestFile>src/META-INF/MANIFEST.MF</manifestFile>
|
||||||
</archive>
|
</archive>
|
||||||
<descriptorRefs>
|
<descriptors>
|
||||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
<descriptor>../SubServers.Client/Common/jar-with-some-dependencies.xml</descriptor>
|
||||||
</descriptorRefs>
|
</descriptors>
|
||||||
<appendAssemblyId>false</appendAssemblyId>
|
<appendAssemblyId>false</appendAssemblyId>
|
||||||
</configuration>
|
</configuration>
|
||||||
<executions>
|
<executions>
|
||||||
|
@ -128,16 +152,22 @@
|
||||||
<goal>javadoc</goal>
|
<goal>javadoc</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<windowtitle>SubServers.Bungee Javadoc</windowtitle>
|
<windowtitle>SubServers.Bungee</windowtitle>
|
||||||
<doctitle>SubServers.Bungee Javadoc</doctitle>
|
<doctitle>SubServers.Bungee ${project.version}</doctitle>
|
||||||
<show>public</show>
|
<show>protected</show>
|
||||||
<destDir>./</destDir>
|
<destDir>./</destDir>
|
||||||
<outputDirectory>${basedir}/../Javadoc/SubServers.Bungee</outputDirectory>
|
<outputDirectory>${basedir}/../Javadoc/SubServers.Bungee</outputDirectory>
|
||||||
<reportOutputDirectory>${basedir}/../Javadoc/SubServers.Bungee</reportOutputDirectory>
|
<reportOutputDirectory>${basedir}/../Javadoc/SubServers.Bungee</reportOutputDirectory>
|
||||||
<additionalOptions>-Xdoclint:none</additionalOptions>
|
<additionalOptions>-Xdoclint:none</additionalOptions>
|
||||||
<links>
|
<links>
|
||||||
|
<link>https://dev.me1312.net/jenkins/job/GalaxiEngine/javadoc/GalaxiBase/</link>
|
||||||
|
<link>https://dev.me1312.net/jenkins/job/SubData/javadoc/Server/</link>
|
||||||
<link>https://ci.md-5.net/job/BungeeCord/ws/api/target/apidocs/</link>
|
<link>https://ci.md-5.net/job/BungeeCord/ws/api/target/apidocs/</link>
|
||||||
</links>
|
</links>
|
||||||
|
<includeDependencySources>true</includeDependencySources>
|
||||||
|
<dependencySourceIncludes>
|
||||||
|
<dependencySourceInclude>net.ME1312.SubServers:SubServers.Bungee.Common:*</dependencySourceInclude>
|
||||||
|
</dependencySourceIncludes>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Manifest-Version: 1.0
|
||||||
|
Class-Path: libraries/GalaxiBase.jar libraries/SubDataServer.jar libraries/BungeeCord.jar
|
||||||
|
Main-Class: net.ME1312.SubServers.Bungee.Launch
|
||||||
|
Implementation-Title: SubServers.Bungee
|
|
@ -1,9 +1,9 @@
|
||||||
package net.ME1312.SubServers.Bungee.Event;
|
package net.ME1312.SubServers.Bungee.Event;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
import net.ME1312.SubServers.Bungee.Host.Host;
|
import net.ME1312.SubServers.Bungee.Host.Host;
|
||||||
import net.ME1312.SubServers.Bungee.Host.Server;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import net.md_5.bungee.api.plugin.Cancellable;
|
import net.md_5.bungee.api.plugin.Cancellable;
|
||||||
import net.md_5.bungee.api.plugin.Event;
|
import net.md_5.bungee.api.plugin.Event;
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ public class SubAddHostEvent extends Event implements SubEvent, Cancellable {
|
||||||
* @param host Host Being Added
|
* @param host Host Being Added
|
||||||
*/
|
*/
|
||||||
public SubAddHostEvent(UUID player, Host host) {
|
public SubAddHostEvent(UUID player, Host host) {
|
||||||
if (Util.isNull(host)) throw new NullPointerException();
|
Util.nullpo(host);
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.host = host;
|
this.host = host;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package net.ME1312.SubServers.Bungee.Event;
|
package net.ME1312.SubServers.Bungee.Event;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
import net.ME1312.SubServers.Bungee.Host.Proxy;
|
import net.ME1312.SubServers.Bungee.Host.Proxy;
|
||||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import net.md_5.bungee.api.plugin.Event;
|
import net.md_5.bungee.api.plugin.Event;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17,7 +18,7 @@ public class SubAddProxyEvent extends Event implements SubEvent {
|
||||||
* @param proxy Host Being Added
|
* @param proxy Host Being Added
|
||||||
*/
|
*/
|
||||||
public SubAddProxyEvent(Proxy proxy) {
|
public SubAddProxyEvent(Proxy proxy) {
|
||||||
if (Util.isNull(proxy)) throw new NullPointerException();
|
Util.nullpo(proxy);
|
||||||
this.proxy = proxy;
|
this.proxy = proxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
package net.ME1312.SubServers.Bungee.Event;
|
package net.ME1312.SubServers.Bungee.Event;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
import net.ME1312.SubServers.Bungee.Host.Host;
|
import net.ME1312.SubServers.Bungee.Host.Host;
|
||||||
import net.ME1312.SubServers.Bungee.Host.Server;
|
import net.ME1312.SubServers.Bungee.Host.Server;
|
||||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import net.md_5.bungee.api.plugin.Cancellable;
|
import net.md_5.bungee.api.plugin.Cancellable;
|
||||||
import net.md_5.bungee.api.plugin.Event;
|
import net.md_5.bungee.api.plugin.Event;
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ public class SubAddServerEvent extends Event implements SubEvent, Cancellable {
|
||||||
* @param server Server Starting
|
* @param server Server Starting
|
||||||
*/
|
*/
|
||||||
public SubAddServerEvent(UUID player, Host host, Server server) {
|
public SubAddServerEvent(UUID player, Host host, Server server) {
|
||||||
if (Util.isNull(server)) throw new NullPointerException();
|
Util.nullpo(server);
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.host = host;
|
this.host = host;
|
||||||
this.server = server;
|
this.server = server;
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
package net.ME1312.SubServers.Bungee.Event;
|
package net.ME1312.SubServers.Bungee.Event;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
|
import net.ME1312.Galaxi.Library.Version.Version;
|
||||||
import net.ME1312.SubServers.Bungee.Host.Host;
|
import net.ME1312.SubServers.Bungee.Host.Host;
|
||||||
import net.ME1312.SubServers.Bungee.Host.SubCreator;
|
import net.ME1312.SubServers.Bungee.Host.SubCreator;
|
||||||
|
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
||||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
|
||||||
import net.md_5.bungee.api.plugin.Cancellable;
|
import net.md_5.bungee.api.plugin.Cancellable;
|
||||||
import net.md_5.bungee.api.plugin.Event;
|
import net.md_5.bungee.api.plugin.Event;
|
||||||
|
|
||||||
|
@ -16,6 +18,7 @@ import java.util.UUID;
|
||||||
public class SubCreateEvent extends Event implements SubEvent, Cancellable {
|
public class SubCreateEvent extends Event implements SubEvent, Cancellable {
|
||||||
private boolean cancelled = false;
|
private boolean cancelled = false;
|
||||||
private UUID player;
|
private UUID player;
|
||||||
|
private SubServer update;
|
||||||
private Host host;
|
private Host host;
|
||||||
private String name;
|
private String name;
|
||||||
private SubCreator.ServerTemplate template;
|
private SubCreator.ServerTemplate template;
|
||||||
|
@ -33,7 +36,7 @@ public class SubCreateEvent extends Event implements SubEvent, Cancellable {
|
||||||
* @param port Server Port Number
|
* @param port Server Port Number
|
||||||
*/
|
*/
|
||||||
public SubCreateEvent(UUID player, Host host, String name, SubCreator.ServerTemplate template, Version version, int port) {
|
public SubCreateEvent(UUID player, Host host, String name, SubCreator.ServerTemplate template, Version version, int port) {
|
||||||
if (Util.isNull(host, name, template, version, port)) throw new NullPointerException();
|
Util.nullpo(host, name, template);
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.host = host;
|
this.host = host;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
@ -42,6 +45,25 @@ public class SubCreateEvent extends Event implements SubEvent, Cancellable {
|
||||||
this.port = port;
|
this.port = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server Create Event (as an Update)
|
||||||
|
*
|
||||||
|
* @param player Player Updating
|
||||||
|
* @param server Server to be Updated
|
||||||
|
* @param template Server Template
|
||||||
|
* @param version Server Version
|
||||||
|
*/
|
||||||
|
public SubCreateEvent(UUID player, SubServer server, SubCreator.ServerTemplate template, Version version) {
|
||||||
|
Util.nullpo(server);
|
||||||
|
this.player = player;
|
||||||
|
this.update = server;
|
||||||
|
this.name = server.getName();
|
||||||
|
this.host = server.getHost();
|
||||||
|
this.template = template;
|
||||||
|
this.version = version;
|
||||||
|
this.port = server.getAddress().getPort();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the Host the SubServer will run on
|
* Get the Host the SubServer will run on
|
||||||
*
|
*
|
||||||
|
@ -51,6 +73,24 @@ public class SubCreateEvent extends Event implements SubEvent, Cancellable {
|
||||||
return host;
|
return host;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if SubCreator is being run in update mode
|
||||||
|
*
|
||||||
|
* @return Update Mode Status
|
||||||
|
*/
|
||||||
|
public boolean isUpdate() {
|
||||||
|
return update != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Server that's being updated
|
||||||
|
*
|
||||||
|
* @return Updating Server
|
||||||
|
*/
|
||||||
|
public SubServer getUpdatingServer() {
|
||||||
|
return update;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the name the SubServer will use
|
* Get the name the SubServer will use
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
package net.ME1312.SubServers.Bungee.Event;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
|
import net.ME1312.Galaxi.Library.Version.Version;
|
||||||
|
import net.ME1312.SubServers.Bungee.Host.Host;
|
||||||
|
import net.ME1312.SubServers.Bungee.Host.SubCreator;
|
||||||
|
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
||||||
|
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.plugin.Event;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server Created Event
|
||||||
|
*/
|
||||||
|
public class SubCreatedEvent extends Event implements SubEvent {
|
||||||
|
private UUID player;
|
||||||
|
private SubServer server;
|
||||||
|
private boolean success;
|
||||||
|
private boolean update;
|
||||||
|
private Host host;
|
||||||
|
private String name;
|
||||||
|
private SubCreator.ServerTemplate template;
|
||||||
|
private Version version;
|
||||||
|
private int port;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server Created Event
|
||||||
|
*
|
||||||
|
* @param player Player Creating
|
||||||
|
* @param host Potential Host
|
||||||
|
* @param name Server Name
|
||||||
|
* @param template Server Template
|
||||||
|
* @param version Server Version
|
||||||
|
* @param port Server Port Number
|
||||||
|
* @param server Server Object
|
||||||
|
* @param update Update Mode Status
|
||||||
|
* @param success Success Status
|
||||||
|
*/
|
||||||
|
public SubCreatedEvent(UUID player, Host host, String name, SubCreator.ServerTemplate template, Version version, int port, SubServer server, boolean update, boolean success) {
|
||||||
|
Util.nullpo(host, name, template);
|
||||||
|
this.player = player;
|
||||||
|
this.host = host;
|
||||||
|
this.name = name;
|
||||||
|
this.template = template;
|
||||||
|
this.version = version;
|
||||||
|
this.port = port;
|
||||||
|
this.server = server;
|
||||||
|
this.update = update;
|
||||||
|
this.success = success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Host the SubServer runs on
|
||||||
|
*
|
||||||
|
* @return Host
|
||||||
|
*/
|
||||||
|
public Host getHost() {
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if SubCreator was being run in update mode
|
||||||
|
*
|
||||||
|
* @return Update Mode Status
|
||||||
|
*/
|
||||||
|
public boolean wasUpdate() {
|
||||||
|
return update;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if the operation was a success
|
||||||
|
*
|
||||||
|
* @return Success Status
|
||||||
|
*/
|
||||||
|
public boolean wasSuccessful() {
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Server that was created/updated
|
||||||
|
*
|
||||||
|
* @return Finished Server
|
||||||
|
*/
|
||||||
|
public SubServer getServer() {
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the name the SubServer used
|
||||||
|
*
|
||||||
|
* @return SubServer Name
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Template that was used
|
||||||
|
*
|
||||||
|
* @return Server Template
|
||||||
|
*/
|
||||||
|
public SubCreator.ServerTemplate getTemplate() {
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Version the Server used
|
||||||
|
*
|
||||||
|
* @return Server Version
|
||||||
|
*/
|
||||||
|
public Version getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Port the Server used
|
||||||
|
*
|
||||||
|
* @return Port Number
|
||||||
|
*/
|
||||||
|
public int getPort() {
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the player that triggered the Event
|
||||||
|
*
|
||||||
|
* @return The Player that triggered this Event or null if Console
|
||||||
|
*/
|
||||||
|
public UUID getPlayer() { return player; }
|
||||||
|
}
|
|
@ -1,11 +1,13 @@
|
||||||
package net.ME1312.SubServers.Bungee.Event;
|
package net.ME1312.SubServers.Bungee.Event;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Container.ContainedPair;
|
||||||
|
import net.ME1312.Galaxi.Library.Container.Pair;
|
||||||
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
|
import net.ME1312.Galaxi.Library.Map.ObjectMapValue;
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
import net.ME1312.SubServers.Bungee.Host.Server;
|
import net.ME1312.SubServers.Bungee.Host.Server;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLValue;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.NamedContainer;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import net.md_5.bungee.api.plugin.Cancellable;
|
import net.md_5.bungee.api.plugin.Cancellable;
|
||||||
import net.md_5.bungee.api.plugin.Event;
|
import net.md_5.bungee.api.plugin.Event;
|
||||||
|
|
||||||
|
@ -18,8 +20,7 @@ public class SubEditServerEvent extends Event implements SubEvent, Cancellable {
|
||||||
private boolean cancelled = false;
|
private boolean cancelled = false;
|
||||||
private UUID player;
|
private UUID player;
|
||||||
private Server server;
|
private Server server;
|
||||||
private NamedContainer<String, YAMLValue> edit;
|
private Pair<String, ObjectMapValue> edit;
|
||||||
private boolean perm;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Server Edit Event
|
* Server Edit Event
|
||||||
|
@ -27,16 +28,14 @@ public class SubEditServerEvent extends Event implements SubEvent, Cancellable {
|
||||||
* @param player Player Adding Server
|
* @param player Player Adding Server
|
||||||
* @param server Server to be Edited
|
* @param server Server to be Edited
|
||||||
* @param edit Edit to make
|
* @param edit Edit to make
|
||||||
* @param permanent If the change is permanent
|
|
||||||
*/
|
*/
|
||||||
public SubEditServerEvent(UUID player, Server server, NamedContainer<String, ?> edit, boolean permanent) {
|
public SubEditServerEvent(UUID player, Server server, Pair<String, ?> edit) {
|
||||||
if (Util.isNull(server, edit)) throw new NullPointerException();
|
Util.nullpo(server, edit);
|
||||||
YAMLSection section = new YAMLSection();
|
ObjectMap<String> section = new ObjectMap<String>();
|
||||||
section.set(".", edit.get());
|
section.set(".", edit.value());
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.edit = new NamedContainer<String, YAMLValue>(edit.name(), section.get("."));
|
this.edit = new ContainedPair<String, ObjectMapValue>(edit.key(), section.get("."));
|
||||||
this.perm = permanent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -58,19 +57,10 @@ public class SubEditServerEvent extends Event implements SubEvent, Cancellable {
|
||||||
*
|
*
|
||||||
* @return Edit to be made
|
* @return Edit to be made
|
||||||
*/
|
*/
|
||||||
public NamedContainer<String, YAMLValue> getEdit() {
|
public Pair<String, ObjectMapValue> getEdit() {
|
||||||
return edit;
|
return edit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets if the edit is permanent
|
|
||||||
*
|
|
||||||
* @return Permanent Status
|
|
||||||
*/
|
|
||||||
public boolean isPermanent() {
|
|
||||||
return perm;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the Cancelled Status
|
* Gets the Cancelled Status
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,28 +1,28 @@
|
||||||
package net.ME1312.SubServers.Bungee.Event;
|
package net.ME1312.SubServers.Bungee.Event;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
|
import net.ME1312.SubData.Server.DataClient;
|
||||||
|
import net.ME1312.SubData.Server.DataServer;
|
||||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.SubDataServer;
|
|
||||||
import net.md_5.bungee.api.plugin.Cancellable;
|
import net.md_5.bungee.api.plugin.Cancellable;
|
||||||
import net.md_5.bungee.api.plugin.Event;
|
import net.md_5.bungee.api.plugin.Event;
|
||||||
|
|
||||||
import java.net.InetAddress;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SubData Network Connect Event
|
* SubData Network Connect Event
|
||||||
*/
|
*/
|
||||||
public class SubNetworkConnectEvent extends Event implements SubEvent, Cancellable {
|
public class SubNetworkConnectEvent extends Event implements SubEvent, Cancellable {
|
||||||
private boolean cancelled = false;
|
private boolean cancelled = false;
|
||||||
private SubDataServer network;
|
private DataServer network;
|
||||||
private InetAddress address;
|
private DataClient client;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SubData Network Connect Event
|
* SubData Network Connect Event
|
||||||
*/
|
*/
|
||||||
public SubNetworkConnectEvent(SubDataServer network, InetAddress address) {
|
public SubNetworkConnectEvent(DataServer network, DataClient client) {
|
||||||
if (Util.isNull(network, address)) throw new NullPointerException();
|
Util.nullpo(network, client);
|
||||||
this.network = network;
|
this.network = network;
|
||||||
this.address = address;
|
this.client = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,17 +30,17 @@ public class SubNetworkConnectEvent extends Event implements SubEvent, Cancellab
|
||||||
*
|
*
|
||||||
* @return SubData Network
|
* @return SubData Network
|
||||||
*/
|
*/
|
||||||
public SubDataServer getNetwork() {
|
public DataServer getNetwork() {
|
||||||
return network;
|
return network;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the address of the connecting client
|
* Get the connecting client
|
||||||
*
|
*
|
||||||
* @return Client address
|
* @return Client
|
||||||
*/
|
*/
|
||||||
public InetAddress getAddress() {
|
public DataClient getClient() {
|
||||||
return address;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,25 +1,29 @@
|
||||||
package net.ME1312.SubServers.Bungee.Event;
|
package net.ME1312.SubServers.Bungee.Event;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
|
import net.ME1312.SubData.Server.DataClient;
|
||||||
|
import net.ME1312.SubData.Server.DataServer;
|
||||||
|
import net.ME1312.SubData.Server.Library.DisconnectReason;
|
||||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.Client;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.SubDataServer;
|
|
||||||
import net.md_5.bungee.api.plugin.Event;
|
import net.md_5.bungee.api.plugin.Event;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SubData Network Disconnect Event
|
* SubData Network Disconnect Event
|
||||||
*/
|
*/
|
||||||
public class SubNetworkDisconnectEvent extends Event implements SubEvent {
|
public class SubNetworkDisconnectEvent extends Event implements SubEvent {
|
||||||
private SubDataServer network;
|
private DataServer network;
|
||||||
private Client client;
|
private DataClient client;
|
||||||
|
private DisconnectReason reason;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SubData Network Disconnect Event
|
* SubData Network Disconnect Event
|
||||||
*/
|
*/
|
||||||
public SubNetworkDisconnectEvent(SubDataServer network, Client client) {
|
public SubNetworkDisconnectEvent(DataServer network, DataClient client, DisconnectReason reason) {
|
||||||
if (Util.isNull(network, client)) throw new NullPointerException();
|
Util.nullpo(network, client, reason);
|
||||||
this.network = network;
|
this.network = network;
|
||||||
this.client = client;
|
this.client = client;
|
||||||
|
this.reason = reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,7 +31,7 @@ public class SubNetworkDisconnectEvent extends Event implements SubEvent {
|
||||||
*
|
*
|
||||||
* @return SubData Network
|
* @return SubData Network
|
||||||
*/
|
*/
|
||||||
public SubDataServer getNetwork() {
|
public DataServer getNetwork() {
|
||||||
return network;
|
return network;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,8 +40,16 @@ public class SubNetworkDisconnectEvent extends Event implements SubEvent {
|
||||||
*
|
*
|
||||||
* @return Client
|
* @return Client
|
||||||
*/
|
*/
|
||||||
public Client getClient() {
|
public DataClient getClient() {
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the reason the client disconnected
|
||||||
|
*
|
||||||
|
* @return Disconnect Reason
|
||||||
|
*/
|
||||||
|
public DisconnectReason getReason() {
|
||||||
|
return reason;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package net.ME1312.SubServers.Bungee.Event;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
|
import net.ME1312.SubData.Server.DataClient;
|
||||||
|
import net.ME1312.SubData.Server.DataServer;
|
||||||
|
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.plugin.Event;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SubData Network Login Event
|
||||||
|
*/
|
||||||
|
public class SubNetworkLoginEvent extends Event implements SubEvent {
|
||||||
|
private DataServer network;
|
||||||
|
private DataClient client;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SubData Network Login Event
|
||||||
|
*/
|
||||||
|
public SubNetworkLoginEvent(DataServer network, DataClient client) {
|
||||||
|
Util.nullpo(network, client);
|
||||||
|
this.network = network;
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the network the client is connected to
|
||||||
|
*
|
||||||
|
* @return SubData Network
|
||||||
|
*/
|
||||||
|
public DataServer getNetwork() {
|
||||||
|
return network;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the connecting client
|
||||||
|
*
|
||||||
|
* @return Client
|
||||||
|
*/
|
||||||
|
public DataClient getClient() {
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,9 @@
|
||||||
package net.ME1312.SubServers.Bungee.Event;
|
package net.ME1312.SubServers.Bungee.Event;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
import net.ME1312.SubServers.Bungee.Host.Host;
|
import net.ME1312.SubServers.Bungee.Host.Host;
|
||||||
import net.ME1312.SubServers.Bungee.Host.Server;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import net.md_5.bungee.api.plugin.Cancellable;
|
import net.md_5.bungee.api.plugin.Cancellable;
|
||||||
import net.md_5.bungee.api.plugin.Event;
|
import net.md_5.bungee.api.plugin.Event;
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ public class SubRemoveHostEvent extends Event implements SubEvent, Cancellable {
|
||||||
* @param host Host to be added
|
* @param host Host to be added
|
||||||
*/
|
*/
|
||||||
public SubRemoveHostEvent(UUID player, Host host) {
|
public SubRemoveHostEvent(UUID player, Host host) {
|
||||||
if (Util.isNull(host)) throw new NullPointerException();
|
Util.nullpo(host);
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.host = host;
|
this.host = host;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package net.ME1312.SubServers.Bungee.Event;
|
package net.ME1312.SubServers.Bungee.Event;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
import net.ME1312.SubServers.Bungee.Host.Proxy;
|
import net.ME1312.SubServers.Bungee.Host.Proxy;
|
||||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import net.md_5.bungee.api.plugin.Event;
|
import net.md_5.bungee.api.plugin.Event;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17,7 +18,7 @@ public class SubRemoveProxyEvent extends Event implements SubEvent {
|
||||||
* @param proxy Host Being Added
|
* @param proxy Host Being Added
|
||||||
*/
|
*/
|
||||||
public SubRemoveProxyEvent(Proxy proxy) {
|
public SubRemoveProxyEvent(Proxy proxy) {
|
||||||
if (Util.isNull(proxy)) throw new NullPointerException();
|
Util.nullpo(proxy);
|
||||||
this.proxy = proxy;
|
this.proxy = proxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
package net.ME1312.SubServers.Bungee.Event;
|
package net.ME1312.SubServers.Bungee.Event;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
import net.ME1312.SubServers.Bungee.Host.Host;
|
import net.ME1312.SubServers.Bungee.Host.Host;
|
||||||
import net.ME1312.SubServers.Bungee.Host.Server;
|
import net.ME1312.SubServers.Bungee.Host.Server;
|
||||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import net.md_5.bungee.api.plugin.Cancellable;
|
import net.md_5.bungee.api.plugin.Cancellable;
|
||||||
import net.md_5.bungee.api.plugin.Event;
|
import net.md_5.bungee.api.plugin.Event;
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ public class SubRemoveServerEvent extends Event implements SubEvent, Cancellable
|
||||||
* @param server Server Starting
|
* @param server Server Starting
|
||||||
*/
|
*/
|
||||||
public SubRemoveServerEvent(UUID player, Host host, Server server) {
|
public SubRemoveServerEvent(UUID player, Host host, Server server) {
|
||||||
if (Util.isNull(server)) throw new NullPointerException();
|
Util.nullpo(server);
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.host = host;
|
this.host = host;
|
||||||
this.server = server;
|
this.server = server;
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package net.ME1312.SubServers.Bungee.Event;
|
package net.ME1312.SubServers.Bungee.Event;
|
||||||
|
|
||||||
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
|
import net.ME1312.SubServers.Bungee.Host.Server;
|
||||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import net.md_5.bungee.api.plugin.Cancellable;
|
import net.md_5.bungee.api.plugin.Cancellable;
|
||||||
import net.md_5.bungee.api.plugin.Event;
|
import net.md_5.bungee.api.plugin.Event;
|
||||||
|
|
||||||
|
@ -14,20 +15,24 @@ import java.util.UUID;
|
||||||
public class SubSendCommandEvent extends Event implements SubEvent, Cancellable {
|
public class SubSendCommandEvent extends Event implements SubEvent, Cancellable {
|
||||||
private boolean cancelled = false;
|
private boolean cancelled = false;
|
||||||
private UUID player;
|
private UUID player;
|
||||||
private SubServer server;
|
private Server server;
|
||||||
private String command;
|
private String command;
|
||||||
|
private UUID target;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Server Command Event
|
* Server Command Event
|
||||||
*
|
*
|
||||||
* @param player Player Commanding Server
|
* @param player Player Commanding
|
||||||
* @param server Server being Commanded
|
* @param server Target Server
|
||||||
|
* @param command Command to Send
|
||||||
|
* @param target Player that will send
|
||||||
*/
|
*/
|
||||||
public SubSendCommandEvent(UUID player, SubServer server, String command) {
|
public SubSendCommandEvent(UUID player, Server server, String command, UUID target) {
|
||||||
if (Util.isNull(server, command)) throw new NullPointerException();
|
Util.nullpo(server, command);
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.command = command;
|
this.command = command;
|
||||||
|
this.target = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,7 +40,7 @@ public class SubSendCommandEvent extends Event implements SubEvent, Cancellable
|
||||||
*
|
*
|
||||||
* @return The Server Effected
|
* @return The Server Effected
|
||||||
*/
|
*/
|
||||||
public SubServer getServer() { return server; }
|
public Server getServer() { return server; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the player that triggered the Event
|
* Gets the player that triggered the Event
|
||||||
|
@ -62,6 +67,15 @@ public class SubSendCommandEvent extends Event implements SubEvent, Cancellable
|
||||||
command = value;
|
command = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the Player that will be forced to send the Command
|
||||||
|
*
|
||||||
|
* @return Target Player or null if Console
|
||||||
|
*/
|
||||||
|
public UUID getTarget() {
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the Cancelled Status
|
* Gets the Cancelled Status
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package net.ME1312.SubServers.Bungee.Event;
|
package net.ME1312.SubServers.Bungee.Event;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
||||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import net.md_5.bungee.api.plugin.Cancellable;
|
import net.md_5.bungee.api.plugin.Cancellable;
|
||||||
import net.md_5.bungee.api.plugin.Event;
|
import net.md_5.bungee.api.plugin.Event;
|
||||||
|
|
||||||
|
@ -23,7 +24,7 @@ public class SubStartEvent extends Event implements SubEvent, Cancellable {
|
||||||
* @param server Server Starting
|
* @param server Server Starting
|
||||||
*/
|
*/
|
||||||
public SubStartEvent(UUID player, SubServer server) {
|
public SubStartEvent(UUID player, SubServer server) {
|
||||||
if (Util.isNull(server)) throw new NullPointerException();
|
Util.nullpo(server);
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.server = server;
|
this.server = server;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
package net.ME1312.SubServers.Bungee.Event;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
|
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
||||||
|
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.plugin.Event;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server Started Event
|
||||||
|
*/
|
||||||
|
public class SubStartedEvent extends Event implements SubEvent {
|
||||||
|
private SubServer server;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server Started Event<br>
|
||||||
|
* <b>This event can only be called when a SubData connection is made!</b>
|
||||||
|
*
|
||||||
|
* @param server Server Starting
|
||||||
|
*/
|
||||||
|
public SubStartedEvent(SubServer server) {
|
||||||
|
Util.nullpo(server);
|
||||||
|
this.server = server;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the Server Effected
|
||||||
|
*
|
||||||
|
* @return The Server Effected
|
||||||
|
*/
|
||||||
|
public SubServer getServer() { return server; }
|
||||||
|
}
|
|
@ -1,8 +1,9 @@
|
||||||
package net.ME1312.SubServers.Bungee.Event;
|
package net.ME1312.SubServers.Bungee.Event;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
||||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import net.md_5.bungee.api.plugin.Cancellable;
|
import net.md_5.bungee.api.plugin.Cancellable;
|
||||||
import net.md_5.bungee.api.plugin.Event;
|
import net.md_5.bungee.api.plugin.Event;
|
||||||
|
|
||||||
|
@ -25,7 +26,7 @@ public class SubStopEvent extends Event implements SubEvent, Cancellable {
|
||||||
* @param force If it was a Forced Shutdown
|
* @param force If it was a Forced Shutdown
|
||||||
*/
|
*/
|
||||||
public SubStopEvent(UUID player, SubServer server, boolean force) {
|
public SubStopEvent(UUID player, SubServer server, boolean force) {
|
||||||
if (Util.isNull(server, force)) throw new NullPointerException();
|
Util.nullpo(server, force);
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.force = force;
|
this.force = force;
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package net.ME1312.SubServers.Bungee.Event;
|
package net.ME1312.SubServers.Bungee.Event;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
||||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import net.md_5.bungee.api.plugin.Event;
|
import net.md_5.bungee.api.plugin.Event;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17,7 +18,7 @@ public class SubStoppedEvent extends Event implements SubEvent {
|
||||||
* @param server Server that Stopped
|
* @param server Server that Stopped
|
||||||
*/
|
*/
|
||||||
public SubStoppedEvent(SubServer server) {
|
public SubStoppedEvent(SubServer server) {
|
||||||
if (Util.isNull(server)) throw new NullPointerException();
|
Util.nullpo(server);
|
||||||
this.server = server;
|
this.server = server;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,67 +1,87 @@
|
||||||
package net.ME1312.SubServers.Bungee.Host;
|
package net.ME1312.SubServers.Bungee.Host;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Platform;
|
||||||
|
import net.ME1312.Galaxi.Library.Try;
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Compatibility.JNA;
|
import net.ME1312.SubServers.Bungee.Library.Compatibility.JNA;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.reflect.Field;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executable Handler Class
|
* Executable Handler Class
|
||||||
*/
|
*/
|
||||||
public class Executable {
|
public class Executable {
|
||||||
private Executable() {}
|
private Executable() {}
|
||||||
|
private static final boolean USE_SESSION_TRACKING;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format a command to be executed
|
* Format a command to be executed
|
||||||
*
|
*
|
||||||
* @param gitbash Git Bash location (optional)
|
* @param gitbash Git Bash location (optional)
|
||||||
* @param exec Executable String
|
* @param exec Executable String
|
||||||
* @return
|
* @return Formatted Executable
|
||||||
*/
|
*/
|
||||||
public static String[] parse(String gitbash, String exec) {
|
public static String[] parse(String gitbash, String exec) {
|
||||||
|
if (exec.startsWith("java "))
|
||||||
|
exec = '\"' + System.getProperty("java.home") + File.separator + "bin" + File.separator + "java" + '\"' + exec.substring(4);
|
||||||
|
|
||||||
String[] cmd;
|
String[] cmd;
|
||||||
if (System.getProperty("os.name").toLowerCase().startsWith("windows")) {
|
if (Platform.getSystem() == Platform.WINDOWS) {
|
||||||
if (gitbash != null && (exec.toLowerCase().startsWith("bash ") || exec.toLowerCase().startsWith("sh ")))
|
if (gitbash != null && (exec.toLowerCase().startsWith("bash ") || exec.toLowerCase().startsWith("sh ")))
|
||||||
exec = '"' + gitbash + ((gitbash.endsWith(File.separator))?"":File.separator) + "bin" + File.separatorChar + "sh.exe\" -lc \"" +
|
exec = '"' + gitbash + ((gitbash.endsWith(File.separator))?"":File.separator) + "bin" + File.separatorChar + "sh.exe\" -lc \"" +
|
||||||
exec.replace("\\", "/\\").replace("\"", "\\\"").replace("^", "^^").replace("%", "^%").replace("&", "^&").replace("<", "^<").replace(">", "^>").replace("|", "^|") + '"';
|
exec.replace("\\", "/\\").replace("\"", "\\\"").replace("^", "^^").replace("%", "^%").replace("&", "^&").replace("<", "^<").replace(">", "^>").replace("|", "^|") + '"';
|
||||||
cmd = new String[]{"cmd.exe", "/q", "/c", '"'+exec+'"'};
|
cmd = new String[]{"cmd.exe", "/q", "/c", '"'+exec+'"'};
|
||||||
|
} else if (USE_SESSION_TRACKING) {
|
||||||
|
cmd = new String[]{"setsid", "sh", "-lc", exec};
|
||||||
} else {
|
} else {
|
||||||
cmd = new String[]{"sh", "-lc", exec};
|
cmd = new String[]{"sh", "-lc", exec};
|
||||||
}
|
}
|
||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
USE_SESSION_TRACKING = Platform.getSystem() != Platform.WINDOWS && Try.all.get(() -> {
|
||||||
|
Process test = Runtime.getRuntime().exec(new String[]{"setsid", "bash", "-c", "exit 0"});
|
||||||
|
test.waitFor(); // The purpose of this block is to test for the 'setsid' command
|
||||||
|
return test.exitValue() == 0;
|
||||||
|
}, false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the PID of a currently running process
|
* Get the PID of a currently running process
|
||||||
*
|
*
|
||||||
* @param process Process
|
* @param process Process
|
||||||
* @return Process ID (null if unknown)
|
* @return Process ID (null if unknown)
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("JavaReflectionMemberAccess")
|
||||||
public static Long pid(Process process) {
|
public static Long pid(Process process) {
|
||||||
if (process.isAlive()) {
|
if (process.isAlive()) {
|
||||||
try {
|
try { // Java 9 Standard
|
||||||
return (long) Process.class.getDeclaredMethod("pid").invoke(process);
|
return (long) Process.class.getMethod("pid").invoke(process);
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable e) {
|
||||||
try {
|
try { // Java 8 Not-so-standard
|
||||||
if (process.getClass().getName().equals("java.lang.Win32Process") || process.getClass().getName().equals("java.lang.ProcessImpl")) {
|
Object response = Util.reflect(process.getClass().getDeclaredField("pid"), process);
|
||||||
|
|
||||||
|
if (response instanceof Number) {
|
||||||
|
return ((Number) response).longValue();
|
||||||
|
} else throw e;
|
||||||
|
} catch (Throwable e2) {
|
||||||
|
if (Platform.getSystem() == Platform.WINDOWS) try {
|
||||||
long handle = Util.reflect(process.getClass().getDeclaredField("handle"), process);
|
long handle = Util.reflect(process.getClass().getDeclaredField("handle"), process);
|
||||||
|
|
||||||
ClassLoader jna = JNA.get();
|
ClassLoader jna = JNA.get();
|
||||||
Class<?> pc = jna.loadClass("com.sun.jna.Pointer"),
|
Class<?> pc = jna.loadClass("com.sun.jna.Pointer"),
|
||||||
ntc = jna.loadClass("com.sun.jna.platform.win32.WinNT$HANDLE"),
|
ntc = jna.loadClass("com.sun.jna.platform.win32.WinNT$HANDLE"),
|
||||||
k32c = jna.loadClass("com.sun.jna.platform.win32.Kernel32");
|
k32c = jna.loadClass("com.sun.jna.platform.win32.Kernel32");
|
||||||
Object k32 = k32c.getField("INSTANCE").get(null),
|
Object k32 = k32c.getField("INSTANCE").get(null),
|
||||||
nt = ntc.getConstructor().newInstance();
|
nt = ntc.getConstructor().newInstance();
|
||||||
ntc.getMethod("setPointer", pc).invoke(nt, pc.getMethod("createConstant", long.class).invoke(null, handle));
|
ntc.getMethod("setPointer", pc).invoke(nt, pc.getMethod("createConstant", long.class).invoke(null, handle));
|
||||||
return ((Number) k32c.getMethod("GetProcessId", ntc).invoke(k32, nt)).longValue();
|
return ((Number) k32c.getMethod("GetProcessId", ntc).invoke(k32, nt)).longValue();
|
||||||
} else if (process.getClass().getName().equals("java.lang.UNIXProcess")) {
|
} catch (Throwable e3) {
|
||||||
Object response = Util.reflect(process.getClass().getDeclaredField("pid"), process);
|
// No way to find pid, I suppose.
|
||||||
|
|
||||||
if (response instanceof Number)
|
|
||||||
return ((Number) response).longValue();
|
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -74,14 +94,28 @@ public class Executable {
|
||||||
*/
|
*/
|
||||||
public static void terminate(Process process) {
|
public static void terminate(Process process) {
|
||||||
if (process.isAlive()) {
|
if (process.isAlive()) {
|
||||||
if (System.getProperty("os.name").toLowerCase().startsWith("windows")) {
|
Long pid;
|
||||||
Long pid = pid(process);
|
if (Platform.getSystem() == Platform.WINDOWS) {
|
||||||
if (pid != null) try {
|
if ((pid = pid(process)) != null) Try.all.run(() -> Runtime.getRuntime().exec(new String[]{"taskkill.exe", "/T", "/F", "/PID", pid.toString()}).waitFor());
|
||||||
Process terminator = Runtime.getRuntime().exec(new String[]{"taskkill.exe", "/T", "/F", "/PID", pid.toString()});
|
} else if (USE_SESSION_TRACKING) {
|
||||||
terminator.waitFor();
|
if ((pid = pid(process)) != null) Try.all.run(() -> Runtime.getRuntime().exec(new String[]{"bash", "-c", "kill -9 $(ps -s " + pid + " -o pid=)"}).waitFor());
|
||||||
} catch (Throwable e) {}
|
|
||||||
}
|
}
|
||||||
if (process.isAlive()) process.destroyForcibly();
|
|
||||||
|
if (process.isAlive() && terminate9(process)) {
|
||||||
|
process.destroyForcibly();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean terminate9(Object handle) {
|
||||||
|
try { // Attempt iteration over Java 9 ProcessHandle objects
|
||||||
|
Class<?> clazz = handle.getClass();
|
||||||
|
Stream<?> children = (Stream<?>) clazz.getMethod("children").invoke(handle);
|
||||||
|
clazz.getMethod("destroyForcibly").invoke(handle);
|
||||||
|
children.forEach(Executable::terminate9);
|
||||||
|
return false;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,26 @@
|
||||||
package net.ME1312.SubServers.Bungee.Host.External;
|
package net.ME1312.SubServers.Bungee.Host.External;
|
||||||
|
|
||||||
import com.google.common.collect.Range;
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
|
import net.ME1312.Galaxi.Library.Try;
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
|
import net.ME1312.SubData.Server.ClientHandler;
|
||||||
|
import net.ME1312.SubData.Server.DataClient;
|
||||||
|
import net.ME1312.SubData.Server.Protocol.PacketOut;
|
||||||
|
import net.ME1312.SubData.Server.SubDataClient;
|
||||||
import net.ME1312.SubServers.Bungee.Event.SubAddServerEvent;
|
import net.ME1312.SubServers.Bungee.Event.SubAddServerEvent;
|
||||||
import net.ME1312.SubServers.Bungee.Event.SubRemoveServerEvent;
|
import net.ME1312.SubServers.Bungee.Event.SubRemoveServerEvent;
|
||||||
import net.ME1312.SubServers.Bungee.Host.Host;
|
import net.ME1312.SubServers.Bungee.Host.Host;
|
||||||
import net.ME1312.SubServers.Bungee.Host.SubCreator;
|
import net.ME1312.SubServers.Bungee.Host.SubCreator;
|
||||||
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Callback;
|
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
||||||
import net.ME1312.SubServers.Bungee.Library.NamedContainer;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.Client;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.ClientHandler;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExAddServer;
|
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExAddServer;
|
||||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExDeleteServer;
|
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExDeleteServer;
|
||||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExRemoveServer;
|
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExRemoveServer;
|
||||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutReset;
|
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutExReset;
|
||||||
import net.ME1312.SubServers.Bungee.Network.PacketOut;
|
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
|
||||||
|
import com.google.common.collect.Range;
|
||||||
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
@ -27,16 +29,17 @@ import java.util.*;
|
||||||
* External Host Class
|
* External Host Class
|
||||||
*/
|
*/
|
||||||
public class ExternalHost extends Host implements ClientHandler {
|
public class ExternalHost extends Host implements ClientHandler {
|
||||||
|
private HashMap<Integer, SubDataClient> subdata = new HashMap<Integer, SubDataClient>();
|
||||||
private HashMap<String, SubServer> servers = new HashMap<String, SubServer>();
|
private HashMap<String, SubServer> servers = new HashMap<String, SubServer>();
|
||||||
private String name;
|
private String name;
|
||||||
|
boolean available;
|
||||||
private boolean enabled;
|
private boolean enabled;
|
||||||
private InetAddress address;
|
private InetAddress address;
|
||||||
private SubCreator creator;
|
private SubCreator creator;
|
||||||
private String directory;
|
private String directory;
|
||||||
protected NamedContainer<Boolean, Client> client;
|
|
||||||
private LinkedList<PacketOut> queue;
|
private LinkedList<PacketOut> queue;
|
||||||
private boolean clean;
|
private boolean clean;
|
||||||
protected SubPlugin plugin;
|
SubProxy plugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an External Host
|
* Creates an External Host
|
||||||
|
@ -50,55 +53,87 @@ public class ExternalHost extends Host implements ClientHandler {
|
||||||
* @param directory The runtime directory of your Host
|
* @param directory The runtime directory of your Host
|
||||||
* @param gitBash The Git Bash directory
|
* @param gitBash The Git Bash directory
|
||||||
*/
|
*/
|
||||||
public ExternalHost(SubPlugin plugin, String name, boolean enabled, Range<Integer> ports, boolean log, InetAddress address, String directory, String gitBash) {
|
public ExternalHost(SubProxy plugin, String name, boolean enabled, Range<Integer> ports, boolean log, InetAddress address, String directory, String gitBash) {
|
||||||
super(plugin, name, enabled, ports, log, address, directory, gitBash);
|
super(plugin, name, enabled, ports, log, address, directory, gitBash);
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
this.available = false;
|
||||||
this.enabled = enabled;
|
this.enabled = enabled;
|
||||||
this.address = address;
|
this.address = address;
|
||||||
this.client = new NamedContainer<Boolean, Client>(false, null);
|
|
||||||
this.creator = new ExternalSubCreator(this, ports, log, gitBash);
|
this.creator = new ExternalSubCreator(this, ports, log, gitBash);
|
||||||
this.directory = directory;
|
this.directory = directory;
|
||||||
this.queue = new LinkedList<PacketOut>();
|
this.queue = new LinkedList<PacketOut>();
|
||||||
this.clean = false;
|
this.clean = false;
|
||||||
|
|
||||||
|
subdata.put(0, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Client getSubData() {
|
public DataClient[] getSubData() {
|
||||||
return client.get();
|
Integer[] keys = subdata.keySet().toArray(new Integer[0]);
|
||||||
|
DataClient[] channels = new DataClient[keys.length];
|
||||||
|
Arrays.sort(keys);
|
||||||
|
for (int i = 0; i < keys.length; ++i) channels[i] = subdata.get(keys[i]);
|
||||||
|
return channels;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubData(DataClient client, int channel) {
|
||||||
|
if (channel < 0) throw new IllegalArgumentException("Subchannel ID cannot be less than zero");
|
||||||
|
if (client == null && channel == 0) available = false;
|
||||||
|
if (client != null || channel == 0) {
|
||||||
|
if (!subdata.containsKey(channel) || (channel == 0 && (client == null || subdata.get(channel) == null))) {
|
||||||
|
subdata.put(channel, (SubDataClient) client);
|
||||||
|
if (client != null && (client.getHandler() == null || !equals(client.getHandler()))) ((SubDataClient) client).setHandler(this);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
subdata.remove(channel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setSubData(Client client) {
|
public void removeSubData(DataClient client) {
|
||||||
this.client = new NamedContainer<Boolean, Client>(false, client);
|
for (Integer channel : Util.getBackwards(subdata, (SubDataClient) client)) setSubData(null, channel);
|
||||||
if (client != null && (client.getHandler() == null || !equals(client.getHandler()))) client.setHandler(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void queue(PacketOut... packet) {
|
void queue(PacketOut... packet) {
|
||||||
for (PacketOut p : packet) if (client.get() == null || client.name() == false) {
|
for (PacketOut p : packet) if (getSubData()[0] == null || !available) {
|
||||||
queue.add(p);
|
queue.add(p);
|
||||||
} else {
|
} else {
|
||||||
client.get().sendPacket(p);
|
((SubDataClient) getSubData()[0]).sendPacket(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void requeue() {
|
private void requeue() {
|
||||||
|
SubDataClient client = (SubDataClient) getSubData()[0];
|
||||||
if (!clean) {
|
if (!clean) {
|
||||||
client.get().sendPacket(new PacketOutReset("Prevent Desync"));
|
client.sendPacket(new PacketOutExReset("Prevent Desync"));
|
||||||
clean = true;
|
clean = true;
|
||||||
}
|
}
|
||||||
|
HashSet<String> served = new HashSet<String>();
|
||||||
|
LinkedList<PacketOut> queue = this.queue; this.queue = new LinkedList<PacketOut>();
|
||||||
|
PacketOut[] payload = new PacketOut[queue.size()];
|
||||||
|
for (int i = 0; i < payload.length; ++i) {
|
||||||
|
PacketOut packet = queue.get(i);
|
||||||
|
if (packet instanceof PacketExAddServer) served.add(((PacketExAddServer) packet).peek());
|
||||||
|
payload[i] = packet;
|
||||||
|
}
|
||||||
for (SubServer server : servers.values()) {
|
for (SubServer server : servers.values()) {
|
||||||
client.get().sendPacket(new PacketExAddServer(server.getName(), server.isEnabled(), server.getAddress().getPort(), server.isLogging(), server.getPath(), ((ExternalSubServer) server).exec, server.getStopCommand(), (server.isRunning())?((ExternalSubLogger) server.getLogger()).getExternalAddress():null));
|
if (!served.contains(server.getName())) {
|
||||||
|
client.sendPacket(new PacketExAddServer((ExternalSubServer) server, (server.isRunning())?((ExternalSubLogger) server.getLogger()).getExternalAddress():null, data -> {
|
||||||
|
if (data.contains(0x0002)) ((ExternalSubServer) server).started(data.getUUID(0x0002));
|
||||||
|
else if (server.isRunning()) ((ExternalSubServer) server).stopped(false);
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while (queue.size() != 0) {
|
client.sendPacket(payload);
|
||||||
client.get().sendPacket(queue.get(0));
|
available = true;
|
||||||
queue.remove(0);
|
while (this.queue.size() != 0) {
|
||||||
|
client.sendPacket(this.queue.remove(0));
|
||||||
}
|
}
|
||||||
client.rename(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAvailable() {
|
public boolean isAvailable() {
|
||||||
return this.client.name();
|
return available;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -138,40 +173,52 @@ public class ExternalHost extends Host implements ClientHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SubServer getSubServer(String name) {
|
public SubServer getSubServer(String name) {
|
||||||
if (Util.isNull(name)) throw new NullPointerException();
|
if (Util.isNull(name)) return null;
|
||||||
return getSubServers().get(name.toLowerCase());
|
return servers.get(name.toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SubServer addSubServer(UUID player, String name, boolean enabled, int port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
public SubServer constructSubServer(String name, boolean enabled, int port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||||
if (plugin.api.getServers().keySet().contains(name.toLowerCase())) throw new InvalidServerException("A Server already exists with this name!");
|
return ExternalSubServer.construct(this, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||||
SubServer server = new ExternalSubServer(this, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean addSubServer(UUID player, SubServer server) throws InvalidServerException {
|
||||||
|
if (server.getHost() != this) throw new IllegalArgumentException("That Server does not belong to this Host!");
|
||||||
|
if (plugin.api.getServers().containsKey(server.getName().toLowerCase())) throw new InvalidServerException("A Server already exists with this name!");
|
||||||
SubAddServerEvent event = new SubAddServerEvent(player, this, server);
|
SubAddServerEvent event = new SubAddServerEvent(player, this, server);
|
||||||
plugin.getPluginManager().callEvent(event);
|
plugin.getPluginManager().callEvent(event);
|
||||||
if (!event.isCancelled()) {
|
if (!event.isCancelled()) {
|
||||||
queue(new PacketExAddServer(name, enabled, port, log, directory, executable, stopcmd, (server.isRunning())?((ExternalSubLogger) server.getLogger()).getExternalAddress():null));
|
queue(new PacketExAddServer(((ExternalSubServer) server), (server.isRunning())?((ExternalSubLogger) server.getLogger()).getExternalAddress():null, data -> {
|
||||||
servers.put(name.toLowerCase(), server);
|
if (data.contains(0x0002)) ((ExternalSubServer) server).started(data.getUUID(0x0002));
|
||||||
return server;
|
((ExternalSubServer) server).registered(true);
|
||||||
|
}));
|
||||||
|
servers.put(server.getName().toLowerCase(), server);
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean removeSubServer(UUID player, String name) throws InterruptedException {
|
protected boolean removeSubServer(UUID player, String name, boolean forced) throws InterruptedException {
|
||||||
if (Util.isNull(name)) throw new NullPointerException();
|
Util.nullpo(name);
|
||||||
String server = servers.get(name.toLowerCase()).getName();
|
ExternalSubServer server = (ExternalSubServer) servers.get(name.toLowerCase());
|
||||||
|
|
||||||
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, getSubServer(server));
|
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, server);
|
||||||
plugin.getPluginManager().callEvent(event);
|
plugin.getPluginManager().callEvent(event);
|
||||||
if (!event.isCancelled()) {
|
if (forced || !event.isCancelled()) {
|
||||||
if (getSubServer(server).isRunning()) {
|
server.registered(false);
|
||||||
getSubServer(server).stop();
|
if (server.isRunning()) {
|
||||||
getSubServer(server).waitFor();
|
server.stop();
|
||||||
|
server.waitFor();
|
||||||
}
|
}
|
||||||
queue(new PacketExRemoveServer(server, data -> {
|
|
||||||
if (data.getInt("r") == 0) {
|
servers.remove(name.toLowerCase());
|
||||||
servers.remove(server.toLowerCase());
|
queue(new PacketExRemoveServer(name.toLowerCase(), data -> {
|
||||||
|
if (data.getInt(0x0001) != 0 && data.getInt(0x0001) != 1) {
|
||||||
|
server.registered(true);
|
||||||
|
servers.put(name.toLowerCase(), server);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
return true;
|
return true;
|
||||||
|
@ -179,56 +226,41 @@ public class ExternalHost extends Host implements ClientHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean forceRemoveSubServer(UUID player, String name) {
|
protected boolean recycleSubServer(UUID player, String name, boolean forced) throws InterruptedException {
|
||||||
if (Util.isNull(name)) throw new NullPointerException();
|
Util.nullpo(name);
|
||||||
String server = servers.get(name.toLowerCase()).getName();
|
ExternalSubServer s = (ExternalSubServer) servers.get(name.toLowerCase());
|
||||||
|
String server = s.getName();
|
||||||
|
|
||||||
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, getSubServer(server));
|
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, s);
|
||||||
plugin.getPluginManager().callEvent(event);
|
plugin.getPluginManager().callEvent(event);
|
||||||
if (getSubServer(server).isRunning()) {
|
if (forced || !event.isCancelled()) {
|
||||||
getSubServer(server).terminate();
|
s.registered(false);
|
||||||
}
|
if (s.isRunning()) {
|
||||||
queue(new PacketExRemoveServer(server, data -> {
|
s.stop();
|
||||||
if (data.getInt("r") == 0) {
|
s.waitFor();
|
||||||
servers.remove(server.toLowerCase());
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean deleteSubServer(UUID player, String name) throws InterruptedException {
|
|
||||||
if (Util.isNull(name)) throw new NullPointerException();
|
|
||||||
String server = servers.get(name.toLowerCase()).getName();
|
|
||||||
|
|
||||||
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, getSubServer(server));
|
|
||||||
plugin.getPluginManager().callEvent(event);
|
|
||||||
if (!event.isCancelled()) {
|
|
||||||
if (getSubServer(server).isRunning()) {
|
|
||||||
getSubServer(server).stop();
|
|
||||||
getSubServer(server).waitFor();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("SubServers > Saving...");
|
Logger.get("SubServers").info("Saving...");
|
||||||
YAMLSection info = (plugin.config.get().getSection("Servers").getKeys().contains(server))?plugin.config.get().getSection("Servers").getSection(server).clone():new YAMLSection();
|
ObjectMap<String> info = (plugin.servers.get().getMap("Servers").getKeys().contains(server))?plugin.servers.get().getMap("Servers").getMap(server).clone():new ObjectMap<String>();
|
||||||
info.set("Name", server);
|
info.set("Name", server);
|
||||||
info.set("Timestamp", Calendar.getInstance().getTime().getTime());
|
info.set("Timestamp", Calendar.getInstance().getTime().getTime());
|
||||||
try {
|
try {
|
||||||
if (plugin.config.get().getSection("Servers").getKeys().contains(server)) {
|
if (plugin.servers.get().getMap("Servers").getKeys().contains(server)) {
|
||||||
plugin.config.get().getSection("Servers").remove(server);
|
plugin.servers.get().getMap("Servers").remove(server);
|
||||||
plugin.config.save();
|
plugin.servers.save();
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("SubServers > Removing Files...");
|
Logger.get("SubServers").info("Moving Files...");
|
||||||
queue(new PacketExDeleteServer(server, info, data -> {
|
queue(new PacketExDeleteServer(server, info, true, data -> {
|
||||||
if (data.getInt("r") == 0) {
|
if (data.getInt(0x0001) == 0 || data.getInt(0x0001) == 1) {
|
||||||
servers.remove(server.toLowerCase());
|
servers.remove(server.toLowerCase());
|
||||||
System.out.println("SubServers > Deleted SubServer: " + server);
|
Logger.get("SubServers").info("Deleted SubServer: " + server);
|
||||||
} else {
|
} else {
|
||||||
System.out.println("SubServers > Couldn't remove " + server + " from memory. See " + getName() + " console for more details");
|
s.registered(true);
|
||||||
|
Logger.get("SubServers").info("Couldn't remove " + server + " from memory. See " + getName() + " console for more details");
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
return true;
|
return true;
|
||||||
|
@ -236,39 +268,61 @@ public class ExternalHost extends Host implements ClientHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean forceDeleteSubServer(UUID player, String name) throws InterruptedException {
|
protected boolean deleteSubServer(UUID player, String name, boolean forced) throws InterruptedException {
|
||||||
if (Util.isNull(name)) throw new NullPointerException();
|
Util.nullpo(name);
|
||||||
String server = servers.get(name.toLowerCase()).getName();
|
ExternalSubServer s = (ExternalSubServer) servers.get(name.toLowerCase());
|
||||||
|
String server = s.getName();
|
||||||
|
|
||||||
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, getSubServer(server));
|
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, getSubServer(server));
|
||||||
plugin.getPluginManager().callEvent(event);
|
plugin.getPluginManager().callEvent(event);
|
||||||
if (getSubServer(server).isRunning()) {
|
if (forced || !event.isCancelled()) {
|
||||||
getSubServer(server).terminate();
|
s.registered(false);
|
||||||
}
|
if (s.isRunning()) {
|
||||||
|
s.stop();
|
||||||
System.out.println("SubServers > Saving...");
|
s.waitFor();
|
||||||
YAMLSection info = (plugin.config.get().getSection("Servers").getKeys().contains(server))?plugin.config.get().getSection("Servers").getSection(server).clone():new YAMLSection();
|
|
||||||
info.set("Name", server);
|
|
||||||
info.set("Timestamp", Calendar.getInstance().getTime().getTime());
|
|
||||||
try {
|
|
||||||
if (plugin.config.get().getSection("Servers").getKeys().contains(server)) {
|
|
||||||
plugin.config.get().getSection("Servers").remove(server);
|
|
||||||
plugin.config.save();
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println("SubServers > Removing Files...");
|
Logger.get("SubServers").info("Saving...");
|
||||||
queue(new PacketExDeleteServer(server, info, data -> {
|
ObjectMap<String> info = (plugin.servers.get().getMap("Servers").getKeys().contains(server))?plugin.servers.get().getMap("Servers").getMap(server).clone():new ObjectMap<String>();
|
||||||
if (data.getInt("r") == 0) {
|
info.set("Name", server);
|
||||||
for (String group : getSubServer(server).getGroups()) getSubServer(server).removeGroup(group);
|
info.set("Timestamp", Calendar.getInstance().getTime().getTime());
|
||||||
servers.remove(server.toLowerCase());
|
try {
|
||||||
System.out.println("SubServers > Deleted SubServer: " + server);
|
if (plugin.servers.get().getMap("Servers").getKeys().contains(server)) {
|
||||||
} else {
|
plugin.servers.get().getMap("Servers").remove(server);
|
||||||
System.out.println("SubServers > Couldn't remove " + server + " from memory. See " + getName() + " console for more details");
|
plugin.servers.save();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}));
|
|
||||||
|
Logger.get("SubServers").info("Removing Files...");
|
||||||
|
queue(new PacketExDeleteServer(server, info, false, data -> {
|
||||||
|
if (data.getInt(0x0001) == 0 || data.getInt(0x0001) == 1) {
|
||||||
|
servers.remove(server.toLowerCase());
|
||||||
|
Logger.get("SubServers").info("Deleted SubServer: " + server);
|
||||||
|
} else {
|
||||||
|
s.registered(true);
|
||||||
|
Logger.get("SubServers").info("Couldn't remove " + server + " from memory. See " + getName() + " console for more details");
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
return true;
|
||||||
|
} else return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean destroy() {
|
||||||
|
if (Try.all.get(() -> Util.reflect(SubProxy.class.getDeclaredField("running"), plugin), true)) {
|
||||||
|
return super.destroy();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObjectMap<String> forSubData() {
|
||||||
|
ObjectMap<String> hinfo = super.forSubData();
|
||||||
|
ObjectMap<Integer> subdata = new ObjectMap<Integer>();
|
||||||
|
for (int channel : this.subdata.keySet()) subdata.set(channel, (this.subdata.get(channel) == null)?null:this.subdata.get(channel).getID());
|
||||||
|
hinfo.set("subdata", subdata);
|
||||||
|
return hinfo;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,38 @@
|
||||||
package net.ME1312.SubServers.Bungee.Host.External;
|
package net.ME1312.SubServers.Bungee.Host.External;
|
||||||
|
|
||||||
import com.google.common.collect.Range;
|
import net.ME1312.Galaxi.Library.Config.YAMLConfig;
|
||||||
|
import net.ME1312.Galaxi.Library.Container.ContainedPair;
|
||||||
|
import net.ME1312.Galaxi.Library.Container.Container;
|
||||||
|
import net.ME1312.Galaxi.Library.Container.Pair;
|
||||||
|
import net.ME1312.Galaxi.Library.Container.Value;
|
||||||
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
|
import net.ME1312.Galaxi.Library.Try;
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
|
import net.ME1312.Galaxi.Library.Version.Version;
|
||||||
|
import net.ME1312.SubData.Server.SubDataClient;
|
||||||
import net.ME1312.SubServers.Bungee.Event.SubCreateEvent;
|
import net.ME1312.SubServers.Bungee.Event.SubCreateEvent;
|
||||||
import net.ME1312.SubServers.Bungee.Host.*;
|
import net.ME1312.SubServers.Bungee.Event.SubCreatedEvent;
|
||||||
import net.ME1312.SubServers.Bungee.Host.Internal.InternalSubCreator;
|
import net.ME1312.SubServers.Bungee.Host.Host;
|
||||||
import net.ME1312.SubServers.Bungee.Library.*;
|
import net.ME1312.SubServers.Bungee.Host.SubCreator;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLConfig;
|
import net.ME1312.SubServers.Bungee.Host.SubLogger;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidHostException;
|
import net.ME1312.SubServers.Bungee.Host.SubServer.StopAction;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
|
||||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExConfigureHost;
|
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExConfigureHost;
|
||||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExCreateServer;
|
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExCreateServer;
|
||||||
|
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExDownloadTemplates;
|
||||||
|
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExUploadTemplates;
|
||||||
import net.ME1312.SubServers.Bungee.SubAPI;
|
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||||
|
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||||
|
|
||||||
|
import com.google.common.collect.Range;
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* External SubCreator Class
|
* External SubCreator Class
|
||||||
|
@ -24,11 +40,13 @@ import java.util.*;
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public class ExternalSubCreator extends SubCreator {
|
public class ExternalSubCreator extends SubCreator {
|
||||||
private HashMap<String, ServerTemplate> templates = new HashMap<String, ServerTemplate>();
|
private HashMap<String, ServerTemplate> templates = new HashMap<String, ServerTemplate>();
|
||||||
|
private HashMap<String, ServerTemplate> templatesR = new HashMap<String, ServerTemplate>();
|
||||||
|
private Boolean enableRT = false;
|
||||||
private ExternalHost host;
|
private ExternalHost host;
|
||||||
private Range<Integer> ports;
|
private Range<Integer> ports;
|
||||||
private Container<Boolean> log;
|
private Value<Boolean> log;
|
||||||
private String gitBash;
|
private String gitBash;
|
||||||
private TreeMap<String, NamedContainer<Integer, ExternalSubLogger>> thread;
|
private TreeMap<String, Pair<Integer, ExternalSubLogger>> thread;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an External SubCreator
|
* Creates an External SubCreator
|
||||||
|
@ -40,116 +58,66 @@ public class ExternalSubCreator extends SubCreator {
|
||||||
*/
|
*/
|
||||||
public ExternalSubCreator(ExternalHost host, Range<Integer> ports, boolean log, String gitBash) {
|
public ExternalSubCreator(ExternalHost host, Range<Integer> ports, boolean log, String gitBash) {
|
||||||
if (!ports.hasLowerBound() || !ports.hasUpperBound()) throw new IllegalArgumentException("Port range is not bound");
|
if (!ports.hasLowerBound() || !ports.hasUpperBound()) throw new IllegalArgumentException("Port range is not bound");
|
||||||
if (Util.isNull(host, ports, log, gitBash)) throw new NullPointerException();
|
Util.nullpo(host, ports, log, gitBash);
|
||||||
this.host = host;
|
this.host = host;
|
||||||
this.ports = ports;
|
this.ports = ports;
|
||||||
this.log = new Container<Boolean>(log);
|
this.log = new Container<Boolean>(log);
|
||||||
this.gitBash = gitBash;
|
this.gitBash = gitBash;
|
||||||
this.thread = new TreeMap<String, NamedContainer<Integer, ExternalSubLogger>>();
|
this.thread = new TreeMap<String, Pair<Integer, ExternalSubLogger>>();
|
||||||
reload();
|
reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reload() {
|
public void reload() {
|
||||||
templates.clear();
|
templatesR.clear();
|
||||||
if (new UniversalFile(host.plugin.dir, "SubServers:Templates").exists()) for (File file : new UniversalFile(host.plugin.dir, "SubServers:Templates").listFiles()) {
|
if (new File(host.plugin.dir, "SubServers/Templates").exists()) for (File file : new File(host.plugin.dir, "SubServers/Templates").listFiles()) {
|
||||||
try {
|
try {
|
||||||
if (file.isDirectory() && !file.getName().endsWith(".x")) {
|
if (file.isDirectory() && !file.getName().endsWith(".x")) {
|
||||||
YAMLSection config = (new UniversalFile(file, "template.yml").exists())?new YAMLConfig(new UniversalFile(file, "template.yml")).get().getSection("Template", new YAMLSection()):new YAMLSection();
|
ObjectMap<String> config = (new File(file, "template.yml").exists())? new YAMLConfig(new File(file, "template.yml")).get().getMap("Template", new ObjectMap<String>()) : new ObjectMap<String>();
|
||||||
ServerTemplate template = new ServerTemplate(file.getName(), config.getBoolean("Enabled", true), config.getRawString("Icon", "::NULL::"), file, config.getSection("Build", new YAMLSection()), config.getSection("Settings", new YAMLSection()));
|
ServerTemplate template = loadTemplate(file.getName(), config.getBoolean("Enabled", true), config.getBoolean("Internal", false), config.getString("Icon", "::NULL::"), file, config.getMap("Build", new ObjectMap<String>()), config.getMap("Settings", new ObjectMap<String>()));
|
||||||
templates.put(file.getName().toLowerCase(), template);
|
templatesR.put(file.getName().toLowerCase(), template);
|
||||||
if (config.getKeys().contains("Display")) template.setDisplayName(config.getString("Display"));
|
if (config.getKeys().contains("Display")) template.setDisplayName(Util.unescapeJavaString(config.getString("Display")));
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.out.println(host.getName() + "/Creator > Couldn't load template: " + file.getName());
|
Logger.get(host.getName()).severe("Couldn't load template: " + file.getName());
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (host.client.name()) host.queue(new PacketExConfigureHost(host.plugin, host));
|
|
||||||
|
if (host.available && !Try.all.get(() -> Util.reflect(SubProxy.class.getDeclaredField("reloading"), host.plugin), false)) {
|
||||||
|
host.queue(new PacketExConfigureHost(host.plugin, host), new PacketExUploadTemplates(host.plugin, () -> {
|
||||||
|
if (enableRT == null || enableRT) host.queue(new PacketExDownloadTemplates(host.plugin, host));
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean create(UUID player, String name, ServerTemplate template, Version version, Integer port, Callback<SubServer> callback) {
|
public boolean create(UUID player, String name, ServerTemplate template, Version version, Integer port, Consumer<SubServer> callback) {
|
||||||
if (Util.isNull(name, template, version)) throw new NullPointerException();
|
Util.nullpo(name, template);
|
||||||
if (host.isAvailable() && host.isEnabled() && template.isEnabled() && !SubAPI.getInstance().getSubServers().keySet().contains(name.toLowerCase()) && !SubCreator.isReserved(name)) {
|
if (host.isAvailable() && host.isEnabled() && template.isEnabled() && !SubAPI.getInstance().getSubServers().containsKey(name.toLowerCase()) && !SubCreator.isReserved(name) && (version != null || !template.requiresVersion())) {
|
||||||
StackTraceElement[] origin = new Exception().getStackTrace();
|
StackTraceElement[] origin = new Throwable().getStackTrace();
|
||||||
|
|
||||||
if (port == null) {
|
if (port == null) {
|
||||||
Container<Integer> i = new Container<Integer>(ports.lowerEndpoint() - 1);
|
Container<Integer> i = new Container<Integer>(ports.lowerEndpoint() - 1);
|
||||||
port = Util.getNew(getAllReservedAddresses(), () -> {
|
port = Util.getNew(getAllReservedAddresses(), () -> {
|
||||||
do {
|
do {
|
||||||
i.set(i.get() + 1);
|
++i.value;
|
||||||
if (i.get() > ports.upperEndpoint()) throw new IllegalStateException("There are no more ports available in range: " + ports.toString());
|
if (i.value > ports.upperEndpoint()) throw new IllegalStateException("There are no more ports available in range: " + ports.toString());
|
||||||
} while (!ports.contains(i.get()));
|
} while (!ports.contains(i.value));
|
||||||
return new InetSocketAddress(host.getAddress(), i.get());
|
return new InetSocketAddress(host.getAddress(), i.value);
|
||||||
}).getPort();
|
}).getPort();
|
||||||
}
|
}
|
||||||
ExternalSubLogger logger = new ExternalSubLogger(this, name + File.separator + "Creator", log, null);
|
String prefix = name + File.separator + "Creator";
|
||||||
thread.put(name.toLowerCase(), new NamedContainer<>(port, logger));
|
ExternalSubLogger logger = new ExternalSubLogger(this, prefix, log, null);
|
||||||
|
thread.put(name.toLowerCase(), new ContainedPair<>(port, logger));
|
||||||
|
|
||||||
final int fport = port;
|
final int fport = port;
|
||||||
final SubCreateEvent event = new SubCreateEvent(player, host, name, template, version, port);
|
final SubCreateEvent event = new SubCreateEvent(player, host, name, template, version, port);
|
||||||
host.plugin.getPluginManager().callEvent(event);
|
host.plugin.getPluginManager().callEvent(event);
|
||||||
if (!event.isCancelled()) {
|
if (!event.isCancelled()) {
|
||||||
logger.start();
|
logger.start();
|
||||||
host.queue(new PacketExCreateServer(name, template, version, port, logger.getExternalAddress(), data -> {
|
host.queue(new PacketExCreateServer(player, name, template, version, port, logger.getExternalAddress(), data -> {
|
||||||
try {
|
finish(player, null, name, template, version, fport, prefix, origin, data, callback);
|
||||||
if (data.getInt("r") == 0) {
|
|
||||||
System.out.println(name + "/Creator > Saving...");
|
|
||||||
if (host.plugin.exServers.keySet().contains(name.toLowerCase()))
|
|
||||||
host.plugin.exServers.remove(name.toLowerCase());
|
|
||||||
|
|
||||||
YAMLSection server = new YAMLSection();
|
|
||||||
YAMLSection config = new YAMLSection((Map<String, ?>) convert(data.getSection("c").get(), new NamedContainer<>("$player$", (player == null)?"":player.toString()), new NamedContainer<>("$name$", name),
|
|
||||||
new NamedContainer<>("$template$", template.getName()), new NamedContainer<>("$type$", template.getType().toString()), new NamedContainer<>("$version$", version.toString().replace(" ", "@")),
|
|
||||||
new NamedContainer<>("$address$", data.getSection("c").getRawString("\033address", "null")), new NamedContainer<>("$port$", Integer.toString(fport))));
|
|
||||||
|
|
||||||
config.remove("\033address");
|
|
||||||
|
|
||||||
server.set("Enabled", true);
|
|
||||||
server.set("Display", "");
|
|
||||||
server.set("Host", host.getName());
|
|
||||||
server.set("Group", new ArrayList<String>());
|
|
||||||
server.set("Port", fport);
|
|
||||||
server.set("Motd", "Some SubServer");
|
|
||||||
server.set("Log", true);
|
|
||||||
server.set("Directory", "." + File.separatorChar + name);
|
|
||||||
server.set("Executable", "java -Xmx1024M -jar " + template.getType().toString() + ".jar");
|
|
||||||
server.set("Stop-Command", "stop");
|
|
||||||
server.set("Stop-Action", "NONE");
|
|
||||||
server.set("Run-On-Launch", false);
|
|
||||||
server.set("Restricted", false);
|
|
||||||
server.set("Incompatible", new ArrayList<String>());
|
|
||||||
server.set("Hidden", false);
|
|
||||||
server.setAll(config);
|
|
||||||
|
|
||||||
SubServer subserver = host.addSubServer(player, name, server.getBoolean("Enabled"), fport, server.getColoredString("Motd", '&'), server.getBoolean("Log"), server.getRawString("Directory"),
|
|
||||||
server.getRawString("Executable"), server.getRawString("Stop-Command"), server.getBoolean("Hidden"), server.getBoolean("Restricted"));
|
|
||||||
if (server.getString("Display").length() > 0) subserver.setDisplayName(server.getString("Display"));
|
|
||||||
for (String group : server.getStringList("Group")) subserver.addGroup(group);
|
|
||||||
SubServer.StopAction action = Util.getDespiteException(() -> SubServer.StopAction.valueOf(server.getRawString("Stop-Action").toUpperCase().replace('-', '_').replace(' ', '_')), null);
|
|
||||||
if (action != null) subserver.setStopAction(action);
|
|
||||||
if (server.contains("Extra")) for (String extra : server.getSection("Extra").getKeys())
|
|
||||||
subserver.addExtra(extra, server.getSection("Extra").getObject(extra));
|
|
||||||
host.plugin.config.get().getSection("Servers").set(name, server);
|
|
||||||
host.plugin.config.save();
|
|
||||||
if (template.getBuildOptions().getBoolean("Run-On-Finish", true))
|
|
||||||
subserver.start();
|
|
||||||
|
|
||||||
if (callback != null) try {
|
|
||||||
callback.run(subserver);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
Throwable ew = new InvocationTargetException(e);
|
|
||||||
ew.setStackTrace(origin);
|
|
||||||
ew.printStackTrace();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
System.out.println(name + "/Creator > " + data.getString("m"));
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
logger.stop();
|
|
||||||
this.thread.remove(name.toLowerCase());
|
this.thread.remove(name.toLowerCase());
|
||||||
}));
|
}));
|
||||||
return true;
|
return true;
|
||||||
|
@ -158,33 +126,129 @@ public class ExternalSubCreator extends SubCreator {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else return false;
|
} else return false;
|
||||||
} private Object convert(Object value, NamedContainer<String, String>... replacements) {
|
} private <T> void callback(StackTraceElement[] origin, Consumer<T> callback, T value) {
|
||||||
if (value instanceof Map) {
|
if (callback != null) try {
|
||||||
List<String> list = new ArrayList<String>();
|
callback.accept(value);
|
||||||
list.addAll(((Map<String, Object>) value).keySet());
|
} catch (Throwable e) {
|
||||||
for (String key : list) ((Map<String, Object>) value).put(key, convert(((Map<String, Object>) value).get(key), replacements));
|
Throwable ew = new InvocationTargetException(e);
|
||||||
return value;
|
ew.setStackTrace(origin);
|
||||||
} else if (value instanceof Collection) {
|
ew.printStackTrace();
|
||||||
List<Object> list = new ArrayList<Object>();
|
}
|
||||||
for (Object val : (Collection<Object>) value) list.add(convert(val, replacements));
|
}
|
||||||
return list;
|
|
||||||
} else if (value.getClass().isArray()) {
|
@Override
|
||||||
List<Object> list = new ArrayList<Object>();
|
public boolean update(UUID player, SubServer server, ServerTemplate template, Version version, Consumer<Boolean> callback) {
|
||||||
for (int i = 0; i < ((Object[]) value).length; i++) list.add(convert(((Object[]) value)[i], replacements));
|
Util.nullpo(server);
|
||||||
return list;
|
final ServerTemplate ft = (template == null)?server.getTemplate():template;
|
||||||
} else if (value instanceof String) {
|
if (host.isAvailable() && host.isEnabled() && host == server.getHost() && server.isAvailable() && !server.isRunning() && ft != null && ft.isEnabled() && ft.canUpdate() && (version != null || !ft.requiresVersion())) {
|
||||||
return replace((String) value, replacements);
|
StackTraceElement[] origin = new Throwable().getStackTrace();
|
||||||
} else {
|
|
||||||
return value;
|
String name = server.getName();
|
||||||
|
String prefix = name + File.separator + "Updater";
|
||||||
|
((ExternalSubServer) server).updating(true);
|
||||||
|
ExternalSubLogger logger = new ExternalSubLogger(this, prefix, log, null);
|
||||||
|
thread.put(name.toLowerCase(), new ContainedPair<>(server.getAddress().getPort(), logger));
|
||||||
|
|
||||||
|
final SubCreateEvent event = new SubCreateEvent(player, server, ft, version);
|
||||||
|
host.plugin.getPluginManager().callEvent(event);
|
||||||
|
if (!event.isCancelled()) {
|
||||||
|
logger.start();
|
||||||
|
host.queue(new PacketExCreateServer(player, server, ft, version, logger.getExternalAddress(), data -> {
|
||||||
|
finish(player, server, server.getName(), ft, version, server.getAddress().getPort(), prefix, origin, data, s -> {
|
||||||
|
((ExternalSubServer) server).updating(false);
|
||||||
|
if (callback != null) callback.accept(s != null);
|
||||||
|
});
|
||||||
|
this.thread.remove(name.toLowerCase());
|
||||||
|
}));
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
thread.remove(name.toLowerCase());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void finish(UUID player, SubServer update, String name, ServerTemplate template, Version version, int port, String prefix, StackTraceElement[] origin, ObjectMap<Integer> data, Consumer<SubServer> callback) {
|
||||||
|
try {
|
||||||
|
if (data.getInt(0x0001) == 0) {
|
||||||
|
Logger.get(prefix).info("Saving...");
|
||||||
|
SubServer subserver = update;
|
||||||
|
if (update == null || update.getTemplate() != template || template.getBuildOptions().getBoolean("Update-Settings", false)) {
|
||||||
|
if (host.plugin.exServers.containsKey(name.toLowerCase()))
|
||||||
|
host.plugin.exServers.remove(name.toLowerCase());
|
||||||
|
|
||||||
|
ObjectMap<String> server = new ObjectMap<String>();
|
||||||
|
ObjectMap<String> config = new ObjectMap<String>((Map<String, ?>) data.getObject(0x0002));
|
||||||
|
if (config.contains("Directory") && (update != null || !template.getConfigOptions().contains("Directory"))) config.remove("Directory");
|
||||||
|
|
||||||
|
if (update == null) {
|
||||||
|
server.set("Enabled", true);
|
||||||
|
server.set("Display", "");
|
||||||
|
server.set("Host", host.getName());
|
||||||
|
server.set("Template", template.getName());
|
||||||
|
server.set("Group", new ArrayList<String>());
|
||||||
|
server.set("Port", port);
|
||||||
|
server.set("Motd", "Some SubServer");
|
||||||
|
server.set("Log", true);
|
||||||
|
server.set("Directory", "./" + name);
|
||||||
|
server.set("Executable", "java -Xmx1024M -jar " + template.getType().toString() + ".jar");
|
||||||
|
server.set("Stop-Command", "stop");
|
||||||
|
server.set("Stop-Action", "NONE");
|
||||||
|
server.set("Run-On-Launch", false);
|
||||||
|
server.set("Restricted", false);
|
||||||
|
server.set("Incompatible", new ArrayList<String>());
|
||||||
|
server.set("Hidden", false);
|
||||||
|
} else {
|
||||||
|
server.setAll(host.plugin.servers.get().getMap("Servers").getMap(name, new HashMap<>()));
|
||||||
|
server.set("Template", template.getName());
|
||||||
|
}
|
||||||
|
server.setAll(config);
|
||||||
|
|
||||||
|
if (update != null) Try.all.run(() -> update.getHost().forceRemoveSubServer(name));
|
||||||
|
subserver = host.constructSubServer(name, server.getBoolean("Enabled"), port, ChatColor.translateAlternateColorCodes('&', Util.unescapeJavaString(server.getString("Motd"))), server.getBoolean("Log"),
|
||||||
|
server.getString("Directory"), server.getString("Executable"), server.getString("Stop-Command"), server.getBoolean("Hidden"), server.getBoolean("Restricted"));
|
||||||
|
|
||||||
|
if (server.getString("Display").length() > 0) subserver.setDisplayName(Util.unescapeJavaString(server.getString("Display")));
|
||||||
|
subserver.setTemplate(server.getString("Template"));
|
||||||
|
for (String group : server.getStringList("Group")) subserver.addGroup(group);
|
||||||
|
SubServer.StopAction action = Try.all.get(() -> SubServer.StopAction.valueOf(server.getString("Stop-Action").toUpperCase().replace('-', '_').replace(' ', '_')));
|
||||||
|
if (action != null) subserver.setStopAction(action);
|
||||||
|
if (server.contains("Extra")) for (String extra : server.getMap("Extra").getKeys())
|
||||||
|
subserver.addExtra(extra, server.getMap("Extra").getObject(extra));
|
||||||
|
|
||||||
|
if ((update != null && host.plugin.servers.get().getMap("Servers").contains(name)) ||
|
||||||
|
!(subserver.getStopAction() == StopAction.REMOVE_SERVER || subserver.getStopAction() == StopAction.RECYCLE_SERVER || subserver.getStopAction() == StopAction.DELETE_SERVER)) {
|
||||||
|
host.plugin.servers.get().getMap("Servers").set(name, server);
|
||||||
|
host.plugin.servers.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
host.addSubServer(subserver);
|
||||||
|
if (update == null && template.getBuildOptions().getBoolean("Run-On-Finish", true)) {
|
||||||
|
while (!subserver.isAvailable() && host.isAvailable()) {
|
||||||
|
Thread.sleep(250);
|
||||||
|
}
|
||||||
|
if (subserver.isAvailable()) {
|
||||||
|
subserver.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
host.plugin.getPluginManager().callEvent(new SubCreatedEvent(player, host, name, template, version, port, subserver, update != null, true));
|
||||||
|
callback(origin, callback, subserver);
|
||||||
|
} else {
|
||||||
|
Logger.get(prefix).info(data.getString(0x0003));
|
||||||
|
host.plugin.getPluginManager().callEvent(new SubCreatedEvent(player, host, name, template, version, port, update, update != null, false));
|
||||||
|
callback(origin, callback, null);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
callback(origin, callback, null);
|
||||||
}
|
}
|
||||||
} private String replace(String string, NamedContainer<String, String>... replacements) {
|
|
||||||
for (NamedContainer<String, String> replacement : replacements) string = string.replace(replacement.name(), replacement.get());
|
|
||||||
return string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void terminate() {
|
public void terminate() {
|
||||||
HashMap<String, NamedContainer<Integer, ExternalSubLogger>> thread = new HashMap<String, NamedContainer<Integer, ExternalSubLogger>>();
|
HashMap<String, Pair<Integer, ExternalSubLogger>> thread = new HashMap<String, Pair<Integer, ExternalSubLogger>>();
|
||||||
thread.putAll(this.thread);
|
thread.putAll(this.thread);
|
||||||
for (String i : thread.keySet()) {
|
for (String i : thread.keySet()) {
|
||||||
terminate(i);
|
terminate(i);
|
||||||
|
@ -193,15 +257,15 @@ public class ExternalSubCreator extends SubCreator {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void terminate(String name) {
|
public void terminate(String name) {
|
||||||
if (this.thread.keySet().contains(name.toLowerCase())) {
|
if (this.thread.containsKey(name.toLowerCase())) {
|
||||||
host.getSubData().sendPacket(new PacketExCreateServer(name.toLowerCase()));
|
((SubDataClient) host.getSubData()[0]).sendPacket(new PacketExCreateServer(name.toLowerCase()));
|
||||||
thread.remove(name.toLowerCase());
|
thread.remove(name.toLowerCase());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void waitFor() throws InterruptedException {
|
public void waitFor() throws InterruptedException {
|
||||||
HashMap<String, NamedContainer<Integer, ExternalSubLogger>> thread = new HashMap<String, NamedContainer<Integer, ExternalSubLogger>>();
|
HashMap<String, Pair<Integer, ExternalSubLogger>> thread = new HashMap<String, Pair<Integer, ExternalSubLogger>>();
|
||||||
thread.putAll(this.thread);
|
thread.putAll(this.thread);
|
||||||
for (String i : thread.keySet()) {
|
for (String i : thread.keySet()) {
|
||||||
waitFor(i);
|
waitFor(i);
|
||||||
|
@ -210,7 +274,7 @@ public class ExternalSubCreator extends SubCreator {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void waitFor(String name) throws InterruptedException {
|
public void waitFor(String name) throws InterruptedException {
|
||||||
while (this.thread.keySet().contains(name.toLowerCase()) && host.client.get() != null) {
|
while (this.thread.containsKey(name.toLowerCase()) && host.getSubData()[0] != null) {
|
||||||
Thread.sleep(250);
|
Thread.sleep(250);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -239,7 +303,7 @@ public class ExternalSubCreator extends SubCreator {
|
||||||
@Override
|
@Override
|
||||||
public List<SubLogger> getLoggers() {
|
public List<SubLogger> getLoggers() {
|
||||||
List<SubLogger> loggers = new ArrayList<SubLogger>();
|
List<SubLogger> loggers = new ArrayList<SubLogger>();
|
||||||
HashMap<String, NamedContainer<Integer, ExternalSubLogger>> temp = new HashMap<String, NamedContainer<Integer, ExternalSubLogger>>();
|
HashMap<String, Pair<Integer, ExternalSubLogger>> temp = new HashMap<String, Pair<Integer, ExternalSubLogger>>();
|
||||||
temp.putAll(thread);
|
temp.putAll(thread);
|
||||||
for (String i : temp.keySet()) {
|
for (String i : temp.keySet()) {
|
||||||
loggers.add(getLogger(i));
|
loggers.add(getLogger(i));
|
||||||
|
@ -249,18 +313,18 @@ public class ExternalSubCreator extends SubCreator {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SubLogger getLogger(String name) {
|
public SubLogger getLogger(String name) {
|
||||||
return this.thread.get(name.toLowerCase()).get();
|
return this.thread.get(name.toLowerCase()).value();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLogging() {
|
public boolean isLogging() {
|
||||||
return log.get();
|
return log.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setLogging(boolean value) {
|
public void setLogging(boolean value) {
|
||||||
if (Util.isNull(value)) throw new NullPointerException();
|
Util.nullpo(value);
|
||||||
log.set(value);
|
log.value(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -271,18 +335,33 @@ public class ExternalSubCreator extends SubCreator {
|
||||||
@Override
|
@Override
|
||||||
public List<Integer> getReservedPorts() {
|
public List<Integer> getReservedPorts() {
|
||||||
List<Integer> ports = new ArrayList<Integer>();
|
List<Integer> ports = new ArrayList<Integer>();
|
||||||
for (NamedContainer<Integer, ExternalSubLogger> task : thread.values()) ports.add(task.name());
|
for (Pair<Integer, ExternalSubLogger> task : thread.values()) ports.add(task.key());
|
||||||
return ports;
|
return ports;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, ServerTemplate> getTemplates() {
|
public Map<String, ServerTemplate> getTemplates() {
|
||||||
return new TreeMap<String, ServerTemplate>(templates);
|
TreeMap<String, ServerTemplate> map = new TreeMap<String, ServerTemplate>();
|
||||||
|
if (enableRT != null && enableRT) for (Map.Entry<String, ServerTemplate> template : templatesR.entrySet()) {
|
||||||
|
if (!template.getValue().isInternal()) map.put(template.getKey(), template.getValue());
|
||||||
|
}
|
||||||
|
for (Map.Entry<String, ServerTemplate> template : templates.entrySet()) {
|
||||||
|
if (!template.getValue().isInternal()) map.put(template.getKey(), template.getValue());
|
||||||
|
}
|
||||||
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ServerTemplate getTemplate(String name) {
|
public ServerTemplate getTemplate(String name) {
|
||||||
if (Util.isNull(name)) throw new NullPointerException();
|
Util.nullpo(name);
|
||||||
return getTemplates().get(name.toLowerCase());
|
name = name.toLowerCase();
|
||||||
|
|
||||||
|
ServerTemplate template = templates.getOrDefault(name, null);
|
||||||
|
if (template == null && enableRT != null && enableRT) template = templatesR.getOrDefault(name, null);
|
||||||
|
if (template == null || template.isInternal()) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return template;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,36 +1,37 @@
|
||||||
package net.ME1312.SubServers.Bungee.Host.External;
|
package net.ME1312.SubServers.Bungee.Host.External;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Container.Value;
|
||||||
|
import net.ME1312.Galaxi.Library.Try;
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
import net.ME1312.SubServers.Bungee.Host.SubLogFilter;
|
import net.ME1312.SubServers.Bungee.Host.SubLogFilter;
|
||||||
import net.ME1312.SubServers.Bungee.Host.SubLogger;
|
import net.ME1312.SubServers.Bungee.Host.SubLogger;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Container;
|
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketInExLogMessage;
|
import net.ME1312.SubServers.Bungee.Network.Packet.PacketInExLogMessage;
|
||||||
import net.ME1312.SubServers.Bungee.SubAPI;
|
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedList;
|
import java.util.Calendar;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* External Process Logger Class
|
* External Process Logger Class
|
||||||
*/
|
*/
|
||||||
public class ExternalSubLogger extends SubLogger {
|
public class ExternalSubLogger extends SubLogger {
|
||||||
private Object handle;
|
private Object handle;
|
||||||
protected UUID id = null;
|
UUID id = null;
|
||||||
protected String name;
|
String name;
|
||||||
protected Container<Boolean> log;
|
Value<Boolean> log;
|
||||||
private List<SubLogFilter> filters = new ArrayList<SubLogFilter>();
|
private List<SubLogFilter> filters = new CopyOnWriteArrayList<>();
|
||||||
protected File file;
|
File file;
|
||||||
private PrintWriter writer = null;
|
private PrintWriter writer = null;
|
||||||
private boolean started = false;
|
private boolean started = false;
|
||||||
|
|
||||||
|
@ -42,7 +43,7 @@ public class ExternalSubLogger extends SubLogger {
|
||||||
* @param log Console Logging Status
|
* @param log Console Logging Status
|
||||||
* @param file File to log to (or null for disabled)
|
* @param file File to log to (or null for disabled)
|
||||||
*/
|
*/
|
||||||
protected ExternalSubLogger(Object user, String name, Container<Boolean> log, File file) {
|
ExternalSubLogger(Object user, String name, Value<Boolean> log, File file) {
|
||||||
this.handle = user;
|
this.handle = user;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.log = log;
|
this.log = log;
|
||||||
|
@ -72,29 +73,20 @@ public class ExternalSubLogger extends SubLogger {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
private void log(String line) {
|
private void log(int type, String msg) {
|
||||||
if (started) {
|
if (started) {
|
||||||
String msg = line;
|
|
||||||
Level level;
|
Level level;
|
||||||
|
|
||||||
// REGEX Formatting
|
|
||||||
String type = "";
|
|
||||||
Matcher matcher = Pattern.compile("^((?:\\s*\\[?([0-9]{2}:[0-9]{2}:[0-9]{2})]?)?[\\s\\/\\\\\\|]*(?:\\[|\\[.*\\/)?(MESSAGE|INFO|WARNING|WARN|ERROR|ERR|SEVERE)\\]?:?(?:\\s*>)?\\s*)").matcher(msg.replaceAll("\u001B\\[[;\\d]*m", ""));
|
|
||||||
while (matcher.find()) {
|
|
||||||
type = matcher.group(3).toUpperCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
msg = msg.substring(msg.length() - msg.replaceAll("^((?:\\s*\\[?([0-9]{2}:[0-9]{2}:[0-9]{2})]?)?[\\s\\/\\\\\\|]*(?:\\[|\\[.*\\/)?(MESSAGE|INFO|WARNING|WARN|ERROR|ERR|SEVERE)\\]?:?(?:\\s*>)?\\s*)", "").length());
|
|
||||||
|
|
||||||
// Determine LOG LEVEL
|
// Determine LOG LEVEL
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "WARNING":
|
case 80:
|
||||||
case "WARN":
|
level = Level.FINE;
|
||||||
|
break;
|
||||||
|
case 40:
|
||||||
level = Level.WARNING;
|
level = Level.WARNING;
|
||||||
break;
|
break;
|
||||||
case "SEVERE":
|
case 30:
|
||||||
case "ERROR":
|
case 20:
|
||||||
case "ERR":
|
|
||||||
level = Level.SEVERE;
|
level = Level.SEVERE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -102,7 +94,7 @@ public class ExternalSubLogger extends SubLogger {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter Message
|
// Filter Message
|
||||||
boolean allow = (SubAPI.getInstance().getInternals().sudo == getHandler() && SubAPI.getInstance().getInternals().canSudo) || (log.get() && (SubAPI.getInstance().getInternals().sudo == null || !SubAPI.getInstance().getInternals().canSudo));
|
boolean allow = (SubAPI.getInstance().getInternals().sudo == getHandler() && SubAPI.getInstance().getInternals().canSudo) || (log.value() && (SubAPI.getInstance().getInternals().sudo == null || !SubAPI.getInstance().getInternals().canSudo));
|
||||||
List<SubLogFilter> filters = new ArrayList<SubLogFilter>();
|
List<SubLogFilter> filters = new ArrayList<SubLogFilter>();
|
||||||
filters.addAll(this.filters);
|
filters.addAll(this.filters);
|
||||||
for (SubLogFilter filter : filters)
|
for (SubLogFilter filter : filters)
|
||||||
|
@ -113,11 +105,11 @@ public class ExternalSubLogger extends SubLogger {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log to CONSOLE
|
// Log to CONSOLE
|
||||||
if (allow) ProxyServer.getInstance().getLogger().log(level, name + " > " + msg);
|
if (allow) Logger.get(name).log(level, msg);
|
||||||
|
|
||||||
// Log to FILE
|
// Log to FILE
|
||||||
if (writer != null) {
|
if (writer != null) {
|
||||||
writer.println(line);
|
writer.println('[' + new SimpleDateFormat("HH:mm:ss").format(Calendar.getInstance().getTime()) + "] [" + level + "] > " + msg);
|
||||||
writer.flush();
|
writer.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,20 +126,19 @@ public class ExternalSubLogger extends SubLogger {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerFilter(SubLogFilter filter) {
|
public void registerFilter(SubLogFilter filter) {
|
||||||
if (Util.isNull(filter)) throw new NullPointerException();
|
Util.nullpo(filter);
|
||||||
filters.add(filter);
|
filters.add(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unregisterFilter(SubLogFilter filter) {
|
public void unregisterFilter(SubLogFilter filter) {
|
||||||
if (Util.isNull(filter)) throw new NullPointerException();
|
Util.nullpo(filter);
|
||||||
filters.remove(filter);
|
Try.all.run(() -> filters.remove(filter));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stop() {
|
public void stop() {
|
||||||
if (started) {
|
if (started) {
|
||||||
PacketInExLogMessage.unregister(id);
|
|
||||||
id = null;
|
id = null;
|
||||||
started = false;
|
started = false;
|
||||||
List<SubLogFilter> filters = new ArrayList<SubLogFilter>();
|
List<SubLogFilter> filters = new ArrayList<SubLogFilter>();
|
||||||
|
@ -160,7 +151,7 @@ public class ExternalSubLogger extends SubLogger {
|
||||||
if (writer != null) {
|
if (writer != null) {
|
||||||
PrintWriter writer = this.writer;
|
PrintWriter writer = this.writer;
|
||||||
this.writer = null;
|
this.writer = null;
|
||||||
int l = (int) Math.floor((("---------- LOG START \u2014 " + name + " ----------").length() - 9) / 2);
|
int l = (("---------- LOG START \u2014 " + name + " ----------").length() - 9) / 2;
|
||||||
String s = "";
|
String s = "";
|
||||||
while (s.length() < l) s += '-';
|
while (s.length() < l) s += '-';
|
||||||
writer.println(s + " LOG END " + s);
|
writer.println(s + " LOG END " + s);
|
||||||
|
@ -181,6 +172,6 @@ public class ExternalSubLogger extends SubLogger {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLogging() {
|
public boolean isLogging() {
|
||||||
return log.get();
|
return log.value();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,34 +1,41 @@
|
||||||
package net.ME1312.SubServers.Bungee.Host.External;
|
package net.ME1312.SubServers.Bungee.Host.External;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Container.ContainedPair;
|
||||||
|
import net.ME1312.Galaxi.Library.Container.Container;
|
||||||
|
import net.ME1312.Galaxi.Library.Container.Value;
|
||||||
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
|
import net.ME1312.Galaxi.Library.Map.ObjectMapValue;
|
||||||
|
import net.ME1312.Galaxi.Library.Try;
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
|
import net.ME1312.SubData.Server.SubDataClient;
|
||||||
import net.ME1312.SubServers.Bungee.Event.*;
|
import net.ME1312.SubServers.Bungee.Event.*;
|
||||||
import net.ME1312.SubServers.Bungee.Host.*;
|
import net.ME1312.SubServers.Bungee.Host.*;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLValue;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Container;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
||||||
import net.ME1312.SubServers.Bungee.Library.NamedContainer;
|
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExControlServer;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExControlServer.Action;
|
||||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExUpdateServer;
|
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutExEditServer;
|
||||||
|
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutExEditServer.Edit;
|
||||||
import net.ME1312.SubServers.Bungee.SubAPI;
|
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||||
import net.md_5.bungee.BungeeServerInfo;
|
|
||||||
|
|
||||||
import java.io.File;
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* External SubServer Class
|
* External SubServer Class
|
||||||
*/
|
*/
|
||||||
public class ExternalSubServer extends SubServerContainer {
|
public class ExternalSubServer extends SubServerImpl {
|
||||||
private ExternalHost host;
|
private ExternalHost host;
|
||||||
private boolean enabled;
|
private boolean enabled;
|
||||||
private Container<Boolean> log;
|
private Value<Boolean> log;
|
||||||
private String dir;
|
private String dir;
|
||||||
protected String exec;
|
String exec;
|
||||||
private String stopcmd;
|
private String stopcmd;
|
||||||
private StopAction stopaction;
|
private StopAction stopaction;
|
||||||
private LinkedList<LoggedCommand> history;
|
private LinkedList<LoggedCommand> history;
|
||||||
|
@ -52,9 +59,34 @@ public class ExternalSubServer extends SubServerContainer {
|
||||||
* @param restricted Restricted Status
|
* @param restricted Restricted Status
|
||||||
* @throws InvalidServerException
|
* @throws InvalidServerException
|
||||||
*/
|
*/
|
||||||
public ExternalSubServer(ExternalHost host, String name, boolean enabled, int port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
public static ExternalSubServer construct(ExternalHost host, String name, boolean enabled, int port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||||
|
try {
|
||||||
|
return new ExternalSubServer(host, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||||
|
} catch (NoSuchMethodError e) {
|
||||||
|
return new ExternalSubServer(host, name, enabled, (Integer) port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Super Method 2 (newest)
|
||||||
|
* @see #construct(ExternalHost, String, boolean, int, String, boolean, String, String, String, boolean, boolean) for method details
|
||||||
|
*/
|
||||||
|
protected ExternalSubServer(ExternalHost host, String name, boolean enabled, int port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||||
super(host, name, port, motd, hidden, restricted);
|
super(host, name, port, motd, hidden, restricted);
|
||||||
if (Util.isNull(host, name, enabled, port, motd, log, stopcmd, hidden, restricted)) throw new NullPointerException();
|
init(host, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Super Method 1 (oldest)
|
||||||
|
* @see #construct(ExternalHost, String, boolean, int, String, boolean, String, String, String, boolean, boolean) for method details
|
||||||
|
*/
|
||||||
|
protected ExternalSubServer(ExternalHost host, String name, boolean enabled, Integer port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||||
|
super(host, name, port, motd, hidden, restricted);
|
||||||
|
init(host, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init(ExternalHost host, String name, boolean enabled, int port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||||
|
Util.nullpo(host, name, enabled, port, motd, log, stopcmd, hidden, restricted);
|
||||||
this.host = host;
|
this.host = host;
|
||||||
this.enabled = enabled;
|
this.enabled = enabled;
|
||||||
this.log = new Container<Boolean>(log);
|
this.log = new Container<Boolean>(log);
|
||||||
|
@ -69,24 +101,46 @@ public class ExternalSubServer extends SubServerContainer {
|
||||||
this.lock = false;
|
this.lock = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void registered(boolean value) {
|
||||||
|
registered = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updating(boolean value) {
|
||||||
|
updating = value;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean start(UUID player) {
|
public boolean start(UUID player) {
|
||||||
if (!lock && isEnabled() && !running && getCurrentIncompatibilities().size() == 0) {
|
if (!lock && isAvailable() && isEnabled() && !running && getCurrentIncompatibilities().size() == 0) {
|
||||||
lock = true;
|
lock = true;
|
||||||
SubStartEvent event = new SubStartEvent(player, this);
|
SubStartEvent event = new SubStartEvent(player, this);
|
||||||
host.plugin.getPluginManager().callEvent(event);
|
host.plugin.getPluginManager().callEvent(event);
|
||||||
lock = false;
|
|
||||||
if (!event.isCancelled()) {
|
if (!event.isCancelled()) {
|
||||||
System.out.println("SubServers > Now starting " + getName());
|
Logger.get("SubServers").info("Now starting " + getName());
|
||||||
running = true;
|
started(null);
|
||||||
logger.start();
|
host.queue(new PacketExControlServer(this, Action.START, logger.getExternalAddress().toString()));
|
||||||
host.queue(new PacketExUpdateServer(this, PacketExUpdateServer.UpdateType.START, logger.getExternalAddress().toString()));
|
|
||||||
return true;
|
return true;
|
||||||
} else return false;
|
} else {
|
||||||
|
lock = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
} else return false;
|
} else return false;
|
||||||
}
|
}
|
||||||
|
void started(UUID address) {
|
||||||
|
if (!running) {
|
||||||
|
stopping = false;
|
||||||
|
started = false;
|
||||||
|
running = true;
|
||||||
|
lock = false;
|
||||||
|
logger.start();
|
||||||
|
if (address != null) {
|
||||||
|
if (address != logger.getExternalAddress()) host.queue(new PacketExControlServer(this, Action.SET_LOGGING_ADDRESS, logger.getExternalAddress().toString()));
|
||||||
|
host.plugin.getPluginManager().callEvent(new SubStartEvent(null, this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
private void falsestart() {
|
private void falsestart() {
|
||||||
System.out.println("SubServers > Couldn't start " + getName() + " - See the " + host.getName() + " console for more details");
|
Logger.get("SubServers").info("Couldn't start " + getName() + " - See the " + host.getName() + " console for more details");
|
||||||
running = false;
|
running = false;
|
||||||
logger.stop();
|
logger.stop();
|
||||||
}
|
}
|
||||||
|
@ -98,28 +152,33 @@ public class ExternalSubServer extends SubServerContainer {
|
||||||
host.plugin.getPluginManager().callEvent(event);
|
host.plugin.getPluginManager().callEvent(event);
|
||||||
if (!event.isCancelled()) {
|
if (!event.isCancelled()) {
|
||||||
history.add(new LoggedCommand(player, stopcmd));
|
history.add(new LoggedCommand(player, stopcmd));
|
||||||
host.queue(new PacketExUpdateServer(this, PacketExUpdateServer.UpdateType.STOP));
|
host.queue(new PacketExControlServer(this, Action.STOP));
|
||||||
|
stopping = true;
|
||||||
return true;
|
return true;
|
||||||
} else return false;
|
} else return false;
|
||||||
} else return false;
|
} else return false;
|
||||||
}
|
}
|
||||||
private void stopped(Boolean allowrestart) {
|
void stopped(Boolean allowrestart) {
|
||||||
SubStoppedEvent event = new SubStoppedEvent(this);
|
|
||||||
host.plugin.getPluginManager().callEvent(event);
|
|
||||||
System.out.println("SubServers > " + getName() + " has stopped");
|
|
||||||
logger.stop();
|
logger.stop();
|
||||||
history.clear();
|
history.clear();
|
||||||
|
started = false;
|
||||||
running = false;
|
running = false;
|
||||||
|
stopping = false;
|
||||||
|
SubStoppedEvent event = new SubStoppedEvent(this);
|
||||||
|
host.plugin.getPluginManager().callEvent(event);
|
||||||
|
Logger.get("SubServers").info(getName() + " has stopped");
|
||||||
|
|
||||||
if (stopaction == StopAction.REMOVE_SERVER || stopaction == StopAction.DELETE_SERVER) {
|
if (stopaction == StopAction.REMOVE_SERVER || stopaction == StopAction.RECYCLE_SERVER || stopaction == StopAction.DELETE_SERVER) {
|
||||||
try {
|
try {
|
||||||
if (stopaction == StopAction.DELETE_SERVER) {
|
if (stopaction == StopAction.RECYCLE_SERVER) {
|
||||||
|
host.recycleSubServer(getName());
|
||||||
|
} else if (stopaction == StopAction.DELETE_SERVER) {
|
||||||
host.deleteSubServer(getName());
|
host.deleteSubServer(getName());
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
if (host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
if (host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
host.plugin.config.get().getSection("Servers").remove(getName());
|
host.plugin.servers.get().getMap("Servers").remove(getName());
|
||||||
host.plugin.config.save();
|
host.plugin.servers.save();
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -149,7 +208,8 @@ public class ExternalSubServer extends SubServerContainer {
|
||||||
SubStopEvent event = new SubStopEvent(player, this, true);
|
SubStopEvent event = new SubStopEvent(player, this, true);
|
||||||
host.plugin.getPluginManager().callEvent(event);
|
host.plugin.getPluginManager().callEvent(event);
|
||||||
if (!event.isCancelled()) {
|
if (!event.isCancelled()) {
|
||||||
host.queue(new PacketExUpdateServer(this, PacketExUpdateServer.UpdateType.TERMINATE));
|
host.queue(new PacketExControlServer(this, Action.TERMINATE));
|
||||||
|
stopping = true;
|
||||||
return true;
|
return true;
|
||||||
} else return false;
|
} else return false;
|
||||||
} else return false;
|
} else return false;
|
||||||
|
@ -157,294 +217,317 @@ public class ExternalSubServer extends SubServerContainer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean command(UUID player, String command) {
|
public boolean command(UUID player, String command) {
|
||||||
if (Util.isNull(command)) throw new NullPointerException();
|
Util.nullpo(command);
|
||||||
if (running) {
|
if (running) {
|
||||||
SubSendCommandEvent event = new SubSendCommandEvent(player, this, command);
|
SubSendCommandEvent event = new SubSendCommandEvent(player, this, command, null);
|
||||||
host.plugin.getPluginManager().callEvent(event);
|
host.plugin.getPluginManager().callEvent(event);
|
||||||
if (!event.isCancelled()) {
|
if (!event.isCancelled() && (player == null || !DISALLOWED_COMMANDS.matcher(command).find())) {
|
||||||
history.add(new LoggedCommand(player, event.getCommand()));
|
history.add(new LoggedCommand(player, event.getCommand()));
|
||||||
if (event.getCommand().equalsIgnoreCase(stopcmd)) {
|
if (event.getCommand().equalsIgnoreCase(stopcmd)) {
|
||||||
host.queue(new PacketExUpdateServer(this, PacketExUpdateServer.UpdateType.STOP));
|
host.queue(new PacketExControlServer(this, Action.STOP));
|
||||||
|
stopping = true;
|
||||||
} else {
|
} else {
|
||||||
host.queue(new PacketExUpdateServer(this, PacketExUpdateServer.UpdateType.COMMAND, event.getCommand()));
|
host.queue(new PacketExControlServer(this, Action.COMMAND, event.getCommand()));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else return false;
|
} else return false;
|
||||||
} else return false;
|
} else return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"deprecation", "unchecked"})
|
||||||
|
@Override
|
||||||
@SuppressWarnings("deprecation")
|
protected int edit(UUID player, ObjectMap<String> edit, boolean perma) {
|
||||||
public int edit(UUID player, YAMLSection edit) {
|
if (isAvailable()) {
|
||||||
int c = 0;
|
int c = 0;
|
||||||
boolean state = isRunning();
|
boolean state = isRunning();
|
||||||
SubServer forward = null;
|
SubServer forward = null;
|
||||||
YAMLSection pending = edit.clone();
|
ObjectMap<String> pending = edit.clone();
|
||||||
for (String key : edit.getKeys()) {
|
for (String key : edit.getKeys()) {
|
||||||
pending.remove(key);
|
pending.remove(key);
|
||||||
YAMLValue value = edit.get(key);
|
ObjectMapValue value = edit.get(key);
|
||||||
SubEditServerEvent event = new SubEditServerEvent(player, this, new NamedContainer<String, YAMLValue>(key, value), true);
|
boolean allowed = true;
|
||||||
host.plugin.getPluginManager().callEvent(event);
|
if (perma) {
|
||||||
if (!event.isCancelled()) {
|
SubEditServerEvent event = new SubEditServerEvent(player, this, new ContainedPair<String, ObjectMapValue>(key, value));
|
||||||
try {
|
host.plugin.getPluginManager().callEvent(event);
|
||||||
switch (key) {
|
allowed = !event.isCancelled();
|
||||||
case "name":
|
}
|
||||||
if (value.isString() && host.removeSubServer(player, getName())) {
|
if (allowed) {
|
||||||
SubServer server = host.addSubServer(player, value.asRawString(), isEnabled(), getAddress().getPort(), getMotd(), isLogging(), getPath(), getExecutable(), getStopCommand(), isHidden(), isRestricted());
|
try {
|
||||||
if (server != null) {
|
switch (key.toLowerCase()) {
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
case "name":
|
||||||
YAMLSection config = this.host.plugin.config.get().getSection("Servers").getSection(getName());
|
if (value.isString() && host.removeSubServer(player, getName())) {
|
||||||
this.host.plugin.config.get().getSection("Servers").remove(getName());
|
SubServer server = host.constructSubServer(value.asString(), isEnabled(), getAddress().getPort(), getMotd(), isLogging(), getPath(), getExecutable(), getStopCommand(), isHidden(), isRestricted());
|
||||||
this.host.plugin.config.get().getSection("Servers").set(server.getName(), config);
|
if (server != null) {
|
||||||
this.host.plugin.config.save();
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
|
ObjectMap<String> config = this.host.plugin.servers.get().getMap("Servers").getMap(getName());
|
||||||
|
this.host.plugin.servers.get().getMap("Servers").remove(getName());
|
||||||
|
this.host.plugin.servers.get().getMap("Servers").set(server.getName(), config);
|
||||||
|
this.host.plugin.servers.save();
|
||||||
|
}
|
||||||
|
forward = server;
|
||||||
|
c++;
|
||||||
}
|
}
|
||||||
forward = server;
|
|
||||||
c++;
|
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
break;
|
case "display":
|
||||||
case "display":
|
if (value.isString()) {
|
||||||
if (value.isString()) {
|
setDisplayName(value.asString());
|
||||||
Field f = ServerContainer.class.getDeclaredField("nick");
|
logger.name = getDisplayName();
|
||||||
f.setAccessible(true);
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
if (value == null || value.asString().length() == 0 || getName().equals(value)) {
|
if (getName().equals(getDisplayName())) {
|
||||||
f.set(this, null);
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).remove("Display");
|
||||||
} else {
|
} else {
|
||||||
f.set(this, value.asString());
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Display", getDisplayName());
|
||||||
}
|
}
|
||||||
f.setAccessible(false);
|
this.host.plugin.servers.save();
|
||||||
logger.name = getDisplayName();
|
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
|
||||||
if (getName().equals(getDisplayName())) {
|
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).remove("Display");
|
|
||||||
} else {
|
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Display", getDisplayName());
|
|
||||||
}
|
|
||||||
this.host.plugin.config.save();
|
|
||||||
}
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "enabled":
|
|
||||||
if (value.isBoolean()) {
|
|
||||||
if (enabled != value.asBoolean()) host.queue(new PacketExUpdateServer(this, PacketExUpdateServer.UpdateType.SET_ENABLED, (Boolean) value.asBoolean()));
|
|
||||||
enabled = value.asBoolean();
|
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Enabled", isEnabled());
|
|
||||||
this.host.plugin.config.save();
|
|
||||||
}
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "group":
|
|
||||||
if (value.isList()) {
|
|
||||||
Util.reflect(ServerContainer.class.getDeclaredField("groups"), this, value.asStringList());
|
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Group", value.asStringList());
|
|
||||||
this.host.plugin.config.save();
|
|
||||||
}
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "host":
|
|
||||||
if (value.isString() && host.removeSubServer(player, getName())) {
|
|
||||||
waitFor(() -> host.getSubServer(getName()), null);
|
|
||||||
SubServer server = this.host.plugin.api.getHost(value.asRawString()).addSubServer(player, getName(), isEnabled(), getAddress().getPort(), getMotd(), isLogging(), getPath(), getExecutable(), getStopCommand(), isHidden(), isRestricted());
|
|
||||||
if (server != null) {
|
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Host", server.getHost().getName());
|
|
||||||
this.host.plugin.config.save();
|
|
||||||
}
|
|
||||||
forward = server;
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "port":
|
|
||||||
if (value.isNumber() && host.removeSubServer(player, getName())) {
|
|
||||||
waitFor(() -> host.getSubServer(getName()), null);
|
|
||||||
SubServer server = host.addSubServer(player, getName(), isEnabled(), value.asInt(), getMotd(), isLogging(), getPath(), getExecutable(), getStopCommand(), isHidden(), isRestricted());
|
|
||||||
if (server != null) {
|
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Port", server.getAddress().getPort());
|
|
||||||
this.host.plugin.config.save();
|
|
||||||
}
|
|
||||||
forward = server;
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "motd":
|
|
||||||
if (value.isString()) {
|
|
||||||
Util.reflect(BungeeServerInfo.class.getDeclaredField("motd"), this, value.asColoredString('&'));
|
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Motd", value.asString());
|
|
||||||
this.host.plugin.config.save();
|
|
||||||
}
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "log":
|
|
||||||
if (value.isBoolean()) {
|
|
||||||
if (log.get() != value.asBoolean()) host.queue(new PacketExUpdateServer(this, PacketExUpdateServer.UpdateType.SET_LOGGING, (Boolean) value.asBoolean()));
|
|
||||||
log.set(value.asBoolean());
|
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Log", isLogging());
|
|
||||||
this.host.plugin.config.save();
|
|
||||||
}
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "dir":
|
|
||||||
if (value.isString() && host.removeSubServer(player, getName())) {
|
|
||||||
waitFor(() -> host.getSubServer(getName()), null);
|
|
||||||
SubServer server = host.addSubServer(player, getName(), isEnabled(), getAddress().getPort(), getMotd(), isLogging(), value.asRawString(), getExecutable(), getStopCommand(), isHidden(), isRestricted());
|
|
||||||
if (server != null) {
|
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Directory", server.getPath());
|
|
||||||
this.host.plugin.config.save();
|
|
||||||
}
|
|
||||||
forward = server;
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "exec":
|
|
||||||
if (value.isString() && host.removeSubServer(player, getName())) {
|
|
||||||
waitFor(() -> host.getSubServer(getName()), null);
|
|
||||||
SubServer server = host.addSubServer(player, getName(), isEnabled(), getAddress().getPort(), getMotd(), isLogging(), getPath(), value.asRawString(), getStopCommand(), isHidden(), isRestricted());
|
|
||||||
if (server != null) {
|
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Executable", value.asRawString());
|
|
||||||
this.host.plugin.config.save();
|
|
||||||
}
|
|
||||||
forward = server;
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "state":
|
|
||||||
if (value.isBoolean()) {
|
|
||||||
state = value.asBoolean();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "stop-cmd":
|
|
||||||
if (value.isString()) {
|
|
||||||
if (!stopcmd.equals(value)) host.queue(new PacketExUpdateServer(this, PacketExUpdateServer.UpdateType.SET_STOP_COMMAND, value.asRawString()));
|
|
||||||
stopcmd = value.asRawString();
|
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Stop-Command", getStopCommand());
|
|
||||||
this.host.plugin.config.save();
|
|
||||||
}
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "stop-action":
|
|
||||||
if (value.isString()) {
|
|
||||||
StopAction action = Util.getDespiteException(() -> StopAction.valueOf(value.asRawString().toUpperCase().replace('-', '_').replace(' ', '_')), null);
|
|
||||||
if (action != null) {
|
|
||||||
stopaction = action;
|
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Stop-Action", getStopAction().toString());
|
|
||||||
this.host.plugin.config.save();
|
|
||||||
}
|
}
|
||||||
c++;
|
c++;
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
break;
|
case "enabled":
|
||||||
case "auto-run":
|
if (value.isBoolean()) {
|
||||||
if (value.isBoolean()) {
|
if (enabled != value.asBoolean()) host.queue(new PacketExControlServer(this, Action.SET_ENABLED, (Boolean) value.asBoolean()));
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
enabled = value.asBoolean();
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Run-On-Launch", value.asBoolean());
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
this.host.plugin.config.save();
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Enabled", isEnabled());
|
||||||
|
this.host.plugin.servers.save();
|
||||||
|
}
|
||||||
|
c++;
|
||||||
}
|
}
|
||||||
c++;
|
break;
|
||||||
}
|
case "group":
|
||||||
break;
|
if (value.isList()) {
|
||||||
case "incompatible":
|
Util.reflect(ServerImpl.class.getDeclaredField("groups"), this, value.asStringList());
|
||||||
if (value.isList()) {
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
for (String oname : value.asStringList()) {
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Group", value.asStringList());
|
||||||
SubServer oserver = host.plugin.api.getSubServer(oname);
|
this.host.plugin.servers.save();
|
||||||
if (oserver != null && isCompatible(oserver)) toggleCompatibility(oserver);
|
}
|
||||||
|
c++;
|
||||||
}
|
}
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
break;
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Incompatible", value.asStringList());
|
case "host":
|
||||||
this.host.plugin.config.save();
|
if (value.isString() && host.removeSubServer(player, getName())) {
|
||||||
|
waitFor(() -> host.getSubServer(getName()), null);
|
||||||
|
SubServer server = this.host.plugin.api.getHost(value.asString()).constructSubServer(getName(), isEnabled(), getAddress().getPort(), getMotd(), isLogging(), getPath(), getExecutable(), getStopCommand(), isHidden(), isRestricted());
|
||||||
|
if (server != null) {
|
||||||
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Host", server.getHost().getName());
|
||||||
|
this.host.plugin.servers.save();
|
||||||
|
}
|
||||||
|
forward = server;
|
||||||
|
c++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
c++;
|
break;
|
||||||
}
|
case "template":
|
||||||
break;
|
if (value.isString()) {
|
||||||
case "restricted":
|
setTemplate(value.asString());
|
||||||
if (value.isBoolean()) {
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
Util.reflect(BungeeServerInfo.class.getDeclaredField("restricted"), this, value.asBoolean());
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Template", value.asString());
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
this.host.plugin.servers.save();
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Restricted", isRestricted());
|
}
|
||||||
this.host.plugin.config.save();
|
c++;
|
||||||
}
|
}
|
||||||
c++;
|
break;
|
||||||
}
|
case "port":
|
||||||
break;
|
if (value.isNumber() && host.removeSubServer(player, getName())) {
|
||||||
case "hidden":
|
waitFor(() -> host.getSubServer(getName()), null);
|
||||||
if (value.isBoolean()) {
|
SubServer server = host.constructSubServer(getName(), isEnabled(), value.asInt(), getMotd(), isLogging(), getPath(), getExecutable(), getStopCommand(), isHidden(), isRestricted());
|
||||||
Util.reflect(ServerContainer.class.getDeclaredField("hidden"), this, value.asBoolean());
|
if (server != null) {
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Hidden", isHidden());
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Port", server.getAddress().getPort());
|
||||||
this.host.plugin.config.save();
|
this.host.plugin.servers.save();
|
||||||
|
}
|
||||||
|
forward = server;
|
||||||
|
c++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
c++;
|
break;
|
||||||
}
|
case "motd":
|
||||||
break;
|
if (value.isString()) {
|
||||||
}
|
setMotd(ChatColor.translateAlternateColorCodes('&', Util.unescapeJavaString(value.asString())));
|
||||||
if (forward != null) {
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
forward.setStopAction(getStopAction());
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Motd", value.asString());
|
||||||
if (!getName().equals(getDisplayName())) forward.setDisplayName(getDisplayName());
|
this.host.plugin.servers.save();
|
||||||
List<String> groups = new ArrayList<String>();
|
}
|
||||||
groups.addAll(getGroups());
|
c++;
|
||||||
for (String group : groups) {
|
}
|
||||||
removeGroup(group);
|
break;
|
||||||
forward.addGroup(group);
|
case "log":
|
||||||
|
if (value.isBoolean()) {
|
||||||
|
if (log.value() != value.asBoolean()) host.queue(new PacketExControlServer(this, Action.SET_LOGGING, (Boolean) value.asBoolean()));
|
||||||
|
log.value(value.asBoolean());
|
||||||
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Log", isLogging());
|
||||||
|
this.host.plugin.servers.save();
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "dir":
|
||||||
|
case "directory":
|
||||||
|
if (value.isString() && host.removeSubServer(player, getName())) {
|
||||||
|
waitFor(() -> host.getSubServer(getName()), null);
|
||||||
|
SubServer server = host.constructSubServer(getName(), isEnabled(), getAddress().getPort(), getMotd(), isLogging(), value.asString(), getExecutable(), getStopCommand(), isHidden(), isRestricted());
|
||||||
|
if (server != null) {
|
||||||
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Directory", server.getPath());
|
||||||
|
this.host.plugin.servers.save();
|
||||||
|
}
|
||||||
|
forward = server;
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "exec":
|
||||||
|
case "executable":
|
||||||
|
if (value.isString() && host.removeSubServer(player, getName())) {
|
||||||
|
waitFor(() -> host.getSubServer(getName()), null);
|
||||||
|
SubServer server = host.constructSubServer(getName(), isEnabled(), getAddress().getPort(), getMotd(), isLogging(), getPath(), value.asString(), getStopCommand(), isHidden(), isRestricted());
|
||||||
|
if (server != null) {
|
||||||
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Executable", value.asString());
|
||||||
|
this.host.plugin.servers.save();
|
||||||
|
}
|
||||||
|
forward = server;
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "state":
|
||||||
|
if (value.isBoolean()) {
|
||||||
|
state = value.asBoolean();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "stop-cmd":
|
||||||
|
case "stop-command":
|
||||||
|
if (value.isString()) {
|
||||||
|
if (!stopcmd.equals(value.asString())) host.queue(new PacketExControlServer(this, Action.SET_STOP_COMMAND, value.asString()));
|
||||||
|
stopcmd = value.asString();
|
||||||
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Stop-Command", getStopCommand());
|
||||||
|
this.host.plugin.servers.save();
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "stop-action":
|
||||||
|
if (value.isString()) {
|
||||||
|
StopAction action = Try.all.get(() -> StopAction.valueOf(value.asString().toUpperCase().replace('-', '_').replace(' ', '_')));
|
||||||
|
if (action != null) {
|
||||||
|
stopaction = action;
|
||||||
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Stop-Action", getStopAction().toString());
|
||||||
|
this.host.plugin.servers.save();
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "auto-run":
|
||||||
|
case "run-on-launch":
|
||||||
|
if (value.isBoolean()) {
|
||||||
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Run-On-Launch", value.asBoolean());
|
||||||
|
this.host.plugin.servers.save();
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "incompatible":
|
||||||
|
if (value.isList()) {
|
||||||
|
for (SubServer oserver : getIncompatibilities()) toggleCompatibility(oserver);
|
||||||
|
for (String oname : (List<String>) value.asStringList()) {
|
||||||
|
SubServer oserver = host.plugin.api.getSubServer(oname);
|
||||||
|
if (oserver != null && isCompatible(oserver)) toggleCompatibility(oserver);
|
||||||
|
}
|
||||||
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Incompatible", value.asStringList());
|
||||||
|
this.host.plugin.servers.save();
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "restricted":
|
||||||
|
if (value.isBoolean()) {
|
||||||
|
setRestricted(value.asBoolean());
|
||||||
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Restricted", isRestricted());
|
||||||
|
this.host.plugin.servers.save();
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "hidden":
|
||||||
|
if (value.isBoolean()) {
|
||||||
|
setHidden(value.asBoolean());
|
||||||
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Hidden", isHidden());
|
||||||
|
this.host.plugin.servers.save();
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "whitelist":
|
||||||
|
if (value.isList()) {
|
||||||
|
Util.reflect(ServerImpl.class.getDeclaredField("whitelist"), this, value.asUUIDList());
|
||||||
|
if (isRegistered()) for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) {
|
||||||
|
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.WHITELIST_SET, value.asUUIDList()));
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
for (SubServer server : getIncompatibilities()) {
|
if (forward != null) {
|
||||||
toggleCompatibility(server);
|
forward.setStopAction(getStopAction());
|
||||||
forward.toggleCompatibility(server);
|
if (!getName().equals(getDisplayName())) forward.setDisplayName(getDisplayName());
|
||||||
}
|
List<String> groups = new ArrayList<String>();
|
||||||
for (String extra : getExtra().getKeys()) forward.addExtra(extra, getExtra(extra));
|
forward.setTemplate(getTemplate());
|
||||||
|
groups.addAll(getGroups());
|
||||||
|
for (String group : groups) {
|
||||||
|
removeGroup(group);
|
||||||
|
forward.addGroup(group);
|
||||||
|
}
|
||||||
|
for (SubServer server : getIncompatibilities()) {
|
||||||
|
toggleCompatibility(server);
|
||||||
|
forward.toggleCompatibility(server);
|
||||||
|
}
|
||||||
|
for (String extra : getExtra().getKeys()) forward.addExtra(extra, getExtra(extra));
|
||||||
|
|
||||||
if (state) pending.set("state", true);
|
if (state) pending.set("state", true);
|
||||||
c += forward.edit(player, pending);
|
c += (perma)?forward.permaEdit(player, pending):forward.edit(player, pending);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (!isRunning() && forward == null && state) start(player);
|
||||||
if (!isRunning() && forward == null && state) start(player);
|
return c;
|
||||||
return c;
|
} else return -1;
|
||||||
} private <V> void waitFor(Util.ReturnRunnable<V> method, V value) throws InterruptedException {
|
} private <V> void waitFor(Supplier<V> method, V value) throws InterruptedException {
|
||||||
while (method.run() != value) {
|
while (method.get() != value) {
|
||||||
Thread.sleep(250);
|
Thread.sleep(250);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void waitFor() throws InterruptedException {
|
public void waitFor() throws InterruptedException {
|
||||||
while (running && host.client.get() != null) {
|
while (running && host.getSubData()[0] != null) {
|
||||||
Thread.sleep(250);
|
Thread.sleep(250);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isRunning() {
|
public boolean isRunning() {
|
||||||
return running;
|
return running || lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setDisplayName(String value) {
|
public void setDisplayName(String value) {
|
||||||
super.setDisplayName(value);
|
super.setDisplayName(value);
|
||||||
logger.name = getDisplayName();
|
logger.name = getDisplayName();
|
||||||
host.plugin.getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer<String, Object>("display", value), false));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -454,28 +537,26 @@ public class ExternalSubServer extends SubServerContainer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
return enabled;
|
return enabled && host.isEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setEnabled(boolean value) {
|
public void setEnabled(boolean value) {
|
||||||
if (Util.isNull(value)) throw new NullPointerException();
|
Util.nullpo(value);
|
||||||
host.plugin.getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer<String, Object>("enabled", value), false));
|
if (enabled != value) host.queue(new PacketExControlServer(this, Action.SET_ENABLED, (Boolean) value));
|
||||||
if (enabled != value) host.queue(new PacketExUpdateServer(this, PacketExUpdateServer.UpdateType.SET_ENABLED, (Boolean) value));
|
|
||||||
enabled = value;
|
enabled = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLogging() {
|
public boolean isLogging() {
|
||||||
return log.get();
|
return log.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setLogging(boolean value) {
|
public void setLogging(boolean value) {
|
||||||
if (Util.isNull(value)) throw new NullPointerException();
|
Util.nullpo(value);
|
||||||
host.plugin.getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer<String, Object>("log", value), false));
|
if (log.value() != value) host.queue(new PacketExControlServer(this, Action.SET_LOGGING, (Boolean) value));
|
||||||
if (log.get() != value) host.queue(new PacketExUpdateServer(this, PacketExUpdateServer.UpdateType.SET_LOGGING, (Boolean) value));
|
log.value(value);
|
||||||
log.set(value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -505,9 +586,8 @@ public class ExternalSubServer extends SubServerContainer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setStopCommand(String value) {
|
public void setStopCommand(String value) {
|
||||||
if (Util.isNull(value)) throw new NullPointerException();
|
Util.nullpo(value);
|
||||||
host.plugin.getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer<String, Object>("stop-cmd", value), false));
|
if (!stopcmd.equals(value)) host.queue(new PacketExControlServer(this, Action.SET_STOP_COMMAND, value));
|
||||||
if (!stopcmd.equals(value)) host.queue(new PacketExUpdateServer(this, PacketExUpdateServer.UpdateType.SET_STOP_COMMAND, value));
|
|
||||||
stopcmd = value;
|
stopcmd = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,8 +598,7 @@ public class ExternalSubServer extends SubServerContainer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setStopAction(StopAction action) {
|
public void setStopAction(StopAction action) {
|
||||||
if (Util.isNull(action)) throw new NullPointerException();
|
Util.nullpo(action);
|
||||||
host.plugin.getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer<String, Object>("stop-action", action), false));
|
|
||||||
stopaction = action;
|
stopaction = action;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +1,29 @@
|
||||||
package net.ME1312.SubServers.Bungee.Host;
|
package net.ME1312.SubServers.Bungee.Host;
|
||||||
|
|
||||||
import com.google.common.collect.Range;
|
import net.ME1312.Galaxi.Library.ExtraDataHandler;
|
||||||
import com.google.gson.Gson;
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
import net.ME1312.Galaxi.Library.Map.ObjectMapValue;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLValue;
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
|
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidHostException;
|
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidHostException;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
||||||
import net.ME1312.SubServers.Bungee.Library.ExtraDataHandler;
|
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||||
import net.ME1312.SubServers.Bungee.Library.NamedContainer;
|
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.ClientHandler;
|
import com.google.common.collect.Range;
|
||||||
import net.ME1312.SubServers.Bungee.Network.SubDataServer;
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
|
||||||
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Host Layout Class
|
* Host Layout Class
|
||||||
*/
|
*/
|
||||||
public abstract class Host implements ExtraDataHandler {
|
public abstract class Host implements ExtraDataHandler<String> {
|
||||||
private YAMLSection extra = new YAMLSection();
|
private final ObjectMap<String> extra = new ObjectMap<String>();
|
||||||
private final String signature;
|
private final String signature;
|
||||||
private String nick = null;
|
private String nick = null;
|
||||||
|
|
||||||
|
@ -37,12 +39,13 @@ public abstract class Host implements ExtraDataHandler {
|
||||||
* @param directory The runtime directory of your Host
|
* @param directory The runtime directory of your Host
|
||||||
* @param gitBash The Git Bash directory
|
* @param gitBash The Git Bash directory
|
||||||
*/
|
*/
|
||||||
public Host(SubPlugin plugin, String name, boolean enabled, Range<Integer> ports, boolean log, InetAddress address, String directory, String gitBash) {
|
@SuppressWarnings("deprecation")
|
||||||
|
public Host(SubProxy plugin, String name, boolean enabled, Range<Integer> ports, boolean log, InetAddress address, String directory, String gitBash) {
|
||||||
if (name.contains(" ")) throw new InvalidHostException("Host names cannot have spaces: " + name);
|
if (name.contains(" ")) throw new InvalidHostException("Host names cannot have spaces: " + name);
|
||||||
if (!ports.hasLowerBound() || !ports.hasUpperBound()) throw new InvalidHostException("Port range is not bound");
|
if (!ports.hasLowerBound() || !ports.hasUpperBound()) throw new InvalidHostException("Port range is not bound");
|
||||||
if (Util.isNull(plugin, name, enabled, ports, log, address, directory, gitBash)) throw new NullPointerException();
|
Util.nullpo(plugin, name, enabled, ports, log, address, directory, gitBash);
|
||||||
signature = plugin.api.signAnonymousObject();
|
signature = plugin.api.signAnonymousObject();
|
||||||
SubDataServer.allowConnection(address.getHostAddress());
|
SubAPI.getInstance().getInternals().subprotocol.whitelist(address.getHostAddress());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -111,6 +114,32 @@ public abstract class Host implements ExtraDataHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get players on servers provided by this host
|
||||||
|
*
|
||||||
|
* @return Local Player Collection
|
||||||
|
*/
|
||||||
|
public Collection<ProxiedPlayer> getPlayers() {
|
||||||
|
LinkedList<ProxiedPlayer> players = new LinkedList<ProxiedPlayer>();
|
||||||
|
for (SubServer server : getSubServers().values()) {
|
||||||
|
players.addAll(server.getPlayers());
|
||||||
|
}
|
||||||
|
return players;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get players on servers provided by this host across all known proxies
|
||||||
|
*
|
||||||
|
* @return Remote Player Collection
|
||||||
|
*/
|
||||||
|
public Collection<RemotePlayer> getRemotePlayers() {
|
||||||
|
LinkedList<RemotePlayer> players = new LinkedList<RemotePlayer>();
|
||||||
|
for (SubServer server : getSubServers().values()) {
|
||||||
|
players.addAll(server.getRemotePlayers());
|
||||||
|
}
|
||||||
|
return players;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts the Servers Specified
|
* Starts the Servers Specified
|
||||||
*
|
*
|
||||||
|
@ -236,9 +265,8 @@ public abstract class Host implements ExtraDataHandler {
|
||||||
public abstract SubServer getSubServer(String name);
|
public abstract SubServer getSubServer(String name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a SubServer
|
* Constructs a SubServer (but doesn't add it to the server manager)
|
||||||
*
|
*
|
||||||
* @param player Player who Added
|
|
||||||
* @param name Name of Server
|
* @param name Name of Server
|
||||||
* @param enabled Enabled Status
|
* @param enabled Enabled Status
|
||||||
* @param port Port Number
|
* @param port Port Number
|
||||||
|
@ -252,7 +280,7 @@ public abstract class Host implements ExtraDataHandler {
|
||||||
* @return The SubServer
|
* @return The SubServer
|
||||||
* @throws InvalidServerException
|
* @throws InvalidServerException
|
||||||
*/
|
*/
|
||||||
public abstract SubServer addSubServer(UUID player, String name, boolean enabled, int port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException;
|
public abstract SubServer constructSubServer(String name, boolean enabled, int port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a SubServer
|
* Adds a SubServer
|
||||||
|
@ -274,6 +302,47 @@ public abstract class Host implements ExtraDataHandler {
|
||||||
return addSubServer(null, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
return addSubServer(null, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a SubServer
|
||||||
|
*
|
||||||
|
* @param player Player who Added
|
||||||
|
* @param name Name of Server
|
||||||
|
* @param enabled Enabled Status
|
||||||
|
* @param port Port Number
|
||||||
|
* @param motd Motd of the Server
|
||||||
|
* @param log Logging Status
|
||||||
|
* @param directory Directory
|
||||||
|
* @param executable Executable String
|
||||||
|
* @param stopcmd Command to Stop the Server
|
||||||
|
* @param hidden if the server should be hidden from players
|
||||||
|
* @param restricted Players will need a permission to join if true
|
||||||
|
* @return The SubServer
|
||||||
|
* @throws InvalidServerException
|
||||||
|
*/
|
||||||
|
public SubServer addSubServer(UUID player, String name, boolean enabled, int port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||||
|
SubServer server = constructSubServer(name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||||
|
return (addSubServer(player, server))?server:null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a SubServer
|
||||||
|
*
|
||||||
|
* @param server SubServer to add
|
||||||
|
* @return Success status
|
||||||
|
*/
|
||||||
|
public boolean addSubServer(SubServer server) throws InvalidServerException {
|
||||||
|
return addSubServer(null, server);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a SubServer
|
||||||
|
*
|
||||||
|
* @param player Player who added
|
||||||
|
* @param server SubServer to add
|
||||||
|
* @return Success status
|
||||||
|
*/
|
||||||
|
public abstract boolean addSubServer(UUID player, SubServer server) throws InvalidServerException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a SubServer
|
* Removes a SubServer
|
||||||
*
|
*
|
||||||
|
@ -283,7 +352,7 @@ public abstract class Host implements ExtraDataHandler {
|
||||||
*/
|
*/
|
||||||
public boolean removeSubServer(String name) throws InterruptedException {
|
public boolean removeSubServer(String name) throws InterruptedException {
|
||||||
return removeSubServer(null, name);
|
return removeSubServer(null, name);
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a SubServer
|
* Removes a SubServer
|
||||||
|
@ -293,12 +362,26 @@ public abstract class Host implements ExtraDataHandler {
|
||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
* @return Success Status
|
* @return Success Status
|
||||||
*/
|
*/
|
||||||
public abstract boolean removeSubServer(UUID player, String name) throws InterruptedException;
|
public boolean removeSubServer(UUID player, String name) throws InterruptedException {
|
||||||
|
return removeSubServer(player, name, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a SubServer
|
||||||
|
*
|
||||||
|
* @param player Player Removing
|
||||||
|
* @param name SubServer Name
|
||||||
|
* @param forced Forces the Removal
|
||||||
|
* @throws InterruptedException
|
||||||
|
* @return Success Status
|
||||||
|
*/
|
||||||
|
protected abstract boolean removeSubServer(UUID player, String name, boolean forced) throws InterruptedException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forces the Removal of a SubServer
|
* Forces the Removal of a SubServer
|
||||||
*
|
*
|
||||||
* @param name SubServer Name
|
* @param name SubServer Name
|
||||||
|
* @return Success Status
|
||||||
*/
|
*/
|
||||||
public boolean forceRemoveSubServer(String name) throws InterruptedException {
|
public boolean forceRemoveSubServer(String name) throws InterruptedException {
|
||||||
return forceRemoveSubServer(null, name);
|
return forceRemoveSubServer(null, name);
|
||||||
|
@ -309,11 +392,66 @@ public abstract class Host implements ExtraDataHandler {
|
||||||
*
|
*
|
||||||
* @param player Player Removing
|
* @param player Player Removing
|
||||||
* @param name SubServer Name
|
* @param name SubServer Name
|
||||||
|
* @return Success Status
|
||||||
*/
|
*/
|
||||||
public abstract boolean forceRemoveSubServer(UUID player, String name) throws InterruptedException;
|
public boolean forceRemoveSubServer(UUID player, String name) throws InterruptedException {
|
||||||
|
return removeSubServer(player, name, true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a SubServer
|
* Deletes a SubServer (will move to 'Recently Deleted')
|
||||||
|
*
|
||||||
|
* @param name SubServer Name
|
||||||
|
* @return Success Status
|
||||||
|
*/
|
||||||
|
public boolean recycleSubServer(String name) throws InterruptedException {
|
||||||
|
return recycleSubServer(null, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a SubServer (will move to 'Recently Deleted')
|
||||||
|
*
|
||||||
|
* @param player Player Deleting
|
||||||
|
* @param name SubServer Name
|
||||||
|
* @return Success Status
|
||||||
|
*/
|
||||||
|
public boolean recycleSubServer(UUID player, String name) throws InterruptedException {
|
||||||
|
return recycleSubServer(player, name, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a SubServer (will move to 'Recently Deleted')
|
||||||
|
*
|
||||||
|
* @param player Player Deleting
|
||||||
|
* @param name SubServer Name
|
||||||
|
* @param forced Forces the Deletion
|
||||||
|
* @return Success Status
|
||||||
|
*/
|
||||||
|
protected abstract boolean recycleSubServer(UUID player, String name, boolean forced) throws InterruptedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forces the Deletion of a SubServer (will move to 'Recently Deleted')
|
||||||
|
*
|
||||||
|
* @param name SubServer Name
|
||||||
|
* @return Success Status
|
||||||
|
*/
|
||||||
|
public boolean forceRecycleSubServer(String name) throws InterruptedException {
|
||||||
|
return forceRecycleSubServer(null, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forces the Deletion of a SubServer (will move to 'Recently Deleted')
|
||||||
|
*
|
||||||
|
* @param player Player Deleting
|
||||||
|
* @param name SubServer Name
|
||||||
|
* @return Success Status
|
||||||
|
*/
|
||||||
|
public boolean forceRecycleSubServer(UUID player, String name) throws InterruptedException {
|
||||||
|
return recycleSubServer(player, name, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a SubServer
|
||||||
*
|
*
|
||||||
* @param name SubServer Name
|
* @param name SubServer Name
|
||||||
* @return Success Status
|
* @return Success Status
|
||||||
|
@ -323,22 +461,34 @@ public abstract class Host implements ExtraDataHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a SubServer
|
* Deletes a SubServer
|
||||||
*
|
*
|
||||||
* @param player Player Deleting
|
* @param player Player Deleting
|
||||||
* @param name SubServer Name
|
* @param name SubServer Name
|
||||||
* @return Success Status
|
* @return Success Status
|
||||||
*/
|
*/
|
||||||
public abstract boolean deleteSubServer(UUID player, String name) throws InterruptedException;
|
public boolean deleteSubServer(UUID player, String name) throws InterruptedException {
|
||||||
|
return deleteSubServer(player, name, false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forced the Deletion of a SubServer
|
* Deletes a SubServer
|
||||||
|
*
|
||||||
|
* @param player Player Deleting
|
||||||
|
* @param name SubServer Name
|
||||||
|
* @param forced Forces the Deletion
|
||||||
|
* @return Success Status
|
||||||
|
*/
|
||||||
|
protected abstract boolean deleteSubServer(UUID player, String name, boolean forced) throws InterruptedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forces the Deletion of a SubServer
|
||||||
*
|
*
|
||||||
* @param name SubServer Name
|
* @param name SubServer Name
|
||||||
* @return Success Status
|
* @return Success Status
|
||||||
*/
|
*/
|
||||||
public boolean forceDeleteSubServer(String name) throws InterruptedException {
|
public boolean forceDeleteSubServer(String name) throws InterruptedException {
|
||||||
return deleteSubServer(null, name);
|
return forceDeleteSubServer(null, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -348,7 +498,32 @@ public abstract class Host implements ExtraDataHandler {
|
||||||
* @param name SubServer Name
|
* @param name SubServer Name
|
||||||
* @return Success Status
|
* @return Success Status
|
||||||
*/
|
*/
|
||||||
public abstract boolean forceDeleteSubServer(UUID player, String name) throws InterruptedException;
|
public boolean forceDeleteSubServer(UUID player, String name) throws InterruptedException {
|
||||||
|
return deleteSubServer(player, name, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets this Host object
|
||||||
|
*
|
||||||
|
* @return Success Status
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public boolean destroy() {
|
||||||
|
try {
|
||||||
|
Map.Entry<String, SubServer>[] subservers = getSubServers().entrySet().toArray(new Map.Entry[0]);
|
||||||
|
|
||||||
|
for (Map.Entry<String, SubServer> entry : subservers) {
|
||||||
|
if (entry.getValue().isRunning()) Logger.get("SubServers").info("Stopping " + entry.getValue().getName());
|
||||||
|
forceRemoveSubServer(entry.getKey());
|
||||||
|
}
|
||||||
|
getCreator().terminate();
|
||||||
|
getCreator().waitFor();
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the Signature of this Object
|
* Get the Signature of this Object
|
||||||
|
@ -359,39 +534,42 @@ public abstract class Host implements ExtraDataHandler {
|
||||||
return signature;
|
return signature;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return obj instanceof Host && signature.equals(((Host) obj).signature);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addExtra(String handle, Object value) {
|
public void addExtra(String handle, Object value) {
|
||||||
if (Util.isNull(handle, value)) throw new NullPointerException();
|
Util.nullpo(handle, value);
|
||||||
extra.set(handle, value);
|
extra.set(handle, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasExtra(String handle) {
|
public boolean hasExtra(String handle) {
|
||||||
if (Util.isNull(handle)) throw new NullPointerException();
|
Util.nullpo(handle);
|
||||||
return extra.getKeys().contains(handle);
|
return extra.getKeys().contains(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public YAMLValue getExtra(String handle) {
|
public ObjectMapValue getExtra(String handle) {
|
||||||
if (Util.isNull(handle)) throw new NullPointerException();
|
Util.nullpo(handle);
|
||||||
return extra.get(handle);
|
return extra.get(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public YAMLSection getExtra() {
|
public ObjectMap<String> getExtra() {
|
||||||
return extra.clone();
|
return extra.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeExtra(String handle) {
|
public void removeExtra(String handle) {
|
||||||
if (Util.isNull(handle)) throw new NullPointerException();
|
Util.nullpo(handle);
|
||||||
extra.remove(handle);
|
extra.remove(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public ObjectMap<String> forSubData() {
|
||||||
@SuppressWarnings("unchecked")
|
ObjectMap<String> hinfo = new ObjectMap<String>();
|
||||||
public String toString() {
|
|
||||||
YAMLSection hinfo = new YAMLSection();
|
|
||||||
hinfo.set("type", "Host");
|
hinfo.set("type", "Host");
|
||||||
hinfo.set("name", getName());
|
hinfo.set("name", getName());
|
||||||
hinfo.set("display", getDisplayName());
|
hinfo.set("display", getDisplayName());
|
||||||
|
@ -400,21 +578,20 @@ public abstract class Host implements ExtraDataHandler {
|
||||||
hinfo.set("address", getAddress().getHostAddress());
|
hinfo.set("address", getAddress().getHostAddress());
|
||||||
hinfo.set("dir", getPath());
|
hinfo.set("dir", getPath());
|
||||||
|
|
||||||
YAMLSection cinfo = new YAMLSection();
|
ObjectMap<String> cinfo = new ObjectMap<String>();
|
||||||
YAMLSection templates = new YAMLSection();
|
ObjectMap<String> templates = new ObjectMap<String>();
|
||||||
for (SubCreator.ServerTemplate template : getCreator().getTemplates().values())
|
for (SubCreator.ServerTemplate template : getCreator().getTemplates().values())
|
||||||
templates.set(template.getName(), new YAMLSection(new Gson().fromJson(template.toString(), Map.class)));
|
templates.set(template.getName(), template.forSubData());
|
||||||
cinfo.set("templates", templates);
|
cinfo.set("templates", templates);
|
||||||
hinfo.set("creator", cinfo);
|
hinfo.set("creator", cinfo);
|
||||||
|
|
||||||
YAMLSection servers = new YAMLSection();
|
ObjectMap<String> servers = new ObjectMap<String>();
|
||||||
for (SubServer server : getSubServers().values()) {
|
for (SubServer server : getSubServers().values()) {
|
||||||
servers.set(server.getName(), new YAMLSection(new Gson().fromJson(server.toString(), Map.class)));
|
servers.set(server.getName(), server.forSubData());
|
||||||
}
|
}
|
||||||
hinfo.set("servers", servers);
|
hinfo.set("servers", servers);
|
||||||
if (this instanceof ClientHandler && ((ClientHandler) this).getSubData() != null) hinfo.set("subdata", ((ClientHandler) this).getSubData().getAddress().toString());
|
|
||||||
hinfo.set("signature", signature);
|
hinfo.set("signature", signature);
|
||||||
hinfo.set("extra", getExtra());
|
hinfo.set("extra", getExtra());
|
||||||
return hinfo.toJSON();
|
return hinfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,21 @@
|
||||||
package net.ME1312.SubServers.Bungee.Host.Internal;
|
package net.ME1312.SubServers.Bungee.Host.Internal;
|
||||||
|
|
||||||
import com.dosse.upnp.UPnP;
|
import net.ME1312.Galaxi.Library.Config.YAMLSection;
|
||||||
import com.google.common.collect.Range;
|
import net.ME1312.Galaxi.Library.Directories;
|
||||||
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
import net.ME1312.SubServers.Bungee.Event.SubAddServerEvent;
|
import net.ME1312.SubServers.Bungee.Event.SubAddServerEvent;
|
||||||
import net.ME1312.SubServers.Bungee.Event.SubRemoveServerEvent;
|
import net.ME1312.SubServers.Bungee.Event.SubRemoveServerEvent;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
|
||||||
import net.ME1312.SubServers.Bungee.Host.Host;
|
import net.ME1312.SubServers.Bungee.Host.Host;
|
||||||
import net.ME1312.SubServers.Bungee.Host.SubCreator;
|
import net.ME1312.SubServers.Bungee.Host.SubCreator;
|
||||||
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
||||||
import net.ME1312.SubServers.Bungee.Library.UniversalFile;
|
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
||||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||||
|
|
||||||
|
import com.dosse.upnp.UPnP;
|
||||||
|
import com.google.common.collect.Range;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
|
@ -29,7 +33,7 @@ public class InternalHost extends Host {
|
||||||
private InetAddress address;
|
private InetAddress address;
|
||||||
private SubCreator creator;
|
private SubCreator creator;
|
||||||
private String directory;
|
private String directory;
|
||||||
protected SubPlugin plugin;
|
SubProxy plugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an Internal Host
|
* Creates an Internal Host
|
||||||
|
@ -43,7 +47,7 @@ public class InternalHost extends Host {
|
||||||
* @param directory The runtime directory of your Host
|
* @param directory The runtime directory of your Host
|
||||||
* @param gitBash The Git Bash directory
|
* @param gitBash The Git Bash directory
|
||||||
*/
|
*/
|
||||||
public InternalHost(SubPlugin plugin, String name, boolean enabled, Range<Integer> ports, boolean log, InetAddress address, String directory, String gitBash) {
|
public InternalHost(SubProxy plugin, String name, boolean enabled, Range<Integer> ports, boolean log, InetAddress address, String directory, String gitBash) {
|
||||||
super(plugin, name, enabled, ports, log, address, directory, gitBash);
|
super(plugin, name, enabled, ports, log, address, directory, gitBash);
|
||||||
if (!DRM_ALLOW) throw new IllegalStateException("SubServers' hosting capabilities have been disabled by your provider");
|
if (!DRM_ALLOW) throw new IllegalStateException("SubServers' hosting capabilities have been disabled by your provider");
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
|
@ -91,144 +95,156 @@ public class InternalHost extends Host {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SubServer getSubServer(String name) {
|
public SubServer getSubServer(String name) {
|
||||||
if (Util.isNull(name)) throw new NullPointerException();
|
if (Util.isNull(name)) return null;
|
||||||
return getSubServers().get(name.toLowerCase());
|
return servers.get(name.toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SubServer addSubServer(UUID player, String name, boolean enabled, int port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
public SubServer constructSubServer(String name, boolean enabled, int port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||||
if (plugin.api.getServers().keySet().contains(name.toLowerCase())) throw new InvalidServerException("A Server already exists with this name!");
|
return InternalSubServer.construct(this, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||||
SubServer server = new InternalSubServer(this, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean addSubServer(UUID player, SubServer server) throws InvalidServerException {
|
||||||
|
if (server.getHost() != this) throw new IllegalArgumentException("That Server does not belong to this Host!");
|
||||||
|
if (plugin.api.getServers().containsKey(server.getName().toLowerCase())) throw new InvalidServerException("A Server already exists with this name!");
|
||||||
SubAddServerEvent event = new SubAddServerEvent(player, this, server);
|
SubAddServerEvent event = new SubAddServerEvent(player, this, server);
|
||||||
plugin.getPluginManager().callEvent(event);
|
plugin.getPluginManager().callEvent(event);
|
||||||
if (!event.isCancelled()) {
|
if (!event.isCancelled()) {
|
||||||
servers.put(name.toLowerCase(), server);
|
((InternalSubServer) server).registered(true);
|
||||||
if (UPnP.isUPnPAvailable() && plugin.config.get().getSection("Settings").getSection("UPnP", new YAMLSection()).getBoolean("Forward-Servers", false)) UPnP.openPortTCP(port);
|
servers.put(server.getName().toLowerCase(), server);
|
||||||
return server;
|
if (UPnP.isUPnPAvailable() && plugin.config.get().getMap("Settings").getMap("UPnP", new ObjectMap<String>()).getBoolean("Forward-Servers", false)) UPnP.openPortTCP(server.getAddress().getPort());
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean removeSubServer(UUID player, String name) throws InterruptedException {
|
protected boolean removeSubServer(UUID player, String name, boolean forced) throws InterruptedException {
|
||||||
if (Util.isNull(name)) throw new NullPointerException();
|
Util.nullpo(name);
|
||||||
String server = servers.get(name.toLowerCase()).getName();
|
InternalSubServer server = (InternalSubServer) servers.get(name.toLowerCase());
|
||||||
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, getSubServer(server));
|
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, server);
|
||||||
plugin.getPluginManager().callEvent(event);
|
plugin.getPluginManager().callEvent(event);
|
||||||
if (!event.isCancelled()) {
|
if (forced || !event.isCancelled()) {
|
||||||
if (getSubServer(server).isRunning()) {
|
server.registered(false);
|
||||||
getSubServer(server).stop();
|
if (server.isRunning()) {
|
||||||
getSubServer(server).waitFor();
|
server.stop();
|
||||||
|
server.waitFor();
|
||||||
}
|
}
|
||||||
if (UPnP.isUPnPAvailable() && UPnP.isMappedTCP(getSubServer(server).getAddress().getPort()))
|
servers.remove(name.toLowerCase());
|
||||||
UPnP.closePortTCP(getSubServer(server).getAddress().getPort());
|
if (UPnP.isUPnPAvailable() && UPnP.isMappedTCP(server.getAddress().getPort()))
|
||||||
servers.remove(server.toLowerCase());
|
UPnP.closePortTCP(server.getAddress().getPort());
|
||||||
return true;
|
return true;
|
||||||
} else return false;
|
} else return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean forceRemoveSubServer(UUID player, String name) {
|
protected boolean recycleSubServer(UUID player, String name, boolean forced) throws InterruptedException {
|
||||||
if (Util.isNull(name)) throw new NullPointerException();
|
return recycleSubServer(player, name, forced, true);
|
||||||
String server = servers.get(name.toLowerCase()).getName();
|
|
||||||
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, getSubServer(server));
|
|
||||||
plugin.getPluginManager().callEvent(event);
|
|
||||||
if (getSubServer(server).isRunning()) {
|
|
||||||
getSubServer(server).terminate();
|
|
||||||
}
|
|
||||||
if (UPnP.isUPnPAvailable() && UPnP.isMappedTCP(getSubServer(server).getAddress().getPort()))
|
|
||||||
UPnP.closePortTCP(getSubServer(server).getAddress().getPort());
|
|
||||||
servers.remove(server.toLowerCase());
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public boolean deleteSubServer(UUID player, String name) throws InterruptedException {
|
* Deletes a SubServer (will move to 'Recently Deleted')
|
||||||
if (Util.isNull(name)) throw new NullPointerException();
|
*
|
||||||
|
* @param player Player Deleting
|
||||||
|
* @param name SubServer Name
|
||||||
|
* @param forced Forces the Deletion
|
||||||
|
* @param multithreading Uses Multithreading for I/O
|
||||||
|
* @return Success Status
|
||||||
|
*/
|
||||||
|
protected boolean recycleSubServer(UUID player, String name, boolean forced, boolean multithreading) throws InterruptedException {
|
||||||
|
Util.nullpo(name);
|
||||||
String server = servers.get(name.toLowerCase()).getName();
|
String server = servers.get(name.toLowerCase()).getName();
|
||||||
File from = new File(getPath(), servers.get(server.toLowerCase()).getPath());
|
File from = new File(getPath(), servers.get(server.toLowerCase()).getPath());
|
||||||
if (removeSubServer(player, server)) {
|
if (removeSubServer(player, server, forced)) {
|
||||||
new Thread(() -> {
|
Runnable method = () -> {
|
||||||
UniversalFile to = new UniversalFile(plugin.dir, "SubServers:Recently Deleted:" + server.toLowerCase());
|
File to = new File(plugin.dir, "SubServers/Recently Deleted/" + server.toLowerCase());
|
||||||
try {
|
try {
|
||||||
if (from.exists()) {
|
if (from.exists()) {
|
||||||
System.out.println("SubServers > Removing Files...");
|
Logger.get("SubServers").info("Moving Files...");
|
||||||
if (to.exists()) {
|
if (to.exists()) {
|
||||||
if (to.isDirectory()) Util.deleteDirectory(to);
|
if (to.isDirectory()) Directories.delete(to);
|
||||||
else to.delete();
|
else to.delete();
|
||||||
}
|
}
|
||||||
to.mkdirs();
|
to.mkdirs();
|
||||||
Util.copyDirectory(from, to);
|
Directories.copy(from, to);
|
||||||
Util.deleteDirectory(from);
|
Directories.delete(from);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("SubServers > Saving...");
|
Logger.get("SubServers").info("Saving...");
|
||||||
YAMLSection info = (plugin.config.get().getSection("Servers").getKeys().contains(server))?plugin.config.get().getSection("Servers").getSection(server).clone():new YAMLSection();
|
YAMLSection info = (plugin.servers.get().getMap("Servers").getKeys().contains(server))?new YAMLSection(plugin.servers.get().getMap("Servers").getMap(server).get()):new YAMLSection();
|
||||||
info.set("Name", server);
|
info.set("Name", server);
|
||||||
info.set("Timestamp", Calendar.getInstance().getTime().getTime());
|
info.set("Timestamp", Calendar.getInstance().getTime().getTime());
|
||||||
try {
|
try {
|
||||||
if (plugin.config.get().getSection("Servers").getKeys().contains(server)) {
|
if (plugin.servers.get().getMap("Servers").getKeys().contains(server)) {
|
||||||
plugin.config.get().getSection("Servers").remove(server);
|
plugin.servers.get().getMap("Servers").remove(server);
|
||||||
plugin.config.save();
|
plugin.servers.save();
|
||||||
}
|
|
||||||
if (!to.exists()) to.mkdirs();
|
|
||||||
FileWriter writer = new FileWriter(new File(to, "info.json"));
|
|
||||||
writer.write(info.toJSON());
|
|
||||||
writer.close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
System.out.println("SubServers > Deleted SubServer: " + server);
|
|
||||||
}, "SubServers.Bungee::Internal_Server_Deletion(" + name + ')').start();
|
|
||||||
return true;
|
|
||||||
} else return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean forceDeleteSubServer(UUID player, String name) throws InterruptedException {
|
|
||||||
if (Util.isNull(name)) throw new NullPointerException();
|
|
||||||
String server = servers.get(name.toLowerCase()).getName();
|
|
||||||
File from = new File(getPath(), servers.get(server.toLowerCase()).getPath());
|
|
||||||
if (forceRemoveSubServer(player, server)) {
|
|
||||||
new Thread(() -> {
|
|
||||||
UniversalFile to = new UniversalFile(plugin.dir, "SubServers:Recently Deleted:" + server.toLowerCase());
|
|
||||||
try {
|
|
||||||
if (from.exists()) {
|
|
||||||
System.out.println("SubServers > Removing Files...");
|
|
||||||
if (to.exists()) {
|
|
||||||
if (to.isDirectory()) Util.deleteDirectory(to);
|
|
||||||
else to.delete();
|
|
||||||
}
|
|
||||||
to.mkdirs();
|
|
||||||
Util.copyDirectory(from, to);
|
|
||||||
Util.deleteDirectory(from);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println("SubServers > Saving...");
|
|
||||||
YAMLSection info = (plugin.config.get().getSection("Servers").getKeys().contains(server))?plugin.config.get().getSection("Servers").getSection(server).clone():new YAMLSection();
|
|
||||||
info.set("Name", server);
|
|
||||||
info.set("Timestamp", Calendar.getInstance().getTime().getTime());
|
|
||||||
try {
|
|
||||||
if (plugin.config.get().getSection("Servers").getKeys().contains(server)) {
|
|
||||||
plugin.config.get().getSection("Servers").remove(server);
|
|
||||||
plugin.config.save();
|
|
||||||
}
|
}
|
||||||
if (!to.exists()) to.mkdirs();
|
if (!to.exists()) to.mkdirs();
|
||||||
FileWriter writer = new FileWriter(new File(to, "info.json"), false);
|
FileWriter writer = new FileWriter(new File(to, "info.json"), false);
|
||||||
writer.write(info.toJSON());
|
writer.write(new Gson().toJson(info.get()));
|
||||||
writer.close();
|
writer.close();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
System.out.println("SubServers > Deleted SubServer: " + server);
|
Logger.get("SubServers").info("Deleted SubServer: " + server);
|
||||||
}, "SubServers.Bungee::Internal_Server_Deletion(" + name + ')').start();
|
};
|
||||||
|
|
||||||
|
if (multithreading) {
|
||||||
|
new Thread(method, "SubServers.Bungee::Internal_Server_Recycler(" + name + ')').start();
|
||||||
|
} else method.run();
|
||||||
|
return true;
|
||||||
|
} else return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean deleteSubServer(UUID player, String name, boolean forced) throws InterruptedException {
|
||||||
|
return deleteSubServer(player, name, forced, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a SubServer
|
||||||
|
*
|
||||||
|
* @param player Player Deleting
|
||||||
|
* @param name SubServer Name
|
||||||
|
* @param forced Forces the Deletion
|
||||||
|
* @param multithreading Uses Multithreading for I/O
|
||||||
|
* @return Success Status
|
||||||
|
*/
|
||||||
|
protected boolean deleteSubServer(UUID player, String name, boolean forced, boolean multithreading) throws InterruptedException {
|
||||||
|
Util.nullpo(name);
|
||||||
|
String server = servers.get(name.toLowerCase()).getName();
|
||||||
|
File from = new File(getPath(), servers.get(server.toLowerCase()).getPath());
|
||||||
|
if (removeSubServer(player, server, forced)) {
|
||||||
|
Runnable method = () -> {
|
||||||
|
try {
|
||||||
|
if (from.exists()) {
|
||||||
|
Logger.get("SubServers").info("Removing Files...");
|
||||||
|
Directories.delete(from);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.get("SubServers").info("Saving...");
|
||||||
|
try {
|
||||||
|
if (plugin.servers.get().getMap("Servers").getKeys().contains(server)) {
|
||||||
|
plugin.servers.get().getMap("Servers").remove(server);
|
||||||
|
plugin.servers.save();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
Logger.get("SubServers").info("Deleted SubServer: " + server);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (multithreading) {
|
||||||
|
new Thread(method, "SubServers.Bungee::Internal_Server_Deletion(" + name + ')').start();
|
||||||
|
} else method.run();
|
||||||
return true;
|
return true;
|
||||||
} else return false;
|
} else return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,31 +1,48 @@
|
||||||
package net.ME1312.SubServers.Bungee.Host.Internal;
|
package net.ME1312.SubServers.Bungee.Host.Internal;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Config.YAMLConfig;
|
||||||
|
import net.ME1312.Galaxi.Library.Config.YAMLSection;
|
||||||
|
import net.ME1312.Galaxi.Library.Container.ContainedPair;
|
||||||
|
import net.ME1312.Galaxi.Library.Container.Container;
|
||||||
|
import net.ME1312.Galaxi.Library.Container.Pair;
|
||||||
|
import net.ME1312.Galaxi.Library.Container.Value;
|
||||||
|
import net.ME1312.Galaxi.Library.Directories;
|
||||||
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
|
import net.ME1312.Galaxi.Library.Map.ObjectMapValue;
|
||||||
|
import net.ME1312.Galaxi.Library.Try;
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
|
import net.ME1312.Galaxi.Library.Version.Version;
|
||||||
|
import net.ME1312.SubServers.Bungee.Event.SubCreateEvent;
|
||||||
|
import net.ME1312.SubServers.Bungee.Event.SubCreatedEvent;
|
||||||
|
import net.ME1312.SubServers.Bungee.Host.*;
|
||||||
|
import net.ME1312.SubServers.Bungee.Host.SubServer.StopAction;
|
||||||
|
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
|
||||||
|
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
||||||
|
import net.ME1312.SubServers.Bungee.Library.Exception.SubCreatorException;
|
||||||
|
import net.ME1312.SubServers.Bungee.Library.ReplacementScanner;
|
||||||
|
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||||
|
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||||
|
|
||||||
import com.google.common.collect.Range;
|
import com.google.common.collect.Range;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import net.ME1312.SubServers.Bungee.Event.SubCreateEvent;
|
import net.md_5.bungee.api.ChatColor;
|
||||||
import net.ME1312.SubServers.Bungee.Host.*;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.*;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLConfig;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Exception.SubCreatorException;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
|
||||||
import net.ME1312.SubServers.Bungee.SubAPI;
|
|
||||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
|
||||||
import org.w3c.dom.Document;
|
|
||||||
import org.w3c.dom.Node;
|
|
||||||
import org.w3c.dom.NodeList;
|
|
||||||
import org.xml.sax.InputSource;
|
|
||||||
|
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.LinkOption;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
|
import java.security.MessageDigest;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import static java.util.logging.Level.INFO;
|
||||||
|
import static java.util.logging.Level.WARNING;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal SubCreator Class
|
* Internal SubCreator Class
|
||||||
*/
|
*/
|
||||||
|
@ -34,89 +51,139 @@ public class InternalSubCreator extends SubCreator {
|
||||||
private HashMap<String, ServerTemplate> templates = new HashMap<String, ServerTemplate>();
|
private HashMap<String, ServerTemplate> templates = new HashMap<String, ServerTemplate>();
|
||||||
private InternalHost host;
|
private InternalHost host;
|
||||||
private Range<Integer> ports;
|
private Range<Integer> ports;
|
||||||
private Container<Boolean> log;
|
private Value<Boolean> log;
|
||||||
private String gitBash;
|
private String gitBash;
|
||||||
private TreeMap<String, CreatorTask> thread;
|
private TreeMap<String, CreatorTask> thread;
|
||||||
|
|
||||||
private class CreatorTask extends Thread {
|
private class CreatorTask extends Thread {
|
||||||
private final UUID player;
|
private final UUID player;
|
||||||
|
private final SubServer update;
|
||||||
private final String name;
|
private final String name;
|
||||||
private final ServerTemplate template;
|
private final ServerTemplate template;
|
||||||
private final Version version;
|
private final Version version;
|
||||||
private final int port;
|
private final int port;
|
||||||
|
private final String prefix;
|
||||||
private final InternalSubLogger log;
|
private final InternalSubLogger log;
|
||||||
private final Callback<SubServer> callback;
|
private final LinkedList<String> replace;
|
||||||
|
private final HashMap<String, String> replacements;
|
||||||
|
private final Consumer<SubServer> callback;
|
||||||
|
private boolean install;
|
||||||
private Process process;
|
private Process process;
|
||||||
|
|
||||||
private CreatorTask(UUID player, String name, ServerTemplate template, Version version, int port, Callback<SubServer> callback) {
|
private CreatorTask(UUID player, String name, ServerTemplate template, Version version, int port, Consumer<SubServer> callback) {
|
||||||
super("SubServers.Bungee::Internal_SubCreator_Process_Handler(" + name + ')');
|
super("SubServers.Bungee::Internal_SubCreator_Process_Handler(" + name + ')');
|
||||||
this.player = player;
|
this.player = player;
|
||||||
|
this.update = null;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.template = template;
|
this.template = template;
|
||||||
this.version = version;
|
this.version = version;
|
||||||
this.port = port;
|
this.port = port;
|
||||||
this.log = new InternalSubLogger(null, this, name + File.separator + "Creator", InternalSubCreator.this.log, null);
|
this.log = new InternalSubLogger(null, this, prefix = name + File.separator + "Creator", InternalSubCreator.this.log, null);
|
||||||
|
(this.replace = new LinkedList<String>()).add("/server.properties");
|
||||||
|
this.replacements = new HashMap<String, String>();
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
|
this.install = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private YAMLSection build(File dir, ServerTemplate template, List<ServerTemplate> history) throws SubCreatorException {
|
private CreatorTask(UUID player, SubServer server, ServerTemplate template, Version version, Consumer<SubServer> callback) {
|
||||||
YAMLSection server = new YAMLSection();
|
super("SubServers.Bungee::Internal_SubCreator_Process_Handler(" + server.getName() + ')');
|
||||||
|
this.player = player;
|
||||||
|
this.update = server;
|
||||||
|
this.name = server.getName();
|
||||||
|
this.template = template;
|
||||||
|
this.version = version;
|
||||||
|
this.port = server.getAddress().getPort();
|
||||||
|
this.log = new InternalSubLogger(null, this, prefix = name + File.separator + "Updater", InternalSubCreator.this.log, null);
|
||||||
|
(this.replace = new LinkedList<String>()).add("/server.properties");
|
||||||
|
this.replacements = new HashMap<String, String>();
|
||||||
|
this.callback = callback;
|
||||||
|
this.install = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ObjectMap<String> build(File dir, ServerTemplate template, List<ServerTemplate> history, List<ServerTemplate> stack) throws SubCreatorException {
|
||||||
|
ObjectMap<String> server = new ObjectMap<String>();
|
||||||
Version version = this.version;
|
Version version = this.version;
|
||||||
HashMap<String, String> var = new HashMap<String, String>();
|
HashMap<String, String> var = new HashMap<String, String>();
|
||||||
boolean error = false;
|
boolean error = false;
|
||||||
if (history.contains(template)) throw new IllegalStateException("Template Import loop detected");
|
if (stack.contains(template)) throw new IllegalStateException("Infinite template import loop detected");
|
||||||
history.add(template);
|
stack.add(template);
|
||||||
for (String other : template.getBuildOptions().getStringList("Import", new ArrayList<String>())) {
|
for (String other : template.getBuildOptions().getStringList("Import", new ArrayList<String>())) {
|
||||||
if (templates.keySet().contains(other.toLowerCase())) {
|
if (templates.containsKey(other.toLowerCase())) {
|
||||||
if (templates.get(other.toLowerCase()).isEnabled()) {
|
final ServerTemplate ot = templates.get(other.toLowerCase());
|
||||||
YAMLSection config = build(dir, templates.get(other.toLowerCase()), history);
|
if (ot.isEnabled()) {
|
||||||
if (config == null) {
|
if (version != null || !ot.requiresVersion()) {
|
||||||
throw new SubCreatorException();
|
if (update == null || ot.canUpdate()) {
|
||||||
|
if (!history.contains(ot)) {
|
||||||
|
server.setAll(this.build(dir, ot, history, stack));
|
||||||
|
} else {
|
||||||
|
log.log(WARNING, "Skipping template that is already loaded: " + other);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.log(WARNING, "Skipping template that cannot be run in update mode: " + other);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
server.setAll(config);
|
log.log(WARNING, "Skipping template that requires extra versioning information: " + other);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
System.out.println(name + File.separator + "Creator > Skipping disabled template: " + other);
|
log.log(WARNING, "Skipping disabled template: " + other);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
System.out.println(name + File.separator + "Creator > Skipping missing template: " + other);
|
log.log(WARNING, "Skipping missing template: " + other);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
history.add(template);
|
||||||
|
stack.remove(template);
|
||||||
server.setAll(template.getConfigOptions());
|
server.setAll(template.getConfigOptions());
|
||||||
try {
|
try {
|
||||||
System.out.println(name + File.separator + "Creator > Loading Template: " + template.getDisplayName());
|
log.log(INFO, "Loading" + ((template.isDynamic())?" Dynamic":"") + " Template: " + template.getDisplayName());
|
||||||
Util.copyDirectory(template.getDirectory(), dir);
|
updateDirectory(template.getDirectory(), dir, template.getBuildOptions().getBoolean("Update-Files", false));
|
||||||
|
|
||||||
|
install = template.getBuildOptions().getBoolean("Install-Client", install);
|
||||||
|
replace.addAll(template.getBuildOptions().getStringList("Replace", Collections.emptyList()));
|
||||||
|
for (ObjectMapValue<String> replacement : template.getBuildOptions().getMap("Replacements", new ObjectMap<>()).getValues()) if (!replacement.isNull()) {
|
||||||
|
replacements.put(replacement.getHandle().toLowerCase().replace('-', '_').replace(' ', '_'), replacement.asString());
|
||||||
|
}
|
||||||
|
|
||||||
|
var.putAll(replacements);
|
||||||
|
var.put("java", System.getProperty("java.home") + File.separator + "bin" + File.separator + "java");
|
||||||
|
var.put("mode", (update == null)? "CREATE" : ((CreatorTask.this.template.equals(update.getTemplate()))?"UPDATE":"SWITCH"));
|
||||||
|
if (player != null) var.put("player", player.toString().toUpperCase());
|
||||||
|
else var.remove("player");
|
||||||
var.put("name", name);
|
var.put("name", name);
|
||||||
|
var.put("host", host.getName());
|
||||||
var.put("template", template.getName());
|
var.put("template", template.getName());
|
||||||
var.put("type", template.getType().toString().toUpperCase());
|
var.put("type", template.getType().toString().toUpperCase());
|
||||||
var.put("version", version.toString());
|
if (version != null) var.put("version", version.toString());
|
||||||
|
else var.remove("version");
|
||||||
var.put("address", host.getAddress().getHostAddress());
|
var.put("address", host.getAddress().getHostAddress());
|
||||||
var.put("port", Integer.toString(port));
|
var.put("port", Integer.toString(port));
|
||||||
switch (template.getType()) {
|
switch (template.getType()) {
|
||||||
case SPONGE:
|
case SPONGE:
|
||||||
case FORGE:
|
case FORGE:
|
||||||
System.out.println(name + File.separator + "Creator > Searching Versions...");
|
if (version != null) {
|
||||||
YAMLSection spversionmanifest = new YAMLSection(new Gson().fromJson("{\"versions\":" + Util.readAll(new BufferedReader(new InputStreamReader(new URL("https://dl-api.spongepowered.org/v1/org.spongepowered/sponge" + ((template.getType() == ServerType.FORGE)?"forge":"vanilla") + "/downloads?type=stable&minecraft=" + version).openStream(), Charset.forName("UTF-8")))) + '}', Map.class));
|
log.log(INFO, "Searching Versions...");
|
||||||
|
ObjectMap<String> spversionmanifest = new ObjectMap<String>(new Gson().fromJson("{\"versions\":" + Util.readAll(new BufferedReader(new InputStreamReader(new URL("https://dl-api.spongepowered.org/v1/org.spongepowered/sponge" + ((template.getType() == ServerType.FORGE)?"forge":"vanilla") + "/downloads?type=stable&minecraft=" + version).openStream(), Charset.forName("UTF-8")))) + '}', Map.class));
|
||||||
|
|
||||||
YAMLSection spprofile = null;
|
ObjectMap<String> spprofile = null;
|
||||||
Version spversion = null;
|
Version spversion = null;
|
||||||
for (YAMLSection profile : spversionmanifest.getSectionList("versions")) {
|
for (ObjectMap<String> profile : spversionmanifest.getMapList("versions")) {
|
||||||
if (profile.getSection("dependencies").getRawString("minecraft").equalsIgnoreCase(version.toString()) && (spversion == null || new Version(profile.getRawString("version")).compareTo(spversion) >= 0)) {
|
if (profile.getMap("dependencies").getString("minecraft").equalsIgnoreCase(version.toString()) && (spversion == null || new Version(profile.getString("version")).compareTo(spversion) >= 0)) {
|
||||||
spprofile = profile;
|
spprofile = profile;
|
||||||
spversion = new Version(profile.getRawString("version"));
|
spversion = new Version(profile.getString("version"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if (spversion == null)
|
||||||
if (spversion == null)
|
throw new InvalidServerException("Cannot find Sponge version for Minecraft " + version.toString());
|
||||||
throw new InvalidServerException("Cannot find Sponge version for Minecraft " + version.toString());
|
log.log(INFO, "Found \"sponge" + ((template.getType() == ServerType.FORGE)?"forge":"vanilla") + "-" + spversion.toString() + '"');
|
||||||
System.out.println(name + File.separator + "Creator > Found \"sponge" + ((template.getType() == ServerType.FORGE)?"forge":"vanilla") + "-" + spversion.toString() + '"');
|
|
||||||
|
|
||||||
if (template.getType() == ServerType.FORGE) {
|
if (template.getType() == ServerType.FORGE) {
|
||||||
Version mcfversion = new Version(spprofile.getSection("dependencies").getRawString("minecraft") + '-' + spprofile.getSection("dependencies").getRawString("forge"));
|
Version mcfversion = new Version(((spprofile.getMap("dependencies").getString("forge").contains("-"))?"":spprofile.getMap("dependencies").getString("minecraft") + '-') + spprofile.getMap("dependencies").getString("forge"));
|
||||||
System.out.println(name + File.separator + "Creator > Found \"forge-" + mcfversion.toString() + '"');
|
log.log(INFO, "Found \"forge-" + mcfversion.toString() + '"');
|
||||||
|
|
||||||
var.put("mcf_version", mcfversion.toString());
|
var.put("mcf_version", mcfversion.toString());
|
||||||
|
}
|
||||||
|
var.put("sp_version", spversion.toString());
|
||||||
}
|
}
|
||||||
var.put("sp_version", spversion.toString());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -124,29 +191,25 @@ public class InternalSubCreator extends SubCreator {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (template.getBuildOptions().contains("Executable")) {
|
if (template.getBuildOptions().contains("Executable")) {
|
||||||
File cache;
|
File cache = null;
|
||||||
if (template.getBuildOptions().getBoolean("Use-Cache", true)) {
|
if (template.getBuildOptions().getBoolean("Use-Cache", true)) {
|
||||||
cache = new UniversalFile(host.plugin.dir, "SubServers:Cache:Templates:" + template.getName());
|
cache = new File(host.plugin.dir, "SubServers/Cache/Templates/" + template.getName());
|
||||||
cache.mkdirs();
|
cache.mkdirs();
|
||||||
String c = cache.toString();
|
var.put("cache", cache.getAbsolutePath());
|
||||||
if (System.getProperty("os.name").toLowerCase().startsWith("windows") &&
|
|
||||||
(template.getBuildOptions().getRawString("Executable").toLowerCase().startsWith("bash ") || template.getBuildOptions().getRawString("Executable").toLowerCase().startsWith("sh "))) c = c.replace(File.separatorChar, '/');
|
|
||||||
var.put("cache", c);
|
|
||||||
} else {
|
|
||||||
cache = null;
|
|
||||||
}
|
}
|
||||||
|
var.put("source", dir.getAbsolutePath());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
System.out.println(name + File.separator + "Creator > Launching Build Script...");
|
log.log(INFO, "Launching Build Script...");
|
||||||
ProcessBuilder pb = new ProcessBuilder().command(Executable.parse(gitBash, template.getBuildOptions().getRawString("Executable"))).directory(dir);
|
ProcessBuilder pb = new ProcessBuilder().command(Executable.parse(gitBash, template.getBuildOptions().getString("Executable"))).directory(dir);
|
||||||
pb.environment().putAll(var);
|
pb.environment().putAll(var);
|
||||||
|
log.file = new File(dir, "SubCreator-" + template.getName() + ((version != null)?"-"+version.toString():"") + ".log");
|
||||||
process = pb.start();
|
process = pb.start();
|
||||||
log.file = new File(dir, "SubCreator-" + template.getName() + "-" + version.toString() + ".log");
|
|
||||||
log.process = process;
|
log.process = process;
|
||||||
log.start();
|
log.start();
|
||||||
|
|
||||||
process.waitFor();
|
process.waitFor();
|
||||||
Thread.sleep(500);
|
Thread.sleep(250);
|
||||||
|
|
||||||
if (process.exitValue() != 0) error = true;
|
if (process.exitValue() != 0) error = true;
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
@ -158,105 +221,132 @@ public class InternalSubCreator extends SubCreator {
|
||||||
|
|
||||||
if (cache != null) {
|
if (cache != null) {
|
||||||
if (cache.isDirectory() && cache.listFiles().length == 0) cache.delete();
|
if (cache.isDirectory() && cache.listFiles().length == 0) cache.delete();
|
||||||
cache = new UniversalFile(host.plugin.dir, "SubServers:Cache:Templates");
|
cache = new File(host.plugin.dir, "SubServers/Cache/Templates");
|
||||||
if (cache.isDirectory() && cache.listFiles().length == 0) cache.delete();
|
if (cache.isDirectory() && cache.listFiles().length == 0) cache.delete();
|
||||||
cache = new UniversalFile(host.plugin.dir, "SubServers:Cache");
|
cache = new File(host.plugin.dir, "SubServers/Cache");
|
||||||
if (cache.isDirectory() && cache.listFiles().length == 0) cache.delete();
|
if (cache.isDirectory() && cache.listFiles().length == 0) cache.delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
new UniversalFile(dir, "template.yml").delete();
|
new File(dir, "template.yml").delete();
|
||||||
if (error) throw new SubCreatorException();
|
if (error) throw new SubCreatorException();
|
||||||
return server;
|
return server;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
UniversalFile dir = new UniversalFile(new File(host.getPath()), name);
|
Runnable declaration = () -> {
|
||||||
dir.mkdirs();
|
replacements.put("player", (player == null)?"":player.toString());
|
||||||
YAMLSection server = new YAMLSection();
|
replacements.put("name", name);
|
||||||
YAMLSection config;
|
replacements.put("host", host.getName());
|
||||||
|
replacements.put("template", template.getName());
|
||||||
|
replacements.put("type", template.getType().toString());
|
||||||
|
replacements.put("version", (version != null)?version.toString():"");
|
||||||
|
replacements.put("address", host.getAddress().getHostAddress());
|
||||||
|
replacements.put("port", Integer.toString(port));
|
||||||
|
};
|
||||||
|
|
||||||
|
declaration.run();
|
||||||
|
File dir = (update != null)?new File(update.getFullPath()):new File(host.getPath(),
|
||||||
|
(template.getConfigOptions().contains("Directory"))?new ReplacementScanner(replacements).replace(template.getConfigOptions().getString("Directory")).toString():name);
|
||||||
|
|
||||||
|
ObjectMap<String> server = new ObjectMap<String>();
|
||||||
|
ObjectMap<String> config;
|
||||||
try {
|
try {
|
||||||
config = build(dir, template, new LinkedList<>());
|
log.init();
|
||||||
generateProperties(dir, port);
|
config = build(dir, template, new LinkedList<>(), new LinkedList<>());
|
||||||
generateClient(dir, template.getType(), name);
|
|
||||||
} catch (SubCreatorException e) {
|
} catch (SubCreatorException e) {
|
||||||
config = null;
|
config = null;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
config = null;
|
config = null;
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
log.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
declaration.run();
|
||||||
|
ReplacementScanner replacements = new ReplacementScanner(this.replacements);
|
||||||
|
if (config != null) {
|
||||||
|
try {
|
||||||
|
if (install) generateClient(dir, template.getType(), name);
|
||||||
|
replacements.replace(dir, replace.toArray(new String[0]));
|
||||||
|
} catch (Exception e) {
|
||||||
|
config = null;
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config != null) {
|
if (config != null) {
|
||||||
try {
|
try {
|
||||||
System.out.println(name + File.separator + "Creator > Saving...");
|
Logger.get(prefix).info("Saving...");
|
||||||
if (host.plugin.exServers.keySet().contains(name.toLowerCase()))
|
SubServer subserver = update;
|
||||||
host.plugin.exServers.remove(name.toLowerCase());
|
if (update == null || update.getTemplate() != template || template.getBuildOptions().getBoolean("Update-Settings", false)) {
|
||||||
|
if (host.plugin.exServers.containsKey(name.toLowerCase()))
|
||||||
|
host.plugin.exServers.remove(name.toLowerCase());
|
||||||
|
|
||||||
config = new YAMLSection((Map<String, ?>) convert(config.get(), new NamedContainer<>("$player$", (player == null)?"":player.toString()), new NamedContainer<>("$name$", name),
|
config = new ObjectMap<String>((Map<String, ?>) replacements.replace(config.get()));
|
||||||
new NamedContainer<>("$template$", template.getName()), new NamedContainer<>("$type$", template.getType().toString()), new NamedContainer<>("$version$", version.toString().replace(" ", "@")),
|
if (config.contains("Directory") && (update != null || !template.getConfigOptions().contains("Directory"))) config.remove("Directory");
|
||||||
new NamedContainer<>("$address$", host.getAddress().getHostAddress()), new NamedContainer<>("$port$", Integer.toString(port))));
|
|
||||||
|
|
||||||
server.set("Enabled", true);
|
if (update == null) {
|
||||||
server.set("Display", "");
|
server.set("Enabled", true);
|
||||||
server.set("Host", host.getName());
|
server.set("Display", "");
|
||||||
server.set("Group", new ArrayList<String>());
|
server.set("Host", host.getName());
|
||||||
server.set("Port", port);
|
server.set("Template", template.getName());
|
||||||
server.set("Motd", "Some SubServer");
|
server.set("Group", new ArrayList<String>());
|
||||||
server.set("Log", true);
|
server.set("Port", port);
|
||||||
server.set("Directory", "." + File.separatorChar + name);
|
server.set("Motd", "Some SubServer");
|
||||||
server.set("Executable", "java -Xmx1024M -jar " + template.getType().toString() + ".jar");
|
server.set("Log", true);
|
||||||
server.set("Stop-Command", "stop");
|
server.set("Directory", "./" + name);
|
||||||
server.set("Stop-Action", "NONE");
|
server.set("Executable", "java -Xmx1024M -jar " + template.getType().toString() + ".jar");
|
||||||
server.set("Run-On-Launch", false);
|
server.set("Stop-Command", "stop");
|
||||||
server.set("Restricted", false);
|
server.set("Stop-Action", "NONE");
|
||||||
server.set("Incompatible", new ArrayList<String>());
|
server.set("Run-On-Launch", false);
|
||||||
server.set("Hidden", false);
|
server.set("Restricted", false);
|
||||||
server.setAll(config);
|
server.set("Incompatible", new ArrayList<String>());
|
||||||
|
server.set("Hidden", false);
|
||||||
|
} else {
|
||||||
|
server.setAll(host.plugin.servers.get().getMap("Servers").getMap(name, new HashMap<>()));
|
||||||
|
server.set("Template", template.getName());
|
||||||
|
}
|
||||||
|
server.setAll(config);
|
||||||
|
|
||||||
SubServer subserver = host.addSubServer(player, name, server.getBoolean("Enabled"), port, server.getColoredString("Motd", '&'), server.getBoolean("Log"), server.getRawString("Directory"),
|
if (update != null) Try.all.run(() -> update.getHost().forceRemoveSubServer(name));
|
||||||
server.getRawString("Executable"), server.getRawString("Stop-Command"), server.getBoolean("Hidden"), server.getBoolean("Restricted"));
|
subserver = host.constructSubServer(name, server.getBoolean("Enabled"), port, ChatColor.translateAlternateColorCodes('&', Util.unescapeJavaString(server.getString("Motd"))), server.getBoolean("Log"),
|
||||||
if (server.getString("Display").length() > 0) subserver.setDisplayName(server.getString("Display"));
|
server.getString("Directory"), server.getString("Executable"), server.getString("Stop-Command"), server.getBoolean("Hidden"), server.getBoolean("Restricted"));
|
||||||
for (String group : server.getStringList("Group")) subserver.addGroup(group);
|
|
||||||
SubServer.StopAction action = Util.getDespiteException(() -> SubServer.StopAction.valueOf(server.getRawString("Stop-Action").toUpperCase().replace('-', '_').replace(' ', '_')), null);
|
if (server.getString("Display").length() > 0) subserver.setDisplayName(Util.unescapeJavaString(server.getString("Display")));
|
||||||
if (action != null) subserver.setStopAction(action);
|
subserver.setTemplate(server.getString("Template"));
|
||||||
if (server.contains("Extra")) for (String extra : server.getSection("Extra").getKeys())
|
for (String group : server.getStringList("Group")) subserver.addGroup(group);
|
||||||
subserver.addExtra(extra, server.getSection("Extra").getObject(extra));
|
SubServer.StopAction action = Try.all.get(() -> SubServer.StopAction.valueOf(server.getString("Stop-Action").toUpperCase().replace('-', '_').replace(' ', '_')));
|
||||||
host.plugin.config.get().getSection("Servers").set(name, server);
|
if (action != null) subserver.setStopAction(action);
|
||||||
host.plugin.config.save();
|
if (server.contains("Extra")) for (String extra : server.getMap("Extra").getKeys())
|
||||||
if (template.getBuildOptions().getBoolean("Run-On-Finish", true))
|
subserver.addExtra(extra, server.getMap("Extra").getObject(extra));
|
||||||
subserver.start();
|
|
||||||
|
if ((update != null && host.plugin.servers.get().getMap("Servers").contains(name)) ||
|
||||||
|
!(subserver.getStopAction() == StopAction.REMOVE_SERVER || subserver.getStopAction() == StopAction.RECYCLE_SERVER || subserver.getStopAction() == StopAction.DELETE_SERVER)) {
|
||||||
|
host.plugin.servers.get().getMap("Servers").set(name, server);
|
||||||
|
host.plugin.servers.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
host.addSubServer(subserver);
|
||||||
|
if (update == null && template.getBuildOptions().getBoolean("Run-On-Finish", true))
|
||||||
|
subserver.start();
|
||||||
|
}
|
||||||
|
|
||||||
InternalSubCreator.this.thread.remove(name.toLowerCase());
|
InternalSubCreator.this.thread.remove(name.toLowerCase());
|
||||||
callback.run(subserver);
|
|
||||||
|
host.plugin.getPluginManager().callEvent(new SubCreatedEvent(player, host, name, template, version, port, subserver, update != null, true));
|
||||||
|
callback.accept(subserver);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
host.plugin.getPluginManager().callEvent(new SubCreatedEvent(player, host, name, template, version, port, update, update != null, false));
|
||||||
|
callback.accept(null);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
System.out.println(name + File.separator + "Creator > Couldn't build the server jar. Check the SubCreator logs for more detail.");
|
Logger.get(prefix).info("Couldn't build the server jar. Check the SubCreator logs for more detail.");
|
||||||
|
host.plugin.getPluginManager().callEvent(new SubCreatedEvent(player, host, name, template, version, port, update, update != null, false));
|
||||||
|
callback.accept(null);
|
||||||
}
|
}
|
||||||
InternalSubCreator.this.thread.remove(name.toLowerCase());
|
InternalSubCreator.this.thread.remove(name.toLowerCase());
|
||||||
} private Object convert(Object value, NamedContainer<String, String>... replacements) {
|
|
||||||
if (value instanceof Map) {
|
|
||||||
List<String> list = new ArrayList<String>();
|
|
||||||
list.addAll(((Map<String, Object>) value).keySet());
|
|
||||||
for (String key : list) ((Map<String, Object>) value).put(key, convert(((Map<String, Object>) value).get(key), replacements));
|
|
||||||
return value;
|
|
||||||
} else if (value instanceof Collection) {
|
|
||||||
List<Object> list = new ArrayList<Object>();
|
|
||||||
for (Object val : (Collection<Object>) value) list.add(convert(val, replacements));
|
|
||||||
return list;
|
|
||||||
} else if (value.getClass().isArray()) {
|
|
||||||
List<Object> list = new ArrayList<Object>();
|
|
||||||
for (int i = 0; i < ((Object[]) value).length; i++) list.add(convert(((Object[]) value)[i], replacements));
|
|
||||||
return list;
|
|
||||||
} else if (value instanceof String) {
|
|
||||||
return replace((String) value, replacements);
|
|
||||||
} else {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
} private String replace(String string, NamedContainer<String, String>... replacements) {
|
|
||||||
for (NamedContainer<String, String> replacement : replacements) string = string.replace(replacement.name(), replacement.get());
|
|
||||||
return string;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,7 +360,7 @@ public class InternalSubCreator extends SubCreator {
|
||||||
*/
|
*/
|
||||||
public InternalSubCreator(InternalHost host, Range<Integer> ports, boolean log, String gitBash) {
|
public InternalSubCreator(InternalHost host, Range<Integer> ports, boolean log, String gitBash) {
|
||||||
if (!ports.hasLowerBound() || !ports.hasUpperBound()) throw new IllegalArgumentException("Port range is not bound");
|
if (!ports.hasLowerBound() || !ports.hasUpperBound()) throw new IllegalArgumentException("Port range is not bound");
|
||||||
if (Util.isNull(host, ports, log, gitBash)) throw new NullPointerException();
|
Util.nullpo(host, ports, log, gitBash);
|
||||||
this.host = host;
|
this.host = host;
|
||||||
this.ports = ports;
|
this.ports = ports;
|
||||||
this.log = new Container<Boolean>(log);
|
this.log = new Container<Boolean>(log);
|
||||||
|
@ -283,17 +373,17 @@ public class InternalSubCreator extends SubCreator {
|
||||||
@Override
|
@Override
|
||||||
public void reload() {
|
public void reload() {
|
||||||
templates.clear();
|
templates.clear();
|
||||||
if (new UniversalFile(host.plugin.dir, "SubServers:Templates").exists())
|
if (new File(host.plugin.dir, "SubServers/Templates").exists())
|
||||||
for (File file : new UniversalFile(host.plugin.dir, "SubServers:Templates").listFiles()) {
|
for (File file : new File(host.plugin.dir, "SubServers/Templates").listFiles()) {
|
||||||
try {
|
try {
|
||||||
if (file.isDirectory() && !file.getName().endsWith(".x")) {
|
if (file.isDirectory() && !file.getName().endsWith(".x")) {
|
||||||
YAMLSection config = (new UniversalFile(file, "template.yml").exists()) ? new YAMLConfig(new UniversalFile(file, "template.yml")).get().getSection("Template", new YAMLSection()) : new YAMLSection();
|
ObjectMap<String> config = (new File(file, "template.yml").exists())? new YAMLConfig(new File(file, "template.yml")).get().getMap("Template", new ObjectMap<String>()) : new ObjectMap<String>();
|
||||||
ServerTemplate template = new ServerTemplate(file.getName(), config.getBoolean("Enabled", true), config.getRawString("Icon", "::NULL::"), file, config.getSection("Build", new YAMLSection()), config.getSection("Settings", new YAMLSection()));
|
ServerTemplate template = loadTemplate(file.getName(), config.getBoolean("Enabled", true), config.getBoolean("Internal", false), config.getString("Icon", "::NULL::"), file, config.getMap("Build", new ObjectMap<String>()), config.getMap("Settings", new ObjectMap<String>()));
|
||||||
templates.put(file.getName().toLowerCase(), template);
|
templates.put(file.getName().toLowerCase(), template);
|
||||||
if (config.getKeys().contains("Display")) template.setDisplayName(config.getString("Display"));
|
if (config.getKeys().contains("Display")) template.setDisplayName(Util.unescapeJavaString(config.getString("Display")));
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.out.println(host.getName() + File.separator + "Creator > Couldn't load template: " + file.getName());
|
Logger.get(host.getName()).severe("Couldn't load template: " + file.getName());
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -301,25 +391,25 @@ public class InternalSubCreator extends SubCreator {
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
@Override
|
@Override
|
||||||
public boolean create(UUID player, String name, ServerTemplate template, Version version, Integer port, Callback<SubServer> callback) {
|
public boolean create(UUID player, String name, ServerTemplate template, Version version, Integer port, Consumer<SubServer> callback) {
|
||||||
if (Util.isNull(name, template, version)) throw new NullPointerException();
|
Util.nullpo(name, template);
|
||||||
if (host.isAvailable() && host.isEnabled() && template.isEnabled() && !SubAPI.getInstance().getSubServers().keySet().contains(name.toLowerCase()) && !SubCreator.isReserved(name)) {
|
if (host.isAvailable() && host.isEnabled() && template.isEnabled() && !SubAPI.getInstance().getSubServers().containsKey(name.toLowerCase()) && !SubCreator.isReserved(name) && (version != null || !template.requiresVersion())) {
|
||||||
StackTraceElement[] origin = new Exception().getStackTrace();
|
StackTraceElement[] origin = new Throwable().getStackTrace();
|
||||||
|
|
||||||
if (port == null) {
|
if (port == null) {
|
||||||
Container<Integer> i = new Container<Integer>(ports.lowerEndpoint() - 1);
|
Value<Integer> i = new Container<Integer>(ports.lowerEndpoint() - 1);
|
||||||
port = Util.getNew(getAllReservedAddresses(), () -> {
|
port = Util.getNew(getAllReservedAddresses(), () -> {
|
||||||
do {
|
do {
|
||||||
i.set(i.get() + 1);
|
i.value(i.value() + 1);
|
||||||
if (i.get() > ports.upperEndpoint()) throw new IllegalStateException("There are no more ports available in range: " + ports.toString());
|
if (i.value() > ports.upperEndpoint()) throw new IllegalStateException("There are no more ports available in range: " + ports.toString());
|
||||||
} while (!ports.contains(i.get()));
|
} while (!ports.contains(i.value()));
|
||||||
return new InetSocketAddress(host.getAddress(), i.get());
|
return new InetSocketAddress(host.getAddress(), i.value());
|
||||||
}).getPort();
|
}).getPort();
|
||||||
}
|
}
|
||||||
|
|
||||||
CreatorTask task = new CreatorTask(player, name, template, version, port, server -> {
|
CreatorTask task = new CreatorTask(player, name, template, version, port, server -> {
|
||||||
if (callback != null && server != null) try {
|
if (callback != null) try {
|
||||||
callback.run(server);
|
callback.accept(server);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Throwable ew = new InvocationTargetException(e);
|
Throwable ew = new InvocationTargetException(e);
|
||||||
ew.setStackTrace(origin);
|
ew.setStackTrace(origin);
|
||||||
|
@ -340,6 +430,39 @@ public class InternalSubCreator extends SubCreator {
|
||||||
} else return false;
|
} else return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Override
|
||||||
|
public boolean update(UUID player, SubServer server, ServerTemplate template, Version version, Consumer<Boolean> callback) {
|
||||||
|
Util.nullpo(server);
|
||||||
|
final ServerTemplate ft = (template == null)?server.getTemplate():template;
|
||||||
|
if (host.isAvailable() && host.isEnabled() && host == server.getHost() && server.isAvailable() && !server.isRunning() && ft != null && ft.isEnabled() && ft.canUpdate() && (version != null || !ft.requiresVersion())) {
|
||||||
|
StackTraceElement[] origin = new Throwable().getStackTrace();
|
||||||
|
|
||||||
|
((InternalSubServer) server).updating(true);
|
||||||
|
CreatorTask task = new CreatorTask(player, server, ft, version, x -> {
|
||||||
|
((InternalSubServer) server).updating(false);
|
||||||
|
if (callback != null) try {
|
||||||
|
callback.accept(x != null);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Throwable ew = new InvocationTargetException(e);
|
||||||
|
ew.setStackTrace(origin);
|
||||||
|
ew.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.thread.put(server.getName().toLowerCase(), task);
|
||||||
|
|
||||||
|
final SubCreateEvent event = new SubCreateEvent(player, server, ft, version);
|
||||||
|
host.plugin.getPluginManager().callEvent(event);
|
||||||
|
if (!event.isCancelled()) {
|
||||||
|
task.start();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
this.thread.remove(server.getName().toLowerCase());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void terminate() {
|
public void terminate() {
|
||||||
HashMap<String, CreatorTask> temp = new HashMap<String, CreatorTask>();
|
HashMap<String, CreatorTask> temp = new HashMap<String, CreatorTask>();
|
||||||
|
@ -351,7 +474,7 @@ public class InternalSubCreator extends SubCreator {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void terminate(String name) {
|
public void terminate(String name) {
|
||||||
if (this.thread.keySet().contains(name.toLowerCase())) {
|
if (this.thread.containsKey(name.toLowerCase())) {
|
||||||
if (this.thread.get(name.toLowerCase()).process != null && this.thread.get(name.toLowerCase()).process.isAlive()) {
|
if (this.thread.get(name.toLowerCase()).process != null && this.thread.get(name.toLowerCase()).process.isAlive()) {
|
||||||
Executable.terminate(this.thread.get(name.toLowerCase()).process);
|
Executable.terminate(this.thread.get(name.toLowerCase()).process);
|
||||||
} else if (this.thread.get(name.toLowerCase()).isAlive()) {
|
} else if (this.thread.get(name.toLowerCase()).isAlive()) {
|
||||||
|
@ -372,7 +495,7 @@ public class InternalSubCreator extends SubCreator {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void waitFor(String name) throws InterruptedException {
|
public void waitFor(String name) throws InterruptedException {
|
||||||
while (this.thread.keySet().contains(name.toLowerCase()) && this.thread.get(name.toLowerCase()).isAlive()) {
|
while (this.thread.containsKey(name.toLowerCase()) && this.thread.get(name.toLowerCase()).isAlive()) {
|
||||||
Thread.sleep(250);
|
Thread.sleep(250);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -416,13 +539,13 @@ public class InternalSubCreator extends SubCreator {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLogging() {
|
public boolean isLogging() {
|
||||||
return log.get();
|
return log.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setLogging(boolean value) {
|
public void setLogging(boolean value) {
|
||||||
if (Util.isNull(value)) throw new NullPointerException();
|
Util.nullpo(value);
|
||||||
log.set(value);
|
log.value(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -439,43 +562,100 @@ public class InternalSubCreator extends SubCreator {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, ServerTemplate> getTemplates() {
|
public Map<String, ServerTemplate> getTemplates() {
|
||||||
return new TreeMap<String, ServerTemplate>(templates);
|
TreeMap<String, ServerTemplate> map = new TreeMap<String, ServerTemplate>();
|
||||||
|
for (Map.Entry<String, ServerTemplate> template : templates.entrySet()) {
|
||||||
|
if (!template.getValue().isInternal()) map.put(template.getKey(), template.getValue());
|
||||||
|
}
|
||||||
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ServerTemplate getTemplate(String name) {
|
public ServerTemplate getTemplate(String name) {
|
||||||
if (Util.isNull(name)) throw new NullPointerException();
|
Util.nullpo(name);
|
||||||
return getTemplates().get(name.toLowerCase());
|
|
||||||
|
ServerTemplate template = templates.getOrDefault(name.toLowerCase(), null);
|
||||||
|
if (template == null || template.isInternal()) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Pair<YAMLSection, Map<String, Object>> subdata = null;
|
||||||
|
private Map<String, Object> getSubData() {
|
||||||
|
if (subdata == null || host.plugin.config.get() != subdata.key()) {
|
||||||
|
Map<String, Object> map = new HashMap<String, Object>();
|
||||||
|
map.put("Address", host.plugin.config.get().getMap("Settings").getMap("SubData").getString("Address", "127.0.0.1").replace("0.0.0.0", "127.0.0.1"));
|
||||||
|
if (host.plugin.config.get().getMap("Settings").getMap("SubData").getString("Password", "").length() > 0) map.put("Password", host.plugin.config.get().getMap("Settings").getMap("SubData").getString("Password"));
|
||||||
|
subdata = new ContainedPair<>(host.plugin.config.get(), map);
|
||||||
|
}
|
||||||
|
return subdata.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateClient(File dir, ServerType type, String name) throws IOException {
|
private void generateClient(File dir, ServerType type, String name) throws IOException {
|
||||||
if (new UniversalFile(dir, "subservers.client").exists()) {
|
boolean installed = false;
|
||||||
if (type == ServerType.SPIGOT) {
|
if (type == ServerType.SPIGOT) {
|
||||||
if (!new UniversalFile(dir, "plugins").exists()) new UniversalFile(dir, "plugins").mkdirs();
|
installed = true;
|
||||||
Util.copyFromJar(SubPlugin.class.getClassLoader(), "net/ME1312/SubServers/Bungee/Library/Files/client.jar", new UniversalFile(dir, "plugins:SubServers.Client.jar").getPath());
|
if (!new File(dir, "plugins").exists()) new File(dir, "plugins").mkdirs();
|
||||||
} else if (type == ServerType.FORGE || type == ServerType.SPONGE) {
|
if (!new File(dir, "plugins/SubServers.Client.jar").exists())
|
||||||
if (!new UniversalFile(dir, "mods").exists()) new UniversalFile(dir, "mods").mkdirs();
|
Util.copyFromJar(SubProxy.class.getClassLoader(), "net/ME1312/SubServers/Bungee/Library/Files/client.jar", new File(dir, "plugins/SubServers.Client.jar").getPath());
|
||||||
Util.copyFromJar(SubPlugin.class.getClassLoader(), "net/ME1312/SubServers/Bungee/Library/Files/client.jar", new UniversalFile(dir, "mods:SubServers.Client.jar").getPath());
|
} else if (type == ServerType.FORGE || type == ServerType.SPONGE) {
|
||||||
}
|
installed = true;
|
||||||
|
if (!new File(dir, "mods").exists()) new File(dir, "mods").mkdirs();
|
||||||
|
if (!new File(dir, "mods/SubServers.Client.jar").exists())
|
||||||
|
Util.copyFromJar(SubProxy.class.getClassLoader(), "net/ME1312/SubServers/Bungee/Library/Files/client.jar", new File(dir, "mods/SubServers.Client.jar").getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (installed) {
|
||||||
YAMLSection config = new YAMLSection();
|
YAMLSection config = new YAMLSection();
|
||||||
FileWriter writer = new FileWriter(new UniversalFile(dir, "subservers.client"), false);
|
FileWriter writer = new FileWriter(new File(dir, "subdata.json"), false);
|
||||||
config.set("Name", name);
|
config.setAll(getSubData());
|
||||||
config.set("Address", host.plugin.config.get().getSection("Settings").getSection("SubData").getRawString("Address", "127.0.0.1").replace("0.0.0.0", "127.0.0.1"));
|
writer.write(new Gson().toJson(config.get()));
|
||||||
config.set("Password", host.plugin.config.get().getSection("Settings").getSection("SubData").getRawString("Password", ""));
|
|
||||||
config.set("Encryption", host.plugin.config.get().getSection("Settings").getSection("SubData").getRawString("Encryption", "NONE"));
|
|
||||||
writer.write(config.toJSON());
|
|
||||||
writer.close();
|
writer.close();
|
||||||
|
|
||||||
|
if (!new File(dir, "subdata.rsa.key").exists() && new File("SubServers/subdata.rsa.key").exists()) {
|
||||||
|
Files.copy(new File("SubServers/subdata.rsa.key").toPath(), new File(dir, "subdata.rsa.key").toPath());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void generateProperties(File dir, int port) throws IOException {
|
|
||||||
File file = new File(dir, "server.properties");
|
private void updateDirectory(File from, File to, boolean overwrite) {
|
||||||
if (!file.exists()) file.createNewFile();
|
if (!to.exists()) {
|
||||||
InputStream stream = new FileInputStream(file);
|
Directories.copy(from, to);
|
||||||
String content = Util.readAll(new BufferedReader(new InputStreamReader(stream))).replaceAll("server-port=.*(\r?\n)", "server-port=" + port + "$1").replaceAll("server-ip=.*(\r?\n)", "server-ip=" + host.getAddress().getHostAddress() + "$1");
|
} else if (from.isDirectory() && !Files.isSymbolicLink(from.toPath())) {
|
||||||
stream.close();
|
String files[] = from.list();
|
||||||
file.delete();
|
|
||||||
PrintWriter writer = new PrintWriter(file, "UTF-8");
|
for (String file : files) {
|
||||||
writer.write(content);
|
File srcFile = new File(from, file);
|
||||||
writer.close();
|
File destFile = new File(to, file);
|
||||||
|
|
||||||
|
updateDirectory(srcFile, destFile, overwrite);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
if (overwrite && (from.length() != to.length() || !Arrays.equals(generateSHA256(to), generateSHA256(from)))) {
|
||||||
|
if (to.exists()) {
|
||||||
|
if (to.isDirectory()) Directories.delete(to);
|
||||||
|
else to.delete();
|
||||||
|
}
|
||||||
|
Files.copy(from.toPath(), to.toPath(), LinkOption.NOFOLLOW_LINKS, StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} private byte[] generateSHA256(File file) throws Exception {
|
||||||
|
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
||||||
|
FileInputStream fis = new FileInputStream(file);
|
||||||
|
byte[] dataBytes = new byte[4096];
|
||||||
|
|
||||||
|
int nread;
|
||||||
|
|
||||||
|
while ((nread = fis.read(dataBytes)) != -1) {
|
||||||
|
md.update(dataBytes, 0, nread);
|
||||||
|
}
|
||||||
|
|
||||||
|
fis.close();
|
||||||
|
return md.digest();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,18 +1,18 @@
|
||||||
package net.ME1312.SubServers.Bungee.Host.Internal;
|
package net.ME1312.SubServers.Bungee.Host.Internal;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Container.Value;
|
||||||
|
import net.ME1312.Galaxi.Library.Try;
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
import net.ME1312.SubServers.Bungee.Host.SubLogFilter;
|
import net.ME1312.SubServers.Bungee.Host.SubLogFilter;
|
||||||
import net.ME1312.SubServers.Bungee.Host.SubLogger;
|
import net.ME1312.SubServers.Bungee.Host.SubLogger;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Container;
|
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
|
||||||
import net.ME1312.SubServers.Bungee.Library.NamedContainer;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import net.ME1312.SubServers.Bungee.SubAPI;
|
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
@ -21,12 +21,12 @@ import java.util.regex.Pattern;
|
||||||
* Internal Process Logger Class
|
* Internal Process Logger Class
|
||||||
*/
|
*/
|
||||||
public class InternalSubLogger extends SubLogger {
|
public class InternalSubLogger extends SubLogger {
|
||||||
protected Process process;
|
Process process;
|
||||||
private Object handle;
|
private Object handle;
|
||||||
protected String name;
|
String name;
|
||||||
protected Container<Boolean> log;
|
Value<Boolean> log;
|
||||||
private List<SubLogFilter> filters = new ArrayList<SubLogFilter>();
|
private List<SubLogFilter> filters = new CopyOnWriteArrayList<>();
|
||||||
protected File file;
|
File file;
|
||||||
private PrintWriter writer = null;
|
private PrintWriter writer = null;
|
||||||
private boolean started = false;
|
private boolean started = false;
|
||||||
private Thread out = null;
|
private Thread out = null;
|
||||||
|
@ -41,7 +41,7 @@ public class InternalSubLogger extends SubLogger {
|
||||||
* @param log Console Logging Status
|
* @param log Console Logging Status
|
||||||
* @param file File to log to (or null for disabled)
|
* @param file File to log to (or null for disabled)
|
||||||
*/
|
*/
|
||||||
protected InternalSubLogger(Process process, Object user, String name, Container<Boolean> log, File file) {
|
InternalSubLogger(Process process, Object user, String name, Value<Boolean> log, File file) {
|
||||||
this.process = process;
|
this.process = process;
|
||||||
this.handle = user;
|
this.handle = user;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
@ -49,6 +49,16 @@ public class InternalSubLogger extends SubLogger {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init() {
|
||||||
|
List<SubLogFilter> filters = new ArrayList<SubLogFilter>();
|
||||||
|
filters.addAll(this.filters);
|
||||||
|
for (SubLogFilter filter : filters) try {
|
||||||
|
filter.start();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
new InvocationTargetException(e, "Exception while running SubLogger Event").printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start() {
|
public void start() {
|
||||||
started = true;
|
started = true;
|
||||||
|
@ -63,13 +73,6 @@ public class InternalSubLogger extends SubLogger {
|
||||||
}
|
}
|
||||||
if (out == null) (out = new Thread(() -> start(process.getInputStream(), false), "SubServers.Bungee::Internal_Log_Spooler(" + name + ')')).start();
|
if (out == null) (out = new Thread(() -> start(process.getInputStream(), false), "SubServers.Bungee::Internal_Log_Spooler(" + name + ')')).start();
|
||||||
if (err == null) (err = new Thread(() -> start(process.getErrorStream(), true), "SubServers.Bungee::Internal_Error_Spooler(" + name + ')')).start();
|
if (err == null) (err = new Thread(() -> start(process.getErrorStream(), true), "SubServers.Bungee::Internal_Error_Spooler(" + name + ')')).start();
|
||||||
List<SubLogFilter> filters = new ArrayList<SubLogFilter>();
|
|
||||||
filters.addAll(this.filters);
|
|
||||||
for (SubLogFilter filter : filters) try {
|
|
||||||
filter.start();
|
|
||||||
} catch (Throwable e) {
|
|
||||||
new InvocationTargetException(e, "Exception while running SubLogger Event").printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
|
@ -91,48 +94,46 @@ public class InternalSubLogger extends SubLogger {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Level level = Level.INFO;
|
||||||
|
private static final String PATTERN = "^((?:\\s*\\[?([0-9]{2}:[0-9]{2}:[0-9]{2})]?)?[\\s\\/\\\\\\|]*(?:\\[|\\[.*\\/)?(DEBUG|MESSAGE|MSG|" + Pattern.quote(Level.INFO.getLocalizedName()) + "|INFO|" + Pattern.quote(Level.WARNING.getLocalizedName()) + "|WARNING|WARN|ERROR|ERR|" + Pattern.quote(Level.SEVERE.getLocalizedName()) + "|SEVERE)\\]?(?::|\\s*>)?\\s*)";
|
||||||
private void log(String line) {
|
private void log(String line) {
|
||||||
if (!line.startsWith(">")) {
|
if (!line.startsWith(">")) {
|
||||||
String msg = line;
|
String msg = line;
|
||||||
Level level;
|
|
||||||
|
|
||||||
// REGEX Formatting
|
// REGEX Formatting
|
||||||
String type = "";
|
String type = null;
|
||||||
Matcher matcher = Pattern.compile("^((?:\\s*\\[?([0-9]{2}:[0-9]{2}:[0-9]{2})]?)?[\\s\\/\\\\\\|]*(?:\\[|\\[.*\\/)?(MESSAGE|INFO|WARNING|WARN|ERROR|ERR|SEVERE)\\]?:?(?:\\s*>)?\\s*)").matcher(msg.replaceAll("\u001B\\[[;\\d]*m", ""));
|
Matcher matcher = Pattern.compile(PATTERN).matcher(msg.replaceAll("\u001B\\[[;\\d]*m", ""));
|
||||||
while (matcher.find()) {
|
if (matcher.find()) {
|
||||||
type = matcher.group(3).toUpperCase();
|
type = matcher.group(3).toUpperCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = msg.replaceAll("^((?:\\s*\\[?([0-9]{2}:[0-9]{2}:[0-9]{2})]?)?[\\s\\/\\\\\\|]*(?:\\[|\\[.*\\/)?(MESSAGE|INFO|WARNING|WARN|ERROR|ERR|SEVERE)\\]?:?(?:\\s*>)?\\s*)", "");
|
msg = msg.replaceAll(PATTERN, "");
|
||||||
|
|
||||||
// Determine LOG LEVEL
|
// Determine LOG LEVEL
|
||||||
switch (type) {
|
if (type != null) {
|
||||||
case "WARNING":
|
if (type.equalsIgnoreCase(Level.INFO.getLocalizedName())) {
|
||||||
case "WARN":
|
|
||||||
level = Level.WARNING;
|
|
||||||
break;
|
|
||||||
case "SEVERE":
|
|
||||||
case "ERROR":
|
|
||||||
case "ERR":
|
|
||||||
level = Level.SEVERE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
level = Level.INFO;
|
level = Level.INFO;
|
||||||
|
} else if (type.equalsIgnoreCase(Level.WARNING.getLocalizedName())) {
|
||||||
|
level = Level.WARNING;
|
||||||
|
} else if (type.equalsIgnoreCase(Level.SEVERE.getLocalizedName())) {
|
||||||
|
level = Level.SEVERE;
|
||||||
|
} else switch (type) {
|
||||||
|
case "WARNING":
|
||||||
|
case "WARN":
|
||||||
|
level = Level.WARNING;
|
||||||
|
break;
|
||||||
|
case "SEVERE":
|
||||||
|
case "ERROR":
|
||||||
|
case "ERR":
|
||||||
|
level = Level.SEVERE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
level = Level.INFO;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter Message
|
// Log to FILTER
|
||||||
boolean allow = (SubAPI.getInstance().getInternals().sudo == getHandler() && SubAPI.getInstance().getInternals().canSudo) || (log.get() && (SubAPI.getInstance().getInternals().sudo == null || !SubAPI.getInstance().getInternals().canSudo));
|
log(level, msg);
|
||||||
List<SubLogFilter> filters = new ArrayList<SubLogFilter>();
|
|
||||||
filters.addAll(this.filters);
|
|
||||||
for (SubLogFilter filter : filters)
|
|
||||||
try {
|
|
||||||
allow = (filter.log(level, msg) && allow);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
new InvocationTargetException(e, "Exception while running SubLogger Event").printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log to CONSOLE
|
|
||||||
if (allow) ProxyServer.getInstance().getLogger().log(level, name + " > " + msg);
|
|
||||||
|
|
||||||
// Log to FILE
|
// Log to FILE
|
||||||
if (writer != null) {
|
if (writer != null) {
|
||||||
|
@ -142,47 +143,68 @@ public class InternalSubLogger extends SubLogger {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void log(Level level, String message) {
|
||||||
|
// Filter Message
|
||||||
|
boolean allow = (SubAPI.getInstance().getInternals().sudo == getHandler() && SubAPI.getInstance().getInternals().canSudo) || (log.value() && (SubAPI.getInstance().getInternals().sudo == null || !SubAPI.getInstance().getInternals().canSudo));
|
||||||
|
List<SubLogFilter> filters = new ArrayList<SubLogFilter>();
|
||||||
|
filters.addAll(this.filters);
|
||||||
|
for (SubLogFilter filter : filters) {
|
||||||
|
try {
|
||||||
|
allow = (filter.log(level, message) && allow);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
new InvocationTargetException(e, "Exception while running SubLogger Event").printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log to CONSOLE
|
||||||
|
if (allow || !started) {
|
||||||
|
Logger.get(name).log(level, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stop() {
|
public void stop() {
|
||||||
if (out != null) out.interrupt();
|
try {
|
||||||
if (err != null) err.interrupt();
|
if (out != null) out.interrupt();
|
||||||
destroy();
|
if (err != null) err.interrupt();
|
||||||
|
level = Level.INFO;
|
||||||
|
|
||||||
|
if (started) {
|
||||||
|
started = false;
|
||||||
|
if (writer != null) {
|
||||||
|
PrintWriter writer = this.writer;
|
||||||
|
this.writer = null;
|
||||||
|
int l = (("---------- LOG START \u2014 " + name + " ----------").length() - 9) / 2;
|
||||||
|
String s = "";
|
||||||
|
while (s.length() < l) s += '-';
|
||||||
|
if (writer != null) {
|
||||||
|
writer.println(s + " LOG END " + s);
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (NullPointerException e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy() {
|
||||||
|
filters.addAll(this.filters);
|
||||||
|
for (SubLogFilter filter : filters) try {
|
||||||
|
filter.stop();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
new InvocationTargetException(e, "Exception while running SubLogger Event").printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerFilter(SubLogFilter filter) {
|
public void registerFilter(SubLogFilter filter) {
|
||||||
if (Util.isNull(filter)) throw new NullPointerException();
|
Util.nullpo(filter);
|
||||||
filters.add(filter);
|
filters.add(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unregisterFilter(SubLogFilter filter) {
|
public void unregisterFilter(SubLogFilter filter) {
|
||||||
if (Util.isNull(filter)) throw new NullPointerException();
|
Util.nullpo(filter);
|
||||||
filters.remove(filter);
|
Try.all.run(() -> filters.remove(filter));
|
||||||
}
|
|
||||||
|
|
||||||
private void destroy() {
|
|
||||||
if (started) {
|
|
||||||
started = false;
|
|
||||||
List<SubLogFilter> filters = new ArrayList<SubLogFilter>();
|
|
||||||
filters.addAll(this.filters);
|
|
||||||
for (SubLogFilter filter : filters) try {
|
|
||||||
filter.stop();
|
|
||||||
} catch (Throwable e) {
|
|
||||||
new InvocationTargetException(e, "Exception while running SubLogger Event").printStackTrace();
|
|
||||||
}
|
|
||||||
if (writer != null) {
|
|
||||||
PrintWriter writer = this.writer;
|
|
||||||
this.writer = null;
|
|
||||||
int l = (int) Math.floor((("---------- LOG START \u2014 " + name + " ----------").length() - 9) / 2);
|
|
||||||
String s = "";
|
|
||||||
while (s.length() < l) s += '-';
|
|
||||||
if (writer != null) {
|
|
||||||
writer.println(s + " LOG END " + s);
|
|
||||||
writer.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -197,6 +219,6 @@ public class InternalSubLogger extends SubLogger {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLogging() {
|
public boolean isLogging() {
|
||||||
return log.get();
|
return log.value();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,29 @@
|
||||||
package net.ME1312.SubServers.Bungee.Host.Internal;
|
package net.ME1312.SubServers.Bungee.Host.Internal;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Container.ContainedPair;
|
||||||
|
import net.ME1312.Galaxi.Library.Container.Container;
|
||||||
|
import net.ME1312.Galaxi.Library.Container.Value;
|
||||||
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
|
import net.ME1312.Galaxi.Library.Map.ObjectMapValue;
|
||||||
|
import net.ME1312.Galaxi.Library.Try;
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
|
import net.ME1312.Galaxi.Library.Version.Version;
|
||||||
|
import net.ME1312.SubData.Server.SubDataClient;
|
||||||
import net.ME1312.SubServers.Bungee.Event.*;
|
import net.ME1312.SubServers.Bungee.Event.*;
|
||||||
import net.ME1312.SubServers.Bungee.Host.*;
|
import net.ME1312.SubServers.Bungee.Host.*;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLValue;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Container;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
||||||
import net.ME1312.SubServers.Bungee.Library.NamedContainer;
|
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutExEditServer;
|
||||||
import net.ME1312.SubServers.Bungee.Library.UniversalFile;
|
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutExEditServer.Edit;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
|
||||||
import net.md_5.bungee.BungeeServerInfo;
|
|
||||||
|
|
||||||
import java.io.*;
|
import net.md_5.bungee.api.ChatColor;
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Method;
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -26,10 +34,10 @@ import java.util.jar.JarInputStream;
|
||||||
/**
|
/**
|
||||||
* Internal SubServer Class
|
* Internal SubServer Class
|
||||||
*/
|
*/
|
||||||
public class InternalSubServer extends SubServerContainer {
|
public class InternalSubServer extends SubServerImpl {
|
||||||
private InternalHost host;
|
private InternalHost host;
|
||||||
private boolean enabled;
|
private boolean enabled;
|
||||||
private Container<Boolean> log;
|
private Value<Boolean> log;
|
||||||
private String dir;
|
private String dir;
|
||||||
private File directory;
|
private File directory;
|
||||||
private String executable;
|
private String executable;
|
||||||
|
@ -59,9 +67,34 @@ public class InternalSubServer extends SubServerContainer {
|
||||||
* @param restricted Restricted Status
|
* @param restricted Restricted Status
|
||||||
* @throws InvalidServerException
|
* @throws InvalidServerException
|
||||||
*/
|
*/
|
||||||
public InternalSubServer(InternalHost host, String name, boolean enabled, int port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
public static InternalSubServer construct(InternalHost host, String name, boolean enabled, int port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||||
|
try {
|
||||||
|
return new InternalSubServer(host, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||||
|
} catch (NoSuchMethodError e) {
|
||||||
|
return new InternalSubServer(host, name, enabled, (Integer) port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Super Method 2 (newest)
|
||||||
|
* @see #construct(InternalHost, String, boolean, int, String, boolean, String, String, String, boolean, boolean) for method details
|
||||||
|
*/
|
||||||
|
protected InternalSubServer(InternalHost host, String name, boolean enabled, int port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||||
super(host, name, port, motd, hidden, restricted);
|
super(host, name, port, motd, hidden, restricted);
|
||||||
if (Util.isNull(host, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted)) throw new NullPointerException();
|
init(host, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Super Method 1 (oldest)
|
||||||
|
* @see #construct(InternalHost, String, boolean, int, String, boolean, String, String, String, boolean, boolean) for method details
|
||||||
|
*/
|
||||||
|
protected InternalSubServer(InternalHost host, String name, boolean enabled, Integer port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||||
|
super(host, name, port, motd, hidden, restricted);
|
||||||
|
init(host, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init(InternalHost host, String name, boolean enabled, int port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||||
|
Util.nullpo(host, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||||
this.host = host;
|
this.host = host;
|
||||||
this.enabled = enabled;
|
this.enabled = enabled;
|
||||||
this.log = new Container<Boolean>(log);
|
this.log = new Container<Boolean>(log);
|
||||||
|
@ -75,58 +108,62 @@ public class InternalSubServer extends SubServerContainer {
|
||||||
this.logger = new InternalSubLogger(null, this, getName(), this.log, null);
|
this.logger = new InternalSubLogger(null, this, getName(), this.log, null);
|
||||||
this.thread = null;
|
this.thread = null;
|
||||||
this.command = null;
|
this.command = null;
|
||||||
|
final File[] locations = new File[] {
|
||||||
|
new File(this.directory, "plugins/SubServers.Client.jar"),
|
||||||
|
new File(this.directory, "mods/SubServers.Client.jar")
|
||||||
|
};
|
||||||
|
|
||||||
if (new UniversalFile(this.directory, "plugins:SubServers.Client.jar").exists()) {
|
for (File location : locations) {
|
||||||
try {
|
if (location.exists()) {
|
||||||
JarInputStream updated = new JarInputStream(SubPlugin.class.getResourceAsStream("/net/ME1312/SubServers/Bungee/Library/Files/client.jar"));
|
try {
|
||||||
JarFile existing = new JarFile(new UniversalFile(this.directory, "plugins:SubServers.Client.jar"));
|
JarInputStream updated = new JarInputStream(SubProxy.class.getResourceAsStream("/net/ME1312/SubServers/Bungee/Library/Files/client.jar"));
|
||||||
|
JarFile existing = new JarFile(location);
|
||||||
|
|
||||||
if (existing.getManifest().getMainAttributes().getValue("Implementation-Title") != null && existing.getManifest().getMainAttributes().getValue("Implementation-Title").startsWith("SubServers.Client") && existing.getManifest().getMainAttributes().getValue("Specification-Title") != null &&
|
if (existing.getManifest().getMainAttributes().getValue("Implementation-Title") != null && existing.getManifest().getMainAttributes().getValue("Implementation-Title").startsWith("SubServers.Client") && existing.getManifest().getMainAttributes().getValue("Specification-Title") != null &&
|
||||||
updated.getManifest().getMainAttributes().getValue("Implementation-Title") != null && updated.getManifest().getMainAttributes().getValue("Implementation-Title").startsWith("SubServers.Client") && updated.getManifest().getMainAttributes().getValue("Specification-Title") != null) {
|
updated.getManifest().getMainAttributes().getValue("Implementation-Title") != null && updated.getManifest().getMainAttributes().getValue("Implementation-Title").startsWith("SubServers.Client") && updated.getManifest().getMainAttributes().getValue("Specification-Title") != null) {
|
||||||
if (new Version(existing.getManifest().getMainAttributes().getValue("Specification-Title")).compareTo(new Version(updated.getManifest().getMainAttributes().getValue("Specification-Title"))) < 0) {
|
if (new Version(existing.getManifest().getMainAttributes().getValue("Specification-Title")).compareTo(new Version(updated.getManifest().getMainAttributes().getValue("Specification-Title"))) < 0) {
|
||||||
new UniversalFile(this.directory, "plugins:SubServers.Client.jar").delete();
|
location.delete();
|
||||||
Util.copyFromJar(SubPlugin.class.getClassLoader(), "net/ME1312/SubServers/Bungee/Library/Files/client.jar", new UniversalFile(this.directory, "plugins:SubServers.Client.jar").getPath());
|
Util.copyFromJar(SubProxy.class.getClassLoader(), "net/ME1312/SubServers/Bungee/Library/Files/client.jar", location.getPath());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
existing.close();
|
||||||
|
updated.close();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
System.out.println("Couldn't auto-update SubServers.Client for subserver: " + name);
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
existing.close();
|
|
||||||
updated.close();
|
|
||||||
} catch (Throwable e) {
|
|
||||||
System.out.println("Couldn't auto-update SubServers.Client.jar for " + name);
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
} else if (new UniversalFile(this.directory, "mods:SubServers.Client.jar").exists()) {
|
|
||||||
try {
|
|
||||||
JarInputStream updated = new JarInputStream(SubPlugin.class.getResourceAsStream("/net/ME1312/SubServers/Bungee/Library/Files/client.jar"));
|
|
||||||
JarFile existing = new JarFile(new UniversalFile(this.directory, "mods:SubServers.Client.jar"));
|
|
||||||
|
|
||||||
if (existing.getManifest().getMainAttributes().getValue("Implementation-Title") != null && existing.getManifest().getMainAttributes().getValue("Implementation-Title").startsWith("SubServers.Client") && existing.getManifest().getMainAttributes().getValue("Specification-Title") != null &&
|
|
||||||
updated.getManifest().getMainAttributes().getValue("Implementation-Title") != null && updated.getManifest().getMainAttributes().getValue("Implementation-Title").startsWith("SubServers.Client") && updated.getManifest().getMainAttributes().getValue("Specification-Title") != null) {
|
|
||||||
if (new Version(existing.getManifest().getMainAttributes().getValue("Specification-Title")).compareTo(new Version(updated.getManifest().getMainAttributes().getValue("Specification-Title"))) < 0) {
|
|
||||||
new UniversalFile(this.directory, "mods:SubServers.Client.jar").delete();
|
|
||||||
Util.copyFromJar(SubPlugin.class.getClassLoader(), "net/ME1312/SubServers/Bungee/Library/Files/client.jar", new UniversalFile(this.directory, "mods:SubServers.Client.jar").getPath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
existing.close();
|
|
||||||
updated.close();
|
|
||||||
} catch (Throwable e) {
|
|
||||||
System.out.println("Couldn't auto-update SubServers.Client.jar for " + name);
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.lock = false;
|
this.lock = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void registered(boolean value) {
|
||||||
|
registered = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updating(boolean value) {
|
||||||
|
updating = value;
|
||||||
|
}
|
||||||
|
|
||||||
private void run() {
|
private void run() {
|
||||||
|
boolean locked = lock;
|
||||||
allowrestart = true;
|
allowrestart = true;
|
||||||
|
stopping = false;
|
||||||
|
started = false;
|
||||||
try {
|
try {
|
||||||
ProcessBuilder pb = new ProcessBuilder().command(Executable.parse(host.getCreator().getBashDirectory(), executable)).directory(directory);
|
ProcessBuilder pb = new ProcessBuilder().command(Executable.parse(host.getCreator().getBashDirectory(), executable)).directory(directory);
|
||||||
|
pb.environment().put("java", System.getProperty("java.home") + File.separator + "bin" + File.separator + "java");
|
||||||
pb.environment().put("name", getName());
|
pb.environment().put("name", getName());
|
||||||
|
pb.environment().put("host", host.getName());
|
||||||
pb.environment().put("address", host.getAddress().getHostAddress());
|
pb.environment().put("address", host.getAddress().getHostAddress());
|
||||||
pb.environment().put("port", Integer.toString(getAddress().getPort()));
|
pb.environment().put("port", Integer.toString(getAddress().getPort()));
|
||||||
|
logger.init();
|
||||||
process = pb.start();
|
process = pb.start();
|
||||||
System.out.println("SubServers > Now starting " + getName());
|
Logger.get("SubServers").info("Now starting " + getName());
|
||||||
logger.process = process;
|
logger.process = process;
|
||||||
logger.start();
|
logger.start();
|
||||||
|
lock = locked = false;
|
||||||
command = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
|
command = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
|
||||||
for (LoggedCommand command : history) if (process.isAlive()) {
|
for (LoggedCommand command : history) if (process.isAlive()) {
|
||||||
this.command.write(command.getCommand());
|
this.command.write(command.getCommand());
|
||||||
|
@ -137,25 +174,32 @@ public class InternalSubServer extends SubServerContainer {
|
||||||
if (process.isAlive()) process.waitFor();
|
if (process.isAlive()) process.waitFor();
|
||||||
} catch (IOException | InterruptedException e) {
|
} catch (IOException | InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
if (locked) lock = false;
|
||||||
allowrestart = false;
|
allowrestart = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SubStoppedEvent event = new SubStoppedEvent(this);
|
logger.destroy();
|
||||||
host.plugin.getPluginManager().callEvent(event);
|
Logger.get("SubServers").info(getName() + " has stopped");
|
||||||
System.out.println("SubServers > " + getName() + " has stopped");
|
|
||||||
process = null;
|
process = null;
|
||||||
command = null;
|
command = null;
|
||||||
|
started = false;
|
||||||
|
stopping = false;
|
||||||
history.clear();
|
history.clear();
|
||||||
|
|
||||||
if (stopaction == StopAction.REMOVE_SERVER || stopaction == StopAction.DELETE_SERVER) {
|
SubStoppedEvent event = new SubStoppedEvent(this);
|
||||||
|
host.plugin.getPluginManager().callEvent(event);
|
||||||
|
|
||||||
|
if (stopaction == StopAction.REMOVE_SERVER || stopaction == StopAction.RECYCLE_SERVER || stopaction == StopAction.DELETE_SERVER) {
|
||||||
try {
|
try {
|
||||||
if (stopaction == StopAction.DELETE_SERVER) {
|
if (stopaction == StopAction.RECYCLE_SERVER) {
|
||||||
host.deleteSubServer(getName());
|
host.recycleSubServer(null, getName(), false, false);
|
||||||
|
} else if (stopaction == StopAction.DELETE_SERVER) {
|
||||||
|
host.deleteSubServer(null, getName(), false, false);
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
if (host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
if (host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
host.plugin.config.get().getSection("Servers").remove(getName());
|
host.plugin.servers.get().getMap("Servers").remove(getName());
|
||||||
host.plugin.config.save();
|
host.plugin.servers.save();
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -183,15 +227,17 @@ public class InternalSubServer extends SubServerContainer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean start(UUID player) {
|
public boolean start(UUID player) {
|
||||||
if (!lock && isEnabled() && !(thread != null && thread.isAlive()) && getCurrentIncompatibilities().size() == 0) {
|
if (!lock && isAvailable() && isEnabled() && !(thread != null && thread.isAlive()) && getCurrentIncompatibilities().size() == 0) {
|
||||||
lock = true;
|
lock = true;
|
||||||
SubStartEvent event = new SubStartEvent(player, this);
|
SubStartEvent event = new SubStartEvent(player, this);
|
||||||
host.plugin.getPluginManager().callEvent(event);
|
host.plugin.getPluginManager().callEvent(event);
|
||||||
lock = false;
|
|
||||||
if (!event.isCancelled()) {
|
if (!event.isCancelled()) {
|
||||||
(thread = new Thread(this::run, "SubServers.Bungee::Internal_Server_Process_Handler(" + getName() + ')')).start();
|
(thread = new Thread(this::run, "SubServers.Bungee::Internal_Server_Process_Handler(" + getName() + ')')).start();
|
||||||
return true;
|
return true;
|
||||||
} else return false;
|
} else {
|
||||||
|
lock = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
} else return false;
|
} else return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,6 +248,7 @@ public class InternalSubServer extends SubServerContainer {
|
||||||
host.plugin.getPluginManager().callEvent(event);
|
host.plugin.getPluginManager().callEvent(event);
|
||||||
if (!event.isCancelled()) {
|
if (!event.isCancelled()) {
|
||||||
try {
|
try {
|
||||||
|
stopping = true;
|
||||||
allowrestart = false;
|
allowrestart = false;
|
||||||
history.add(new LoggedCommand(player, stopcmd));
|
history.add(new LoggedCommand(player, stopcmd));
|
||||||
if (process != null && process.isAlive()) {
|
if (process != null && process.isAlive()) {
|
||||||
|
@ -224,6 +271,7 @@ public class InternalSubServer extends SubServerContainer {
|
||||||
SubStopEvent event = new SubStopEvent(player, this, true);
|
SubStopEvent event = new SubStopEvent(player, this, true);
|
||||||
host.plugin.getPluginManager().callEvent(event);
|
host.plugin.getPluginManager().callEvent(event);
|
||||||
if (!event.isCancelled()) {
|
if (!event.isCancelled()) {
|
||||||
|
stopping = true;
|
||||||
allowrestart = false;
|
allowrestart = false;
|
||||||
if (process != null && process.isAlive()) Executable.terminate(process);
|
if (process != null && process.isAlive()) Executable.terminate(process);
|
||||||
return true;
|
return true;
|
||||||
|
@ -233,13 +281,16 @@ public class InternalSubServer extends SubServerContainer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean command(UUID player, String command) {
|
public boolean command(UUID player, String command) {
|
||||||
if (Util.isNull(command)) throw new NullPointerException();
|
Util.nullpo(command);
|
||||||
if (thread != null && thread.isAlive()) {
|
if (thread != null && thread.isAlive()) {
|
||||||
SubSendCommandEvent event = new SubSendCommandEvent(player, this, command);
|
SubSendCommandEvent event = new SubSendCommandEvent(player, this, command, null);
|
||||||
host.plugin.getPluginManager().callEvent(event);
|
host.plugin.getPluginManager().callEvent(event);
|
||||||
if (!event.isCancelled()) {
|
if (!event.isCancelled() && (player == null || !DISALLOWED_COMMANDS.matcher(command).find())) {
|
||||||
try {
|
try {
|
||||||
if (event.getCommand().equalsIgnoreCase(stopcmd)) allowrestart = false;
|
if (event.getCommand().equalsIgnoreCase(stopcmd)) {
|
||||||
|
stopping = true;
|
||||||
|
allowrestart = false;
|
||||||
|
}
|
||||||
history.add(new LoggedCommand(player, event.getCommand()));
|
history.add(new LoggedCommand(player, event.getCommand()));
|
||||||
if (process != null && process.isAlive()) {
|
if (process != null && process.isAlive()) {
|
||||||
this.command.write(event.getCommand());
|
this.command.write(event.getCommand());
|
||||||
|
@ -255,249 +306,275 @@ public class InternalSubServer extends SubServerContainer {
|
||||||
} else return false;
|
} else return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings({"deprecation", "unchecked"})
|
||||||
public int edit(UUID player, YAMLSection edit) {
|
@Override
|
||||||
int c = 0;
|
protected int edit(UUID player, ObjectMap<String> edit, boolean perma) {
|
||||||
boolean state = isRunning();
|
if (isAvailable()) {
|
||||||
SubServer forward = null;
|
int c = 0;
|
||||||
YAMLSection pending = edit.clone();
|
boolean state = isRunning();
|
||||||
for (String key : edit.getKeys()) {
|
SubServer forward = null;
|
||||||
pending.remove(key);
|
ObjectMap<String> pending = edit.clone();
|
||||||
YAMLValue value = edit.get(key);
|
for (String key : edit.getKeys()) {
|
||||||
SubEditServerEvent event = new SubEditServerEvent(player, this, new NamedContainer<String, YAMLValue>(key, value), true);
|
pending.remove(key);
|
||||||
host.plugin.getPluginManager().callEvent(event);
|
ObjectMapValue value = edit.get(key);
|
||||||
if (!event.isCancelled()) {
|
boolean allowed = true;
|
||||||
try {
|
if (perma) {
|
||||||
switch (key) {
|
SubEditServerEvent event = new SubEditServerEvent(player, this, new ContainedPair<String, ObjectMapValue>(key, value));
|
||||||
case "name":
|
host.plugin.getPluginManager().callEvent(event);
|
||||||
if (value.isString() && host.removeSubServer(player, getName())) {
|
allowed = !event.isCancelled();
|
||||||
SubServer server = host.addSubServer(player, value.asRawString(), isEnabled(), getAddress().getPort(), getMotd(), isLogging(), getPath(), getExecutable(), getStopCommand(), isHidden(), isRestricted());
|
}
|
||||||
if (server != null) {
|
if (allowed) {
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
try {
|
||||||
YAMLSection config = this.host.plugin.config.get().getSection("Servers").getSection(getName());
|
switch (key.toLowerCase()) {
|
||||||
this.host.plugin.config.get().getSection("Servers").remove(getName());
|
case "name":
|
||||||
this.host.plugin.config.get().getSection("Servers").set(server.getName(), config);
|
if (value.isString() && host.removeSubServer(player, getName())) {
|
||||||
this.host.plugin.config.save();
|
SubServer server = host.constructSubServer(value.asString(), isEnabled(), getAddress().getPort(), getMotd(), isLogging(), getPath(), getExecutable(), getStopCommand(), isHidden(), isRestricted());
|
||||||
|
if (server != null) {
|
||||||
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
|
ObjectMap<String> config = this.host.plugin.servers.get().getMap("Servers").getMap(getName());
|
||||||
|
this.host.plugin.servers.get().getMap("Servers").remove(getName());
|
||||||
|
this.host.plugin.servers.get().getMap("Servers").set(server.getName(), config);
|
||||||
|
this.host.plugin.servers.save();
|
||||||
|
}
|
||||||
|
forward = server;
|
||||||
|
c++;
|
||||||
}
|
}
|
||||||
forward = server;
|
|
||||||
c++;
|
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
break;
|
case "display":
|
||||||
case "display":
|
if (value.isString()) {
|
||||||
if (value.isString()) {
|
setDisplayName(value.asString());
|
||||||
Field f = ServerContainer.class.getDeclaredField("nick");
|
logger.name = getDisplayName();
|
||||||
f.setAccessible(true);
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
if (value == null || value.asString().length() == 0 || getName().equals(value)) {
|
if (getName().equals(getDisplayName())) {
|
||||||
f.set(this, null);
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).remove("Display");
|
||||||
} else {
|
} else {
|
||||||
f.set(this, value.asString());
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Display", getDisplayName());
|
||||||
}
|
}
|
||||||
f.setAccessible(false);
|
this.host.plugin.servers.save();
|
||||||
logger.name = getDisplayName();
|
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
|
||||||
if (getName().equals(getDisplayName())) {
|
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).remove("Display");
|
|
||||||
} else {
|
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Display", getDisplayName());
|
|
||||||
}
|
|
||||||
this.host.plugin.config.save();
|
|
||||||
}
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "enabled":
|
|
||||||
if (value.isBoolean()) {
|
|
||||||
enabled = value.asBoolean();
|
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Enabled", isEnabled());
|
|
||||||
this.host.plugin.config.save();
|
|
||||||
}
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "group":
|
|
||||||
if (value.isList()) {
|
|
||||||
Util.reflect(ServerContainer.class.getDeclaredField("groups"), this, value.asStringList());
|
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Group", value.asStringList());
|
|
||||||
this.host.plugin.config.save();
|
|
||||||
}
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "host":
|
|
||||||
if (value.isString() && host.removeSubServer(player, getName())) {
|
|
||||||
SubServer server = this.host.plugin.api.getHost(value.asRawString()).addSubServer(player, getName(), isEnabled(), getAddress().getPort(), getMotd(), isLogging(), getPath(), getExecutable(), getStopCommand(), isHidden(), isRestricted());
|
|
||||||
if (server != null) {
|
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Host", server.getHost().getName());
|
|
||||||
this.host.plugin.config.save();
|
|
||||||
}
|
|
||||||
forward = server;
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "port":
|
|
||||||
if (value.isNumber() && host.removeSubServer(player, getName())) {
|
|
||||||
SubServer server = host.addSubServer(player, getName(), isEnabled(), value.asInt(), getMotd(), isLogging(), getPath(), getExecutable(), getStopCommand(), isHidden(), isRestricted());
|
|
||||||
if (server != null) {
|
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Port", server.getAddress().getPort());
|
|
||||||
this.host.plugin.config.save();
|
|
||||||
}
|
|
||||||
forward = server;
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "motd":
|
|
||||||
if (value.isString()) {
|
|
||||||
Util.reflect(BungeeServerInfo.class.getDeclaredField("motd"), this, value.asColoredString('&'));
|
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Motd", value.asString());
|
|
||||||
this.host.plugin.config.save();
|
|
||||||
}
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "log":
|
|
||||||
if (value.isBoolean()) {
|
|
||||||
log.set(value.asBoolean());
|
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Log", isLogging());
|
|
||||||
this.host.plugin.config.save();
|
|
||||||
}
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "dir":
|
|
||||||
if (value.isString()) {
|
|
||||||
if (isRunning()) {
|
|
||||||
stop(player);
|
|
||||||
waitFor();
|
|
||||||
}
|
|
||||||
dir = value.asRawString();
|
|
||||||
directory = new File(getHost().getPath(), value.asRawString());
|
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Directory", getPath());
|
|
||||||
this.host.plugin.config.save();
|
|
||||||
}
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "exec":
|
|
||||||
if (value.isString()) {
|
|
||||||
if (isRunning()) {
|
|
||||||
stop(player);
|
|
||||||
waitFor();
|
|
||||||
}
|
|
||||||
executable = value.asRawString();
|
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Executable", value.asRawString());
|
|
||||||
this.host.plugin.config.save();
|
|
||||||
}
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "stop-cmd":
|
|
||||||
if (value.isString()) {
|
|
||||||
stopcmd = value.asRawString();
|
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Stop-Command", getStopCommand());
|
|
||||||
this.host.plugin.config.save();
|
|
||||||
}
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "stop-action":
|
|
||||||
if (value.isString()) {
|
|
||||||
StopAction action = Util.getDespiteException(() -> StopAction.valueOf(value.asRawString().toUpperCase().replace('-', '_').replace(' ', '_')), null);
|
|
||||||
if (action != null) {
|
|
||||||
stopaction = action;
|
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Stop-Action", getStopAction().toString());
|
|
||||||
this.host.plugin.config.save();
|
|
||||||
}
|
}
|
||||||
c++;
|
c++;
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
break;
|
case "enabled":
|
||||||
case "state":
|
if (value.isBoolean()) {
|
||||||
if (value.isBoolean()) {
|
enabled = value.asBoolean();
|
||||||
state = value.asBoolean();
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
}
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Enabled", isEnabled());
|
||||||
break;
|
this.host.plugin.servers.save();
|
||||||
case "auto-run":
|
}
|
||||||
if (value.isBoolean()) {
|
c++;
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Run-On-Launch", value.asBoolean());
|
|
||||||
this.host.plugin.config.save();
|
|
||||||
}
|
}
|
||||||
c++;
|
break;
|
||||||
}
|
case "group":
|
||||||
break;
|
if (value.isList()) {
|
||||||
case "incompatible":
|
Util.reflect(ServerImpl.class.getDeclaredField("groups"), this, value.asStringList());
|
||||||
if (value.isList()) {
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
for (String oname : value.asStringList()) {
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Group", value.asStringList());
|
||||||
SubServer oserver = host.plugin.api.getSubServer(oname);
|
this.host.plugin.servers.save();
|
||||||
if (oserver != null && isCompatible(oserver)) toggleCompatibility(oserver);
|
}
|
||||||
|
c++;
|
||||||
}
|
}
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
break;
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Incompatible", value.asStringList());
|
case "host":
|
||||||
this.host.plugin.config.save();
|
if (value.isString() && host.removeSubServer(player, getName())) {
|
||||||
|
SubServer server = this.host.plugin.api.getHost(value.asString()).constructSubServer(getName(), isEnabled(), getAddress().getPort(), getMotd(), isLogging(), getPath(), getExecutable(), getStopCommand(), isHidden(), isRestricted());
|
||||||
|
if (server != null) {
|
||||||
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Host", server.getHost().getName());
|
||||||
|
this.host.plugin.servers.save();
|
||||||
|
}
|
||||||
|
forward = server;
|
||||||
|
c++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
c++;
|
break;
|
||||||
}
|
case "template":
|
||||||
break;
|
if (value.isString()) {
|
||||||
case "restricted":
|
setTemplate(value.asString());
|
||||||
if (value.isBoolean()) {
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
Util.reflect(BungeeServerInfo.class.getDeclaredField("restricted"), this, value.asBoolean());
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Template", value.asString());
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
this.host.plugin.servers.save();
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Restricted", isRestricted());
|
}
|
||||||
this.host.plugin.config.save();
|
c++;
|
||||||
}
|
}
|
||||||
c++;
|
break;
|
||||||
}
|
case "port":
|
||||||
break;
|
if (value.isNumber() && host.removeSubServer(player, getName())) {
|
||||||
case "hidden":
|
SubServer server = host.constructSubServer(getName(), isEnabled(), value.asInt(), getMotd(), isLogging(), getPath(), getExecutable(), getStopCommand(), isHidden(), isRestricted());
|
||||||
if (value.isBoolean()) {
|
if (server != null) {
|
||||||
Util.reflect(ServerContainer.class.getDeclaredField("hidden"), this, value.asBoolean());
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Port", server.getAddress().getPort());
|
||||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Hidden", isHidden());
|
this.host.plugin.servers.save();
|
||||||
this.host.plugin.config.save();
|
}
|
||||||
|
forward = server;
|
||||||
|
c++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
c++;
|
break;
|
||||||
}
|
case "motd":
|
||||||
break;
|
if (value.isString()) {
|
||||||
}
|
setMotd(ChatColor.translateAlternateColorCodes('&', Util.unescapeJavaString(value.asString())));
|
||||||
if (forward != null) {
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
forward.setStopAction(getStopAction());
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Motd", value.asString());
|
||||||
if (!getName().equals(getDisplayName())) forward.setDisplayName(getDisplayName());
|
this.host.plugin.servers.save();
|
||||||
List<String> groups = new ArrayList<String>();
|
}
|
||||||
groups.addAll(getGroups());
|
c++;
|
||||||
for (String group : groups) {
|
}
|
||||||
removeGroup(group);
|
break;
|
||||||
forward.addGroup(group);
|
case "log":
|
||||||
|
if (value.isBoolean()) {
|
||||||
|
log.value(value.asBoolean());
|
||||||
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Log", isLogging());
|
||||||
|
this.host.plugin.servers.save();
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "dir":
|
||||||
|
case "directory":
|
||||||
|
if (value.isString()) {
|
||||||
|
if (isRunning()) {
|
||||||
|
stop(player);
|
||||||
|
waitFor();
|
||||||
|
}
|
||||||
|
dir = value.asString();
|
||||||
|
directory = new File(getHost().getPath(), value.asString());
|
||||||
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Directory", getPath());
|
||||||
|
this.host.plugin.servers.save();
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "exec":
|
||||||
|
case "executable":
|
||||||
|
if (value.isString()) {
|
||||||
|
if (isRunning()) {
|
||||||
|
stop(player);
|
||||||
|
waitFor();
|
||||||
|
}
|
||||||
|
executable = value.asString();
|
||||||
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Executable", value.asString());
|
||||||
|
this.host.plugin.servers.save();
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "stop-cmd":
|
||||||
|
case "stop-command":
|
||||||
|
if (value.isString()) {
|
||||||
|
stopcmd = value.asString();
|
||||||
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Stop-Command", getStopCommand());
|
||||||
|
this.host.plugin.servers.save();
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "stop-action":
|
||||||
|
if (value.isString()) {
|
||||||
|
StopAction action = Try.all.get(() -> StopAction.valueOf(value.asString().toUpperCase().replace('-', '_').replace(' ', '_')));
|
||||||
|
if (action != null) {
|
||||||
|
stopaction = action;
|
||||||
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Stop-Action", getStopAction().toString());
|
||||||
|
this.host.plugin.servers.save();
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "state":
|
||||||
|
if (value.isBoolean()) {
|
||||||
|
state = value.asBoolean();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "auto-run":
|
||||||
|
case "run-on-launch":
|
||||||
|
if (value.isBoolean()) {
|
||||||
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Run-On-Launch", value.asBoolean());
|
||||||
|
this.host.plugin.servers.save();
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "incompatible":
|
||||||
|
if (value.isList()) {
|
||||||
|
for (SubServer oserver : getIncompatibilities()) toggleCompatibility(oserver);
|
||||||
|
for (String oname : (List<String>) value.asStringList()) {
|
||||||
|
SubServer oserver = host.plugin.api.getSubServer(oname);
|
||||||
|
if (oserver != null && isCompatible(oserver)) toggleCompatibility(oserver);
|
||||||
|
}
|
||||||
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Incompatible", value.asStringList());
|
||||||
|
this.host.plugin.servers.save();
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "restricted":
|
||||||
|
if (value.isBoolean()) {
|
||||||
|
setRestricted(value.asBoolean());
|
||||||
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Restricted", isRestricted());
|
||||||
|
this.host.plugin.servers.save();
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "hidden":
|
||||||
|
if (value.isBoolean()) {
|
||||||
|
setHidden(value.asBoolean());
|
||||||
|
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||||
|
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Hidden", isHidden());
|
||||||
|
this.host.plugin.servers.save();
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "whitelist":
|
||||||
|
if (value.isList()) {
|
||||||
|
Util.reflect(ServerImpl.class.getDeclaredField("whitelist"), this, value.asUUIDList());
|
||||||
|
if (isRegistered()) for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) {
|
||||||
|
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.WHITELIST_SET, value.asUUIDList()));
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
for (SubServer server : getIncompatibilities()) {
|
if (forward != null) {
|
||||||
toggleCompatibility(server);
|
forward.setStopAction(getStopAction());
|
||||||
forward.toggleCompatibility(server);
|
if (!getName().equals(getDisplayName())) forward.setDisplayName(getDisplayName());
|
||||||
}
|
forward.setTemplate(getTemplate());
|
||||||
for (String extra : getExtra().getKeys()) forward.addExtra(extra, getExtra(extra));
|
List<String> groups = new ArrayList<String>();
|
||||||
|
groups.addAll(getGroups());
|
||||||
|
for (String group : groups) {
|
||||||
|
removeGroup(group);
|
||||||
|
forward.addGroup(group);
|
||||||
|
}
|
||||||
|
for (SubServer server : getIncompatibilities()) {
|
||||||
|
toggleCompatibility(server);
|
||||||
|
forward.toggleCompatibility(server);
|
||||||
|
}
|
||||||
|
for (String extra : getExtra().getKeys()) forward.addExtra(extra, getExtra(extra));
|
||||||
|
forward.getHost().addSubServer(player, forward);
|
||||||
|
|
||||||
if (state) pending.set("state", true);
|
if (state) pending.set("state", true);
|
||||||
c += forward.edit(player, pending);
|
c += (perma)?forward.permaEdit(player, pending):forward.edit(player, pending);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (!isRunning() && forward == null && state) start(player);
|
||||||
if (!isRunning() && forward == null && state) start(player);
|
return c;
|
||||||
return c;
|
} else return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -509,7 +586,7 @@ public class InternalSubServer extends SubServerContainer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isRunning() {
|
public boolean isRunning() {
|
||||||
return process != null && process.isAlive();
|
return (process != null && process.isAlive()) || lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -525,26 +602,24 @@ public class InternalSubServer extends SubServerContainer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
return enabled;
|
return enabled && host.isEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setEnabled(boolean value) {
|
public void setEnabled(boolean value) {
|
||||||
if (Util.isNull(value)) throw new NullPointerException();
|
Util.nullpo(value);
|
||||||
host.plugin.getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer<String, Object>("enabled", value), false));
|
|
||||||
enabled = value;
|
enabled = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLogging() {
|
public boolean isLogging() {
|
||||||
return log.get();
|
return log.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setLogging(boolean value) {
|
public void setLogging(boolean value) {
|
||||||
if (Util.isNull(value)) throw new NullPointerException();
|
Util.nullpo(value);
|
||||||
host.plugin.getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer<String, Object>("log", value), false));
|
log.value(value);
|
||||||
log.set(value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -574,8 +649,7 @@ public class InternalSubServer extends SubServerContainer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setStopCommand(String value) {
|
public void setStopCommand(String value) {
|
||||||
if (Util.isNull(value)) throw new NullPointerException();
|
Util.nullpo(value);
|
||||||
host.plugin.getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer<String, Object>("stop-cmd", value), false));
|
|
||||||
stopcmd = value;
|
stopcmd = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -586,8 +660,7 @@ public class InternalSubServer extends SubServerContainer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setStopAction(StopAction action) {
|
public void setStopAction(StopAction action) {
|
||||||
if (Util.isNull(action)) throw new NullPointerException();
|
Util.nullpo(action);
|
||||||
host.plugin.getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer<String, Object>("stop-action", action), false));
|
|
||||||
stopaction = action;
|
stopaction = action;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
package net.ME1312.SubServers.Bungee.Host;
|
package net.ME1312.SubServers.Bungee.Host;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.ExtraDataHandler;
|
||||||
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
|
import net.ME1312.Galaxi.Library.Map.ObjectMapValue;
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
|
import net.ME1312.SubData.Server.ClientHandler;
|
||||||
|
import net.ME1312.SubData.Server.DataClient;
|
||||||
|
import net.ME1312.SubData.Server.SubDataClient;
|
||||||
import net.ME1312.SubServers.Bungee.Event.SubRemoveProxyEvent;
|
import net.ME1312.SubServers.Bungee.Event.SubRemoveProxyEvent;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExSyncPlayer;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLValue;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.ExtraDataHandler;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.NamedContainer;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.Client;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.ClientHandler;
|
|
||||||
import net.ME1312.SubServers.Bungee.SubAPI;
|
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||||
|
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
@ -17,39 +19,70 @@ import java.util.*;
|
||||||
/**
|
/**
|
||||||
* Proxy Class
|
* Proxy Class
|
||||||
*/
|
*/
|
||||||
public class Proxy implements ClientHandler, ExtraDataHandler {
|
public class Proxy implements ClientHandler, ExtraDataHandler<String> {
|
||||||
private YAMLSection extra = new YAMLSection();
|
private final HashMap<Integer, SubDataClient> subdata = new HashMap<Integer, SubDataClient>();
|
||||||
|
private final ObjectMap<String> extra = new ObjectMap<String>();
|
||||||
private final String signature;
|
private final String signature;
|
||||||
private boolean persistent = true;
|
private boolean persistent = false;
|
||||||
private Client client = null;
|
|
||||||
private String nick = null;
|
private String nick = null;
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public Proxy(String name) throws IllegalArgumentException {
|
public Proxy(String name) throws IllegalArgumentException {
|
||||||
if (name == null) {
|
if (name == null) name = Util.getNew(SubAPI.getInstance().getInternals().proxies.keySet(), () -> UUID.randomUUID().toString());
|
||||||
name = Util.getNew(SubAPI.getInstance().getInternals().proxies.keySet(), () -> UUID.randomUUID().toString());
|
|
||||||
persistent = false;
|
|
||||||
}
|
|
||||||
if (name.contains(" ")) throw new IllegalArgumentException("Proxy names cannot have spaces: " + name);
|
if (name.contains(" ")) throw new IllegalArgumentException("Proxy names cannot have spaces: " + name);
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.signature = SubAPI.getInstance().signAnonymousObject();
|
this.signature = SubAPI.getInstance().signAnonymousObject();
|
||||||
|
|
||||||
|
subdata.put(0, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Client getSubData() {
|
public DataClient[] getSubData() {
|
||||||
return client;
|
Integer[] keys = subdata.keySet().toArray(new Integer[0]);
|
||||||
|
DataClient[] channels = new DataClient[keys.length];
|
||||||
|
Arrays.sort(keys);
|
||||||
|
for (int i = 0; i < keys.length; ++i) channels[i] = subdata.get(keys[i]);
|
||||||
|
return channels;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public void setSubData(Client client) {
|
public void setSubData(SubDataClient client, int channel) {
|
||||||
this.client = client;
|
boolean update = false;
|
||||||
if (client == null && !persistent) {
|
if (channel < 0) throw new IllegalArgumentException("Subchannel ID cannot be less than zero");
|
||||||
ProxyServer.getInstance().getPluginManager().callEvent(new SubRemoveProxyEvent(this));
|
if (client != null || channel == 0) {
|
||||||
SubAPI.getInstance().getInternals().proxies.remove(getName().toLowerCase());
|
if (!subdata.containsKey(channel) || (channel == 0 && (client == null || subdata.get(channel) == null))) {
|
||||||
|
update = true;
|
||||||
|
subdata.put(channel, client);
|
||||||
|
if (client != null && (client.getHandler() == null || !equals(client.getHandler()))) client.setHandler(this);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
update = true;
|
||||||
|
subdata.remove(channel);
|
||||||
}
|
}
|
||||||
if (client != null && (client.getHandler() == null || !equals(client.getHandler()))) client.setHandler(this);
|
|
||||||
|
if (update) {
|
||||||
|
DataClient[] subdata = getSubData();
|
||||||
|
if (subdata[0] == null && subdata.length <= 1) {
|
||||||
|
SubProxy plugin = SubAPI.getInstance().getInternals();
|
||||||
|
for (UUID id : Util.getBackwards(plugin.rPlayerLinkP, this)) {
|
||||||
|
plugin.rPlayerLinkS.remove(id);
|
||||||
|
plugin.rPlayerLinkP.remove(id);
|
||||||
|
plugin.rPlayers.remove(id);
|
||||||
|
}
|
||||||
|
for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null && proxy != this) {
|
||||||
|
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketExSyncPlayer(getName(), null, (RemotePlayer[]) null));
|
||||||
|
}
|
||||||
|
if (!persistent) {
|
||||||
|
ProxyServer.getInstance().getPluginManager().callEvent(new SubRemoveProxyEvent(this));
|
||||||
|
SubAPI.getInstance().getInternals().proxies.remove(getName().toLowerCase());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeSubData(DataClient client) {
|
||||||
|
for (Integer channel : Util.getBackwards(subdata, (SubDataClient) client)) setSubData(null, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -84,34 +117,36 @@ public class Proxy implements ClientHandler, ExtraDataHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if the proxy is connected to RedisBungee's server
|
* Determine if the proxy is the Master Proxy
|
||||||
*
|
*
|
||||||
* @return Redis Status
|
* @return Master Proxy Status
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"deprecation", "unchecked"})
|
public boolean isMaster() {
|
||||||
public boolean isRedis() {
|
return SubAPI.getInstance().getMasterProxy() == this;
|
||||||
SubPlugin plugin = SubAPI.getInstance().getInternals();
|
|
||||||
return plugin.redis != null && Util.getDespiteException(() -> plugin.redis("getPlayersOnProxy", new NamedContainer<>(String.class, getName())) != null, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the players on this proxy (via RedisBungee)
|
* Get the players on this proxy
|
||||||
*
|
*
|
||||||
* @return Player Collection
|
* @return Remote Player Collection
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"deprecation", "unchecked"})
|
@SuppressWarnings("deprecation")
|
||||||
public Collection<NamedContainer<String, UUID>> getPlayers() {
|
public Collection<RemotePlayer> getPlayers() {
|
||||||
List<NamedContainer<String, UUID>> players = new ArrayList<NamedContainer<String, UUID>>();
|
SubProxy plugin = SubAPI.getInstance().getInternals();
|
||||||
SubPlugin plugin = SubAPI.getInstance().getInternals();
|
ArrayList<RemotePlayer> players = new ArrayList<RemotePlayer>();
|
||||||
if (plugin.redis != null) {
|
for (UUID id : Util.getBackwards(plugin.rPlayerLinkP, this)) {
|
||||||
try {
|
players.add(plugin.rPlayers.get(id));
|
||||||
for (UUID player : (Set<UUID>) plugin.redis("getPlayersOnProxy", new NamedContainer<>(String.class, getName())))
|
|
||||||
players.add(new NamedContainer<>((String) plugin.redis("getNameFromUuid", new NamedContainer<>(UUID.class, player)), player));
|
|
||||||
} catch (Exception e) {}
|
|
||||||
}
|
}
|
||||||
return players;
|
return players;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes it so the proxy object will still exist within the server manager even if it is disconnected
|
||||||
|
*/
|
||||||
|
public final void persist() {
|
||||||
|
persistent = true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the Signature of this Object
|
* Get the Signature of this Object
|
||||||
*
|
*
|
||||||
|
@ -121,52 +156,56 @@ public class Proxy implements ClientHandler, ExtraDataHandler {
|
||||||
return signature;
|
return signature;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return obj instanceof Proxy && signature.equals(((Proxy) obj).signature);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addExtra(String handle, Object value) {
|
public void addExtra(String handle, Object value) {
|
||||||
if (Util.isNull(handle, value)) throw new NullPointerException();
|
Util.nullpo(handle, value);
|
||||||
extra.set(handle, value);
|
extra.set(handle, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasExtra(String handle) {
|
public boolean hasExtra(String handle) {
|
||||||
if (Util.isNull(handle)) throw new NullPointerException();
|
Util.nullpo(handle);
|
||||||
return extra.getKeys().contains(handle);
|
return extra.getKeys().contains(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public YAMLValue getExtra(String handle) {
|
public ObjectMapValue getExtra(String handle) {
|
||||||
if (Util.isNull(handle)) throw new NullPointerException();
|
Util.nullpo(handle);
|
||||||
return extra.get(handle);
|
return extra.get(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public YAMLSection getExtra() {
|
public ObjectMap<String> getExtra() {
|
||||||
return extra.clone();
|
return extra.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeExtra(String handle) {
|
public void removeExtra(String handle) {
|
||||||
if (Util.isNull(handle)) throw new NullPointerException();
|
Util.nullpo(handle);
|
||||||
extra.remove(handle);
|
extra.remove(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public ObjectMap<String> forSubData() {
|
||||||
YAMLSection info = new YAMLSection();
|
ObjectMap<String> info = new ObjectMap<String>();
|
||||||
info.set("type", "Proxy");
|
info.set("type", "Proxy");
|
||||||
info.set("name", getName());
|
info.set("name", getName());
|
||||||
info.set("display", getDisplayName());
|
info.set("display", getDisplayName());
|
||||||
YAMLSection players = new YAMLSection();
|
ObjectMap<String> players = new ObjectMap<String>();
|
||||||
for (NamedContainer<String, UUID> player : getPlayers()) {
|
for (RemotePlayer player : getPlayers())
|
||||||
YAMLSection pinfo = new YAMLSection();
|
players.set(player.getUniqueId().toString(), player.getName());
|
||||||
pinfo.set("name", player.name());
|
|
||||||
players.set(player.get().toString(), pinfo);
|
|
||||||
}
|
|
||||||
info.set("players", players);
|
info.set("players", players);
|
||||||
info.set("redis", isRedis());
|
info.set("master", isMaster());
|
||||||
if (getSubData() != null) info.set("subdata", getSubData().getAddress().toString());
|
ObjectMap<Integer> subdata = new ObjectMap<Integer>();
|
||||||
|
for (int channel : this.subdata.keySet()) subdata.set(channel, (this.subdata.get(channel) == null)?null:this.subdata.get(channel).getID());
|
||||||
|
info.set("subdata", subdata);
|
||||||
info.set("signature", signature);
|
info.set("signature", signature);
|
||||||
info.set("extra", getExtra());
|
info.set("extra", getExtra());
|
||||||
return info.toJSON();
|
return info;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,314 @@
|
||||||
|
package net.ME1312.SubServers.Bungee.Host;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Container.ContainedPair;
|
||||||
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
|
import net.ME1312.SubData.Server.SubDataClient;
|
||||||
|
import net.ME1312.SubData.Server.SubDataSerializable;
|
||||||
|
import net.ME1312.SubServers.Bungee.Library.Compatibility.RPSI;
|
||||||
|
import net.ME1312.SubServers.Bungee.Network.Packet.PacketDisconnectPlayer;
|
||||||
|
import net.ME1312.SubServers.Bungee.Network.Packet.PacketMessagePlayer;
|
||||||
|
import net.ME1312.SubServers.Bungee.Network.Packet.PacketTransferPlayer;
|
||||||
|
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
import net.md_5.bungee.api.chat.BaseComponent;
|
||||||
|
import net.md_5.bungee.api.config.ServerInfo;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.function.IntConsumer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remote Player Class
|
||||||
|
*/
|
||||||
|
public class RemotePlayer implements net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer, SubDataSerializable {
|
||||||
|
private ProxiedPlayer local;
|
||||||
|
private UUID id;
|
||||||
|
private String name;
|
||||||
|
private InetSocketAddress ip;
|
||||||
|
private Proxy proxy;
|
||||||
|
private Server server;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translate a Local Player to a Remote Player
|
||||||
|
*
|
||||||
|
* @param player Local Player
|
||||||
|
*/
|
||||||
|
public RemotePlayer(ProxiedPlayer player) {
|
||||||
|
this(player, player.getServer().getInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translate a Local Player to a Remote Player
|
||||||
|
*
|
||||||
|
* @param player Local Player
|
||||||
|
* @param server Server the player is on
|
||||||
|
*/
|
||||||
|
public RemotePlayer(ProxiedPlayer player, ServerInfo server) {
|
||||||
|
Util.nullpo(player);
|
||||||
|
this.local = player;
|
||||||
|
this.id = player.getUniqueId();
|
||||||
|
this.server = (server instanceof Server)? (Server) server : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search for a Remote Player using their ID
|
||||||
|
*
|
||||||
|
* @param name Player Name
|
||||||
|
* @param id Player UUID
|
||||||
|
* @param proxy Proxy the player is on
|
||||||
|
* @param server Server the player is on
|
||||||
|
* @param ip Player IP Address
|
||||||
|
*/
|
||||||
|
public RemotePlayer(String name, UUID id, Proxy proxy, ServerInfo server, InetSocketAddress ip) {
|
||||||
|
Util.nullpo(name, id, proxy, ip);
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.ip = ip;
|
||||||
|
this.proxy = proxy;
|
||||||
|
this.server = (server instanceof Server)? (Server) server : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProxiedPlayer get() {
|
||||||
|
return local;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ProxiedPlayer get(UUID player) {
|
||||||
|
return ProxyServer.getInstance().getPlayer(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UUID getUniqueId() {
|
||||||
|
if (local != null) {
|
||||||
|
return local.getUniqueId();
|
||||||
|
} else return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
if (local != null) {
|
||||||
|
return local.getName();
|
||||||
|
} else return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Override
|
||||||
|
public InetSocketAddress getAddress() {
|
||||||
|
if (local != null) {
|
||||||
|
return local.getAddress();
|
||||||
|
} else return ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the proxy this player is connected to.
|
||||||
|
*
|
||||||
|
* @return the proxy this player is connected to
|
||||||
|
*/
|
||||||
|
public Proxy getProxy() {
|
||||||
|
if (local != null) {
|
||||||
|
return SubAPI.getInstance().getMasterProxy();
|
||||||
|
} else return proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getProxyName() {
|
||||||
|
Proxy proxy = getProxy();
|
||||||
|
return (proxy == null)? null : proxy.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
private SubDataClient getProxyConnection() {
|
||||||
|
Proxy proxy = getProxy();
|
||||||
|
return (proxy == null)? null : (SubDataClient) proxy.getSubData()[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Server getServer() {
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getServerName() {
|
||||||
|
Server server = getServer();
|
||||||
|
return (server == null)? null : server.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return obj instanceof RemotePlayer && getUniqueId().equals(((RemotePlayer) obj).getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObjectMap<String> forSubData() {
|
||||||
|
ObjectMap<String> pinfo = new ObjectMap<String>();
|
||||||
|
pinfo.set("name", getName());
|
||||||
|
pinfo.set("id", getUniqueId());
|
||||||
|
pinfo.set("address", getAddress().getAddress().getHostAddress() + ':' + getAddress().getPort());
|
||||||
|
if (getServer() != null) pinfo.set("server", getServer().getName());
|
||||||
|
if (getProxy() != null) pinfo.set("proxy", getProxy().getName());
|
||||||
|
return pinfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
// These overrides provide for the static methods in BungeeCommon
|
||||||
|
new RPSI() {
|
||||||
|
@Override
|
||||||
|
protected void sendMessage(UUID[] players, String[] messages, IntConsumer response) {
|
||||||
|
StackTraceElement[] origin = new Throwable().getStackTrace();
|
||||||
|
PacketMessagePlayer.run(Arrays.asList(players), new ContainedPair<>(messages, null), null, i -> {
|
||||||
|
try {
|
||||||
|
response.accept(i);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Throwable ew = new InvocationTargetException(e);
|
||||||
|
ew.setStackTrace(origin);
|
||||||
|
ew.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void sendMessage(UUID[] players, BaseComponent[][] messages, IntConsumer response) {
|
||||||
|
StackTraceElement[] origin = new Throwable().getStackTrace();
|
||||||
|
PacketMessagePlayer.run(Arrays.asList(players), new ContainedPair<>(null, messages), null, i -> {
|
||||||
|
try {
|
||||||
|
response.accept(i);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Throwable ew = new InvocationTargetException(e);
|
||||||
|
ew.setStackTrace(origin);
|
||||||
|
ew.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void transfer(UUID[] players, String server, IntConsumer response) {
|
||||||
|
StackTraceElement[] origin = new Throwable().getStackTrace();
|
||||||
|
PacketTransferPlayer.run(Arrays.asList(players), server, i -> {
|
||||||
|
try {
|
||||||
|
response.accept(i);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Throwable ew = new InvocationTargetException(e);
|
||||||
|
ew.setStackTrace(origin);
|
||||||
|
ew.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void disconnect(UUID[] players, String reason, IntConsumer response) {
|
||||||
|
StackTraceElement[] origin = new Throwable().getStackTrace();
|
||||||
|
PacketDisconnectPlayer.run(Arrays.asList(players), reason, i -> {
|
||||||
|
try {
|
||||||
|
response.accept(i);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Throwable ew = new InvocationTargetException(e);
|
||||||
|
ew.setStackTrace(origin);
|
||||||
|
ew.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// The following methods all redirect to their BungeeCommon counterparts
|
||||||
|
public static void broadcastMessage(String... messages) {
|
||||||
|
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.broadcastMessage(messages);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void broadcastMessage(String message, IntConsumer response) {
|
||||||
|
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.broadcastMessage(message, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void broadcastMessage(String[] messages, IntConsumer response) {
|
||||||
|
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.broadcastMessage(messages, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendMessage(UUID[] players, String... messages) {
|
||||||
|
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.sendMessage(players, messages);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendMessage(UUID[] players, String message, IntConsumer response) {
|
||||||
|
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.sendMessage(players, message, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendMessage(UUID[] players, String[] messages, IntConsumer response) {
|
||||||
|
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.sendMessage(players, messages, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void broadcastMessage(BaseComponent... message) {
|
||||||
|
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.broadcastMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void broadcastMessage(BaseComponent message, IntConsumer response) {
|
||||||
|
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.broadcastMessage(message, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void broadcastMessage(BaseComponent[] message, IntConsumer response) {
|
||||||
|
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.broadcastMessage(message, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void broadcastMessage(BaseComponent[]... messages) {
|
||||||
|
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.broadcastMessage(messages);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void broadcastMessage(BaseComponent[][] messages, IntConsumer response) {
|
||||||
|
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.broadcastMessage(messages, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendMessage(UUID[] players, BaseComponent... message) {
|
||||||
|
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.sendMessage(players, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendMessage(UUID[] players, BaseComponent message, IntConsumer response) {
|
||||||
|
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.sendMessage(players, message, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendMessage(UUID[] players, BaseComponent[] message, IntConsumer response) {
|
||||||
|
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.sendMessage(players, message, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendMessage(UUID[] players, BaseComponent[]... messages) {
|
||||||
|
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.sendMessage(players, messages);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendMessage(UUID[] players, BaseComponent[][] messages, IntConsumer response) {
|
||||||
|
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.sendMessage(players, messages, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void transfer(UUID[] players, String server) {
|
||||||
|
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.transfer(players, server);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void transfer(UUID[] players, String server, IntConsumer response) {
|
||||||
|
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.transfer(players, server, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void transfer(UUID[] players, ServerInfo server) {
|
||||||
|
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.transfer(players, server);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void transfer(UUID[] players, ServerInfo server, IntConsumer response) {
|
||||||
|
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.transfer(players, server, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void disconnect(UUID... players) {
|
||||||
|
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.disconnect(players);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void disconnect(UUID[] players, IntConsumer response) {
|
||||||
|
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.disconnect(players, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void disconnect(UUID[] players, String reason) {
|
||||||
|
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.disconnect(players, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void disconnect(UUID[] players, String reason, IntConsumer response) {
|
||||||
|
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.disconnect(players, reason, response);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,9 @@
|
||||||
package net.ME1312.SubServers.Bungee.Host;
|
package net.ME1312.SubServers.Bungee.Host;
|
||||||
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.ExtraDataHandler;
|
import net.ME1312.Galaxi.Library.ExtraDataHandler;
|
||||||
import net.ME1312.SubServers.Bungee.Library.NamedContainer;
|
import net.ME1312.SubData.Server.ClientHandler;
|
||||||
import net.ME1312.SubServers.Bungee.Network.ClientHandler;
|
import net.ME1312.SubData.Server.DataClient;
|
||||||
|
|
||||||
import net.md_5.bungee.api.config.ServerInfo;
|
import net.md_5.bungee.api.config.ServerInfo;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -12,7 +13,15 @@ import java.util.UUID;
|
||||||
/**
|
/**
|
||||||
* Server Interface
|
* Server Interface
|
||||||
*/
|
*/
|
||||||
public interface Server extends ServerInfo, ClientHandler, ExtraDataHandler {
|
public interface Server extends ServerInfo, ClientHandler, ExtraDataHandler<String> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Link a SubData Client to this Object
|
||||||
|
*
|
||||||
|
* @param client Client to Link
|
||||||
|
* @param channel Channel ID
|
||||||
|
*/
|
||||||
|
void setSubData(DataClient client, int channel);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the Display Name of this Server
|
* Get the Display Name of this Server
|
||||||
|
@ -49,12 +58,40 @@ public interface Server extends ServerInfo, ClientHandler, ExtraDataHandler {
|
||||||
*/
|
*/
|
||||||
void removeGroup(String value);
|
void removeGroup(String value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Commands the Server
|
||||||
|
*
|
||||||
|
* @param player Player who's Commanding
|
||||||
|
* @param target Player who will Send
|
||||||
|
* @param command Command to Send
|
||||||
|
*/
|
||||||
|
boolean command(UUID player, UUID target, String command);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Commands the Server
|
||||||
|
*
|
||||||
|
* @param player Player who's Commanding
|
||||||
|
* @param command Command to Send
|
||||||
|
*/
|
||||||
|
default boolean command(UUID player, String command) {
|
||||||
|
return command(player, null, command);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Commands the Server
|
||||||
|
*
|
||||||
|
* @param command Command to Send
|
||||||
|
*/
|
||||||
|
default boolean command(String command) {
|
||||||
|
return command(null, command);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get players on this server across all known proxies
|
* Get players on this server across all known proxies
|
||||||
*
|
*
|
||||||
* @return Player Collection
|
* @return Remote Player Collection
|
||||||
*/
|
*/
|
||||||
Collection<NamedContainer<String, UUID>> getGlobalPlayers();
|
Collection<RemotePlayer> getRemotePlayers();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the server is hidden from players
|
* If the server is hidden from players
|
||||||
|
@ -127,6 +164,11 @@ public interface Server extends ServerInfo, ClientHandler, ExtraDataHandler {
|
||||||
*/
|
*/
|
||||||
void unwhitelist(UUID player);
|
void unwhitelist(UUID player);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes it so the server object will still exist within the server manager even if it is disconnected
|
||||||
|
*/
|
||||||
|
void persist();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the Signature of this Object
|
* Get the Signature of this Object
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,247 +0,0 @@
|
||||||
package net.ME1312.SubServers.Bungee.Host;
|
|
||||||
|
|
||||||
import net.ME1312.SubServers.Bungee.Event.SubEditServerEvent;
|
|
||||||
import net.ME1312.SubServers.Bungee.Event.SubNetworkConnectEvent;
|
|
||||||
import net.ME1312.SubServers.Bungee.Event.SubNetworkDisconnectEvent;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLValue;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.NamedContainer;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.Client;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutExUpdateWhitelist;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutRunEvent;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.SubDataServer;
|
|
||||||
import net.ME1312.SubServers.Bungee.SubAPI;
|
|
||||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
|
||||||
import net.md_5.bungee.BungeeServerInfo;
|
|
||||||
import net.md_5.bungee.api.CommandSender;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Server Class
|
|
||||||
*/
|
|
||||||
public class ServerContainer extends BungeeServerInfo implements Server {
|
|
||||||
private YAMLSection extra = new YAMLSection();
|
|
||||||
private Client client = null;
|
|
||||||
private String nick = null;
|
|
||||||
private List<String> groups = new ArrayList<String>();
|
|
||||||
private List<UUID> whitelist = new ArrayList<UUID>();
|
|
||||||
private boolean hidden;
|
|
||||||
private final String signature;
|
|
||||||
|
|
||||||
public ServerContainer(String name, InetSocketAddress address, String motd, boolean hidden, boolean restricted) throws InvalidServerException {
|
|
||||||
super(name, address, motd, restricted);
|
|
||||||
if (Util.isNull(name, address, motd, hidden, restricted)) throw new NullPointerException();
|
|
||||||
if (name.contains(" ")) throw new InvalidServerException("Server names cannot have spaces: " + name);
|
|
||||||
signature = SubAPI.getInstance().signAnonymousObject();
|
|
||||||
SubDataServer.allowConnection(getAddress().getAddress().getHostAddress());
|
|
||||||
this.hidden = hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Client getSubData() {
|
|
||||||
return client;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSubData(Client client) {
|
|
||||||
this.client = client;
|
|
||||||
for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData() != null) {
|
|
||||||
YAMLSection args = new YAMLSection();
|
|
||||||
args.set("server", getName());
|
|
||||||
if (client != null) args.set("address", client.getAddress().toString());
|
|
||||||
proxy.getSubData().sendPacket(new PacketOutRunEvent((client != null)?SubNetworkConnectEvent.class:SubNetworkDisconnectEvent.class, args));
|
|
||||||
}
|
|
||||||
if (client != null && (client.getHandler() == null || !equals(client.getHandler()))) client.setHandler(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getDisplayName() {
|
|
||||||
return (nick == null)?getName():nick;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public void setDisplayName(String value) {
|
|
||||||
if (value == null || value.length() == 0 || getName().equals(value)) {
|
|
||||||
SubAPI.getInstance().getInternals().getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer<String, Object>("display", getName()), false));
|
|
||||||
this.nick = null;
|
|
||||||
} else {
|
|
||||||
SubAPI.getInstance().getInternals().getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer<String, Object>("display", value), false));
|
|
||||||
this.nick = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getGroups() {
|
|
||||||
return groups;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public void addGroup(String value) {
|
|
||||||
if (Util.isNull(value)) throw new NullPointerException();
|
|
||||||
if (value.length() > 0 && !groups.contains(value)) {
|
|
||||||
groups.add(value);
|
|
||||||
Collections.sort(groups);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public void removeGroup(String value) {
|
|
||||||
if (Util.isNull(value)) throw new NullPointerException();
|
|
||||||
groups.remove(value);
|
|
||||||
Collections.sort(groups);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings({"deprecation", "unchecked"})
|
|
||||||
@Override
|
|
||||||
public Collection<NamedContainer<String, UUID>> getGlobalPlayers() {
|
|
||||||
List<NamedContainer<String, UUID>> players = new ArrayList<NamedContainer<String, UUID>>();
|
|
||||||
SubPlugin plugin = SubAPI.getInstance().getInternals();
|
|
||||||
if (plugin.redis != null) {
|
|
||||||
try {
|
|
||||||
for (UUID player : (Set<UUID>) plugin.redis("getPlayersOnServer", new NamedContainer<>(String.class, getName()))) players.add(new NamedContainer<>((String) plugin.redis("getNameFromUuid", new NamedContainer<>(UUID.class, player)), player));
|
|
||||||
} catch (Exception e) {}
|
|
||||||
} else {
|
|
||||||
for (ProxiedPlayer player : getPlayers()) players.add(new NamedContainer<>(player.getName(), player.getUniqueId()));
|
|
||||||
}
|
|
||||||
return players;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isHidden() {
|
|
||||||
return hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public void setHidden(boolean value) {
|
|
||||||
if (Util.isNull(value)) throw new NullPointerException();
|
|
||||||
SubAPI.getInstance().getInternals().getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer<String, Object>("hidden", value), false));
|
|
||||||
this.hidden = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public void setMotd(String value) {
|
|
||||||
if (Util.isNull(value)) throw new NullPointerException();
|
|
||||||
SubAPI.getInstance().getInternals().getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer<String, Object>("motd", value), false));
|
|
||||||
try {
|
|
||||||
Util.reflect(BungeeServerInfo.class.getDeclaredField("motd"), this, value);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public void setRestricted(boolean value) {
|
|
||||||
if (Util.isNull(value)) throw new NullPointerException();
|
|
||||||
SubAPI.getInstance().getInternals().getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer<String, Object>("restricted", value), false));
|
|
||||||
try {
|
|
||||||
Util.reflect(BungeeServerInfo.class.getDeclaredField("restricted"), this, value);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<UUID> getWhitelist() {
|
|
||||||
return new ArrayList<UUID>(whitelist);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* See if a player can access this server
|
|
||||||
*
|
|
||||||
* @param player Player
|
|
||||||
* @return Whitelisted Status
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean canAccess(CommandSender player) {
|
|
||||||
return (player instanceof ProxiedPlayer && whitelist.contains(((ProxiedPlayer) player).getUniqueId())) || super.canAccess(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isWhitelisted(UUID player) {
|
|
||||||
return whitelist.contains(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void whitelist(UUID player) {
|
|
||||||
if (Util.isNull(player)) throw new NullPointerException();
|
|
||||||
whitelist.add(player);
|
|
||||||
for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData() != null) proxy.getSubData().sendPacket(new PacketOutExUpdateWhitelist(getName(), true, player));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void unwhitelist(UUID player) {
|
|
||||||
if (Util.isNull(player)) throw new NullPointerException();
|
|
||||||
whitelist.remove(player);
|
|
||||||
for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData() != null) proxy.getSubData().sendPacket(new PacketOutExUpdateWhitelist(getName(), false, player));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final String getSignature() {
|
|
||||||
return signature;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addExtra(String handle, Object value) {
|
|
||||||
if (Util.isNull(handle, value)) throw new NullPointerException();
|
|
||||||
extra.set(handle, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasExtra(String handle) {
|
|
||||||
if (Util.isNull(handle)) throw new NullPointerException();
|
|
||||||
return extra.getKeys().contains(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public YAMLValue getExtra(String handle) {
|
|
||||||
if (Util.isNull(handle)) throw new NullPointerException();
|
|
||||||
return extra.get(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public YAMLSection getExtra() {
|
|
||||||
return extra.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeExtra(String handle) {
|
|
||||||
if (Util.isNull(handle)) throw new NullPointerException();
|
|
||||||
extra.remove(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
YAMLSection info = new YAMLSection();
|
|
||||||
info.set("type", "Server");
|
|
||||||
info.set("name", getName());
|
|
||||||
info.set("display", getDisplayName());
|
|
||||||
info.set("group", getGroups());
|
|
||||||
info.set("address", getAddress().getAddress().getHostAddress() + ':' + getAddress().getPort());
|
|
||||||
info.set("motd", getMotd());
|
|
||||||
info.set("whitelist", whitelist);
|
|
||||||
info.set("restricted", isRestricted());
|
|
||||||
info.set("hidden", isHidden());
|
|
||||||
if (getSubData() != null) info.set("subdata", getSubData().getAddress().toString());
|
|
||||||
YAMLSection players = new YAMLSection();
|
|
||||||
for (NamedContainer<String, UUID> player : getGlobalPlayers()) {
|
|
||||||
YAMLSection pinfo = new YAMLSection();
|
|
||||||
pinfo.set("name", player.name());
|
|
||||||
players.set(player.get().toString(), pinfo);
|
|
||||||
}
|
|
||||||
info.set("players", players);
|
|
||||||
if (getSubData() != null) info.set("subdata", getSubData().getAddress().toString());
|
|
||||||
info.set("signature", signature);
|
|
||||||
info.set("extra", getExtra());
|
|
||||||
return info.toJSON();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,344 @@
|
||||||
|
package net.ME1312.SubServers.Bungee.Host;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
|
import net.ME1312.Galaxi.Library.Map.ObjectMapValue;
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
|
import net.ME1312.SubData.Server.DataClient;
|
||||||
|
import net.ME1312.SubData.Server.SubDataClient;
|
||||||
|
import net.ME1312.SubServers.Bungee.Event.SubSendCommandEvent;
|
||||||
|
import net.ME1312.SubServers.Bungee.Host.SubServer.LoggedCommand;
|
||||||
|
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
||||||
|
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExControlPlayer;
|
||||||
|
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutExEditServer;
|
||||||
|
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutExEditServer.Edit;
|
||||||
|
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||||
|
|
||||||
|
import net.md_5.bungee.BungeeServerInfo;
|
||||||
|
import net.md_5.bungee.api.CommandSender;
|
||||||
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.SocketAddress;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server Class
|
||||||
|
*/
|
||||||
|
public class ServerImpl extends BungeeServerInfo implements Server {
|
||||||
|
private HashMap<Integer, SubDataClient> subdata = new HashMap<Integer, SubDataClient>();
|
||||||
|
private ObjectMap<String> extra = new ObjectMap<String>();
|
||||||
|
private String nick = null;
|
||||||
|
private List<String> groups = new ArrayList<String>();
|
||||||
|
private List<UUID> whitelist = new ArrayList<UUID>();
|
||||||
|
private boolean hidden;
|
||||||
|
private final String signature = SubAPI.getInstance().signAnonymousObject();
|
||||||
|
private volatile boolean persistent = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a new Server data type
|
||||||
|
*
|
||||||
|
* @param name Server name
|
||||||
|
* @param address Server Address
|
||||||
|
* @param motd Server MOTD
|
||||||
|
* @param hidden Hidden Status
|
||||||
|
* @param restricted Restricted Status
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static ServerImpl construct(String name, SocketAddress address, String motd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||||
|
try {
|
||||||
|
return new ServerImpl(name, address, motd, hidden, restricted);
|
||||||
|
} catch (NoSuchMethodError e) {
|
||||||
|
return new ServerImpl(name, (InetSocketAddress) address, motd, hidden, restricted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Super Method 2 (newest)
|
||||||
|
* @see #construct(String, SocketAddress, String, boolean, boolean) for method details
|
||||||
|
*/
|
||||||
|
protected ServerImpl(String name, SocketAddress address, String motd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||||
|
super(name, address, motd, restricted);
|
||||||
|
init(name, address, motd, hidden, restricted);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Super Method 1 (oldest)
|
||||||
|
* @see #construct(String, SocketAddress, String, boolean, boolean) for method details
|
||||||
|
*/
|
||||||
|
protected ServerImpl(String name, InetSocketAddress address, String motd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||||
|
super(name, address, motd, restricted);
|
||||||
|
init(name, address, motd, hidden, restricted);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
private void init(String name, SocketAddress address, String motd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||||
|
Util.nullpo(name, address, motd, hidden, restricted);
|
||||||
|
if (name.contains(" ")) throw new InvalidServerException("Server names cannot have spaces: " + name);
|
||||||
|
SubAPI.getInstance().getInternals().subprotocol.whitelist(getAddress().getAddress().getHostAddress());
|
||||||
|
this.hidden = hidden;
|
||||||
|
|
||||||
|
subdata.put(0, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if this server has been registered
|
||||||
|
*
|
||||||
|
* @return Registered status
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
protected boolean isRegistered() {
|
||||||
|
return SubAPI.getInstance().getInternals().exServers.containsKey(getName().toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataClient[] getSubData() {
|
||||||
|
Integer[] keys = subdata.keySet().toArray(new Integer[0]);
|
||||||
|
DataClient[] channels = new DataClient[keys.length];
|
||||||
|
Arrays.sort(keys);
|
||||||
|
for (int i = 0; i < keys.length; ++i) channels[i] = subdata.get(keys[i]);
|
||||||
|
return channels;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubData(DataClient client, int channel) {
|
||||||
|
boolean update = false;
|
||||||
|
if (channel < 0) throw new IllegalArgumentException("Subchannel ID cannot be less than zero");
|
||||||
|
if (client != null || channel == 0) {
|
||||||
|
if (!subdata.containsKey(channel) || (channel == 0 && (client == null || subdata.get(channel) == null))) {
|
||||||
|
update = true;
|
||||||
|
subdata.put(channel, (SubDataClient) client);
|
||||||
|
if (client != null && (client.getHandler() == null || !equals(client.getHandler()))) ((SubDataClient) client).setHandler(this);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
update = true;
|
||||||
|
subdata.remove(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (update) {
|
||||||
|
for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) {
|
||||||
|
if (client != null) {
|
||||||
|
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.CONNECTED, channel, client.getID()));
|
||||||
|
} else {
|
||||||
|
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.DISCONNECTED, channel));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!persistent) {
|
||||||
|
DataClient[] subdata = getSubData();
|
||||||
|
if (subdata[0] == null && subdata.length <= 1) {
|
||||||
|
SubAPI.getInstance().removeServer(getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeSubData(DataClient client) {
|
||||||
|
for (Integer channel : Util.getBackwards(subdata, (SubDataClient) client)) setSubData(null, channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDisplayName() {
|
||||||
|
return (nick == null)?getName():nick;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public void setDisplayName(String value) {
|
||||||
|
if (value == null || value.length() == 0 || getName().equals(value)) {
|
||||||
|
this.nick = null;
|
||||||
|
} else {
|
||||||
|
this.nick = value;
|
||||||
|
}
|
||||||
|
for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) {
|
||||||
|
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.DISPLAY_NAME, getDisplayName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getGroups() {
|
||||||
|
return groups;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public void addGroup(String value) {
|
||||||
|
Util.nullpo(value);
|
||||||
|
if (value.length() > 0 && !groups.contains(value)) {
|
||||||
|
groups.add(value);
|
||||||
|
Collections.sort(groups);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public void removeGroup(String value) {
|
||||||
|
Util.nullpo(value);
|
||||||
|
groups.remove(value);
|
||||||
|
Collections.sort(groups);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean command(UUID player, UUID target, String command) {
|
||||||
|
Util.nullpo(command);
|
||||||
|
SubDataClient channel = (SubDataClient) getSubData()[0];
|
||||||
|
if (channel != null) {
|
||||||
|
SubSendCommandEvent event = new SubSendCommandEvent(player, this, command, target);
|
||||||
|
ProxyServer.getInstance().getPluginManager().callEvent(event);
|
||||||
|
if (!event.isCancelled() && (player == null || !SubServerImpl.DISALLOWED_COMMANDS.matcher(command).find())) {
|
||||||
|
channel.sendPacket(new PacketExControlPlayer(target, command));
|
||||||
|
return true;
|
||||||
|
} else return false;
|
||||||
|
} else return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<RemotePlayer> getRemotePlayers() {
|
||||||
|
return SubAPI.getInstance().getRemotePlayers(this).values();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isHidden() {
|
||||||
|
return hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHidden(boolean value) {
|
||||||
|
this.hidden = value;
|
||||||
|
if (isRegistered()) for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) {
|
||||||
|
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.HIDDEN, isHidden()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMotd(String value) {
|
||||||
|
Util.nullpo(value);
|
||||||
|
try {
|
||||||
|
Util.reflect(BungeeServerInfo.class.getDeclaredField("motd"), this, value);
|
||||||
|
for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) {
|
||||||
|
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.MOTD, getMotd()));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRestricted(boolean value) {
|
||||||
|
Util.nullpo(value);
|
||||||
|
try {
|
||||||
|
Util.reflect(BungeeServerInfo.class.getDeclaredField("restricted"), this, value);
|
||||||
|
|
||||||
|
if (isRegistered()) for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) {
|
||||||
|
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.RESTRICTED, isRestricted()));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See if a player can access this server
|
||||||
|
*
|
||||||
|
* @param player Player
|
||||||
|
* @return Whitelisted Status
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean canAccess(CommandSender player) {
|
||||||
|
return super.canAccess(player) || (player instanceof ProxiedPlayer && whitelist.contains(((ProxiedPlayer) player).getUniqueId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<UUID> getWhitelist() {
|
||||||
|
return new ArrayList<UUID>(whitelist);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWhitelisted(UUID player) {
|
||||||
|
return whitelist.contains(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void whitelist(UUID player) {
|
||||||
|
Util.nullpo(player);
|
||||||
|
if (!whitelist.contains(player)) whitelist.add(player);
|
||||||
|
if (isRegistered()) for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) {
|
||||||
|
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.WHITELIST_ADD, player));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unwhitelist(UUID player) {
|
||||||
|
Util.nullpo(player);
|
||||||
|
whitelist.remove(player);
|
||||||
|
if (isRegistered()) for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) {
|
||||||
|
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.WHITELIST_REMOVE, player));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void persist() {
|
||||||
|
persistent = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final String getSignature() {
|
||||||
|
return signature;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return obj instanceof ServerImpl && signature.equals(((ServerImpl) obj).signature);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addExtra(String handle, Object value) {
|
||||||
|
Util.nullpo(handle, value);
|
||||||
|
extra.set(handle, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasExtra(String handle) {
|
||||||
|
Util.nullpo(handle);
|
||||||
|
return extra.getKeys().contains(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObjectMapValue getExtra(String handle) {
|
||||||
|
Util.nullpo(handle);
|
||||||
|
return extra.get(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObjectMap<String> getExtra() {
|
||||||
|
return extra.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeExtra(String handle) {
|
||||||
|
Util.nullpo(handle);
|
||||||
|
extra.remove(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObjectMap<String> forSubData() {
|
||||||
|
ObjectMap<String> info = new ObjectMap<String>();
|
||||||
|
info.set("type", "Server");
|
||||||
|
info.set("name", getName());
|
||||||
|
info.set("display", getDisplayName());
|
||||||
|
info.set("group", getGroups());
|
||||||
|
info.set("address", getAddress().getAddress().getHostAddress() + ':' + getAddress().getPort());
|
||||||
|
info.set("motd", getMotd());
|
||||||
|
info.set("whitelist", getWhitelist());
|
||||||
|
info.set("restricted", isRestricted());
|
||||||
|
info.set("hidden", isHidden());
|
||||||
|
ObjectMap<String> players = new ObjectMap<String>();
|
||||||
|
for (RemotePlayer player : getRemotePlayers())
|
||||||
|
players.set(player.getUniqueId().toString(), player.getName());
|
||||||
|
info.set("players", players);
|
||||||
|
ObjectMap<Integer> subdata = new ObjectMap<Integer>();
|
||||||
|
for (int channel : this.subdata.keySet()) subdata.set(channel, (this.subdata.get(channel) == null)?null:this.subdata.get(channel).getID());
|
||||||
|
info.set("subdata", subdata);
|
||||||
|
info.set("signature", signature);
|
||||||
|
info.set("extra", getExtra());
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,50 +1,60 @@
|
||||||
package net.ME1312.SubServers.Bungee.Host;
|
package net.ME1312.SubServers.Bungee.Host;
|
||||||
|
|
||||||
import com.google.common.collect.Range;
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Callback;
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
import net.ME1312.Galaxi.Library.Version.Version;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidTemplateException;
|
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidTemplateException;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
|
||||||
import net.ME1312.SubServers.Bungee.SubAPI;
|
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||||
|
|
||||||
|
import com.google.common.collect.Range;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SubCreator Layout Class
|
* SubCreator Layout Class
|
||||||
*/
|
*/
|
||||||
public abstract class SubCreator {
|
public abstract class SubCreator {
|
||||||
public static class ServerTemplate {
|
public static class ServerTemplate {
|
||||||
|
private final boolean dynamic;
|
||||||
private String name;
|
private String name;
|
||||||
private String nick = null;
|
private String nick = null;
|
||||||
private boolean enabled;
|
private boolean enabled;
|
||||||
|
private boolean internal;
|
||||||
private String icon;
|
private String icon;
|
||||||
private File directory;
|
private File directory;
|
||||||
private ServerType type;
|
private ServerType type;
|
||||||
private YAMLSection build;
|
private ObjectMap<String> build;
|
||||||
private YAMLSection options;
|
private ObjectMap<String> options;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a SubCreator Template
|
* Create a SubCreator Template
|
||||||
*
|
*
|
||||||
* @param name Template Name
|
* @param name Template Name
|
||||||
|
* @param enabled Template Enabled Status
|
||||||
|
* @param icon Template Item Icon Name
|
||||||
* @param directory Template Directory
|
* @param directory Template Directory
|
||||||
* @param build Build Options
|
* @param build Build Options
|
||||||
* @param options Configuration Options
|
* @param options Configuration Options
|
||||||
*/
|
*/
|
||||||
public ServerTemplate(String name, boolean enabled, String icon, File directory, YAMLSection build, YAMLSection options) {
|
public ServerTemplate(String name, boolean enabled, String icon, File directory, ObjectMap<String> build, ObjectMap<String> options) {
|
||||||
if (Util.isNull(name, enabled, directory, build, options)) throw new NullPointerException();
|
this(name, enabled, false, icon, directory, build, options, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ServerTemplate(String name, boolean enabled, boolean internal, String icon, File directory, ObjectMap<String> build, ObjectMap<String> options, boolean dynamic) {
|
||||||
|
Util.nullpo(name, enabled, directory, build, options);
|
||||||
if (name.contains(" ")) throw new InvalidTemplateException("Template names cannot have spaces: " + name);
|
if (name.contains(" ")) throw new InvalidTemplateException("Template names cannot have spaces: " + name);
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.enabled = enabled;
|
this.enabled = enabled;
|
||||||
|
this.internal = internal;
|
||||||
this.icon = icon;
|
this.icon = icon;
|
||||||
this.directory = directory;
|
this.directory = directory;
|
||||||
this.type = (build.contains("Server-Type"))?ServerType.valueOf(build.getRawString("Server-Type").toUpperCase()):ServerType.CUSTOM;
|
this.type = (build.contains("Server-Type"))?ServerType.valueOf(build.getString("Server-Type").toUpperCase()):ServerType.CUSTOM;
|
||||||
this.build = build;
|
this.build = build;
|
||||||
this.options = options;
|
this.options = options;
|
||||||
|
this.dynamic = dynamic;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -96,6 +106,15 @@ public abstract class SubCreator {
|
||||||
enabled = value;
|
enabled = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if this Template is for Internal use only
|
||||||
|
*
|
||||||
|
* @return Internal Status
|
||||||
|
*/
|
||||||
|
public boolean isInternal() {
|
||||||
|
return internal;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the Item Icon for this Template
|
* Get the Item Icon for this Template
|
||||||
*
|
*
|
||||||
|
@ -132,12 +151,39 @@ public abstract class SubCreator {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get whether this Template requires the Version argument
|
||||||
|
*
|
||||||
|
* @return Version Requirement
|
||||||
|
*/
|
||||||
|
public boolean requiresVersion() {
|
||||||
|
return getBuildOptions().getBoolean("Require-Version", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get whether this Template can be used to update it's servers
|
||||||
|
*
|
||||||
|
* @return Updatable Status
|
||||||
|
*/
|
||||||
|
public boolean canUpdate() {
|
||||||
|
return getBuildOptions().getBoolean("Can-Update", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get whether this Template was generated by a SubCreator instance
|
||||||
|
*
|
||||||
|
* @return Dynamic Status
|
||||||
|
*/
|
||||||
|
public boolean isDynamic() {
|
||||||
|
return dynamic;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the Build Options for this Template
|
* Get the Build Options for this Template
|
||||||
*
|
*
|
||||||
* @return Build Options
|
* @return Build Options
|
||||||
*/
|
*/
|
||||||
public YAMLSection getBuildOptions() {
|
public ObjectMap<String> getBuildOptions() {
|
||||||
return build;
|
return build;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,19 +192,21 @@ public abstract class SubCreator {
|
||||||
*
|
*
|
||||||
* @return Configuration Options
|
* @return Configuration Options
|
||||||
*/
|
*/
|
||||||
public YAMLSection getConfigOptions() {
|
public ObjectMap<String> getConfigOptions() {
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
public ObjectMap<String> forSubData() {
|
||||||
YAMLSection tinfo = new YAMLSection();
|
ObjectMap<String> tinfo = new ObjectMap<String>();
|
||||||
tinfo.set("enabled", isEnabled());
|
tinfo.set("enabled", isEnabled());
|
||||||
tinfo.set("name", getName());
|
tinfo.set("name", getName());
|
||||||
tinfo.set("display", getDisplayName());
|
tinfo.set("display", getDisplayName());
|
||||||
tinfo.set("icon", getIcon());
|
tinfo.set("icon", getIcon());
|
||||||
tinfo.set("type", getType().toString());
|
tinfo.set("type", getType().toString());
|
||||||
return tinfo.toJSON();
|
tinfo.set("version-req", requiresVersion());
|
||||||
|
tinfo.set("can-update", canUpdate());
|
||||||
|
return tinfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public enum ServerType {
|
public enum ServerType {
|
||||||
|
@ -180,11 +228,12 @@ public abstract class SubCreator {
|
||||||
* @param player Player Creating
|
* @param player Player Creating
|
||||||
* @param name Server Name
|
* @param name Server Name
|
||||||
* @param template Server Template
|
* @param template Server Template
|
||||||
* @param version Server Version
|
* @param version Server Version (may be null)
|
||||||
* @param port Server Port Number (null to auto-select)
|
* @param port Server Port Number (null to auto-select)
|
||||||
|
* @param callback Callback
|
||||||
* @return Success Status
|
* @return Success Status
|
||||||
*/
|
*/
|
||||||
public abstract boolean create(UUID player, String name, ServerTemplate template, Version version, Integer port, Callback<SubServer> callback);
|
public abstract boolean create(UUID player, String name, ServerTemplate template, Version version, Integer port, Consumer<SubServer> callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a SubServer
|
* Create a SubServer
|
||||||
|
@ -192,7 +241,7 @@ public abstract class SubCreator {
|
||||||
* @param player Player Creating
|
* @param player Player Creating
|
||||||
* @param name Server Name
|
* @param name Server Name
|
||||||
* @param template Server Template
|
* @param template Server Template
|
||||||
* @param version Server Version
|
* @param version Server Version (may be null)
|
||||||
* @param port Server Port Number (null to auto-select)
|
* @param port Server Port Number (null to auto-select)
|
||||||
* @return Success Status
|
* @return Success Status
|
||||||
*/
|
*/
|
||||||
|
@ -205,11 +254,12 @@ public abstract class SubCreator {
|
||||||
*
|
*
|
||||||
* @param name Server Name
|
* @param name Server Name
|
||||||
* @param template Server Template
|
* @param template Server Template
|
||||||
* @param version Server Version
|
* @param version Server Version (may be null)
|
||||||
* @param port Server Port Number (null to auto-select)
|
* @param port Server Port Number (null to auto-select)
|
||||||
|
* @param callback Callback
|
||||||
* @return Success Status
|
* @return Success Status
|
||||||
*/
|
*/
|
||||||
public boolean create(String name, ServerTemplate template, Version version, Integer port, Callback<SubServer> callback) {
|
public boolean create(String name, ServerTemplate template, Version version, Integer port, Consumer<SubServer> callback) {
|
||||||
return create(null, name, template, version, port, callback);
|
return create(null, name, template, version, port, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,7 +268,7 @@ public abstract class SubCreator {
|
||||||
*
|
*
|
||||||
* @param name Server Name
|
* @param name Server Name
|
||||||
* @param template Server Template
|
* @param template Server Template
|
||||||
* @param version Server Version
|
* @param version Server Version (may be null)
|
||||||
* @param port Server Port Number (null to auto-select)
|
* @param port Server Port Number (null to auto-select)
|
||||||
* @return Success Status
|
* @return Success Status
|
||||||
*/
|
*/
|
||||||
|
@ -226,6 +276,79 @@ public abstract class SubCreator {
|
||||||
return create(null, name, template, version, port);
|
return create(null, name, template, version, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a SubServer
|
||||||
|
*
|
||||||
|
* @param player Player Updating
|
||||||
|
* @param server Server to Update
|
||||||
|
* @param template Server Template
|
||||||
|
* @param version Server Version (may be null)
|
||||||
|
* @param callback Callback
|
||||||
|
* @return Success Status
|
||||||
|
*/
|
||||||
|
public abstract boolean update(UUID player, SubServer server, ServerTemplate template, Version version, Consumer<Boolean> callback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a SubServer
|
||||||
|
*
|
||||||
|
* @param player Player Updating
|
||||||
|
* @param server Server to Update
|
||||||
|
* @param template Server Template
|
||||||
|
* @param version Server Version (may be null)
|
||||||
|
* @return Success Status
|
||||||
|
*/
|
||||||
|
public boolean update(UUID player, SubServer server, ServerTemplate template, Version version) {
|
||||||
|
return update(player, server, template, version, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a SubServer
|
||||||
|
*
|
||||||
|
* @param server Server to Update
|
||||||
|
* @param template Server Template
|
||||||
|
* @param version Server Version (may be null)
|
||||||
|
* @param callback Callback
|
||||||
|
* @return Success Status
|
||||||
|
*/
|
||||||
|
public boolean update(SubServer server, ServerTemplate template, Version version, Consumer<Boolean> callback) {
|
||||||
|
return update(null, server, template, version, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a SubServer
|
||||||
|
*
|
||||||
|
* @param server Server to Update
|
||||||
|
* @param template Server Template
|
||||||
|
* @param version Server Version (may be null)
|
||||||
|
* @return Success Status
|
||||||
|
*/
|
||||||
|
public boolean update(SubServer server, ServerTemplate template, Version version) {
|
||||||
|
return update(null, server, template, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a SubServer
|
||||||
|
*
|
||||||
|
* @param player Player Updating
|
||||||
|
* @param server Server to Update
|
||||||
|
* @param version Server Version (may be null)
|
||||||
|
* @return Success Status
|
||||||
|
*/
|
||||||
|
public boolean update(UUID player, SubServer server, Version version) {
|
||||||
|
return update(player, server, null, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a SubServer
|
||||||
|
*
|
||||||
|
* @param server Server to Update
|
||||||
|
* @param version Server Version (may be null)
|
||||||
|
* @return Success Status
|
||||||
|
*/
|
||||||
|
public boolean update(SubServer server, Version version) {
|
||||||
|
return update(null, server, version);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Terminate All SubCreator Instances on this host
|
* Terminate All SubCreator Instances on this host
|
||||||
*/
|
*/
|
||||||
|
@ -395,8 +518,28 @@ public abstract class SubCreator {
|
||||||
*/
|
*/
|
||||||
public abstract ServerTemplate getTemplate(String name);
|
public abstract ServerTemplate getTemplate(String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a SubCreator Template
|
||||||
|
*
|
||||||
|
* @param name Template Name
|
||||||
|
* @param enabled Template Enabled Status
|
||||||
|
* @param internal Template Internal Status
|
||||||
|
* @param icon Template Item Icon Name
|
||||||
|
* @param directory Template Directory
|
||||||
|
* @param build Build Options
|
||||||
|
* @param options Configuration Options
|
||||||
|
*/
|
||||||
|
protected ServerTemplate loadTemplate(String name, boolean enabled, boolean internal, String icon, File directory, ObjectMap<String> build, ObjectMap<String> options) {
|
||||||
|
return new ServerTemplate(name, enabled, internal, icon, directory, build, options, false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reload SubCreator
|
* Reload SubCreator
|
||||||
*/
|
*/
|
||||||
public abstract void reload();
|
public abstract void reload();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return obj instanceof SubCreator && getHost().getSignature().equals(((SubCreator) obj).getHost().getSignature());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package net.ME1312.SubServers.Bungee.Host;
|
package net.ME1312.SubServers.Bungee.Host;
|
||||||
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17,6 +18,7 @@ public interface SubServer extends Server {
|
||||||
NONE,
|
NONE,
|
||||||
RESTART,
|
RESTART,
|
||||||
REMOVE_SERVER,
|
REMOVE_SERVER,
|
||||||
|
RECYCLE_SERVER,
|
||||||
DELETE_SERVER;
|
DELETE_SERVER;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -39,7 +41,7 @@ public interface SubServer extends Server {
|
||||||
* @param command Command
|
* @param command Command
|
||||||
*/
|
*/
|
||||||
public LoggedCommand(String command) {
|
public LoggedCommand(String command) {
|
||||||
if (Util.isNull(command)) throw new NullPointerException();
|
Util.nullpo(command);
|
||||||
this.date = Calendar.getInstance().getTime();
|
this.date = Calendar.getInstance().getTime();
|
||||||
this.sender = null;
|
this.sender = null;
|
||||||
this.command = command;
|
this.command = command;
|
||||||
|
@ -52,7 +54,7 @@ public interface SubServer extends Server {
|
||||||
* @param command Command
|
* @param command Command
|
||||||
*/
|
*/
|
||||||
public LoggedCommand(UUID sender, String command) {
|
public LoggedCommand(UUID sender, String command) {
|
||||||
if (Util.isNull(command)) throw new NullPointerException();
|
Util.nullpo(command);
|
||||||
this.date = Calendar.getInstance().getTime();
|
this.date = Calendar.getInstance().getTime();
|
||||||
this.sender = sender;
|
this.sender = sender;
|
||||||
this.command = command;
|
this.command = command;
|
||||||
|
@ -66,7 +68,7 @@ public interface SubServer extends Server {
|
||||||
* @param command Command
|
* @param command Command
|
||||||
*/
|
*/
|
||||||
public LoggedCommand(Date date, UUID sender, String command) {
|
public LoggedCommand(Date date, UUID sender, String command) {
|
||||||
if (Util.isNull(date, command)) throw new NullPointerException();
|
Util.nullpo(date, command);
|
||||||
this.date = date;
|
this.date = date;
|
||||||
this.sender = sender;
|
this.sender = sender;
|
||||||
this.command = command;
|
this.command = command;
|
||||||
|
@ -113,7 +115,9 @@ public interface SubServer extends Server {
|
||||||
*
|
*
|
||||||
* @return Success Status
|
* @return Success Status
|
||||||
*/
|
*/
|
||||||
boolean start();
|
default boolean start() {
|
||||||
|
return start(null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stops the Server
|
* Stops the Server
|
||||||
|
@ -128,7 +132,9 @@ public interface SubServer extends Server {
|
||||||
*
|
*
|
||||||
* @return Success Status
|
* @return Success Status
|
||||||
*/
|
*/
|
||||||
boolean stop();
|
default boolean stop() {
|
||||||
|
return stop(null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Terminates the Server
|
* Terminates the Server
|
||||||
|
@ -143,24 +149,9 @@ public interface SubServer extends Server {
|
||||||
*
|
*
|
||||||
* @return Success Status
|
* @return Success Status
|
||||||
*/
|
*/
|
||||||
boolean terminate();
|
default boolean terminate() {
|
||||||
|
return terminate(null);
|
||||||
/**
|
}
|
||||||
* Commands the Server
|
|
||||||
*
|
|
||||||
* @param player Player who Commanded
|
|
||||||
* @param command Command to Send
|
|
||||||
* @return Success Status
|
|
||||||
*/
|
|
||||||
boolean command(UUID player, String command);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Commands the Server
|
|
||||||
*
|
|
||||||
* @param command Command to Send
|
|
||||||
* @return Success Status
|
|
||||||
*/
|
|
||||||
boolean command(String command);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Edits the Server
|
* Edits the Server
|
||||||
|
@ -169,7 +160,7 @@ public interface SubServer extends Server {
|
||||||
* @param edit Edits
|
* @param edit Edits
|
||||||
* @return Success Status
|
* @return Success Status
|
||||||
*/
|
*/
|
||||||
default int edit(UUID player, YAMLSection edit) {
|
default int edit(UUID player, ObjectMap<String> edit) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,10 +170,31 @@ public interface SubServer extends Server {
|
||||||
* @param edit Edits
|
* @param edit Edits
|
||||||
* @return Success Status
|
* @return Success Status
|
||||||
*/
|
*/
|
||||||
default int edit(YAMLSection edit) {
|
default int edit(ObjectMap<String> edit) {
|
||||||
|
return edit(null, edit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Edits the Server (& Saves Changes)
|
||||||
|
*
|
||||||
|
* @param player Player Editing
|
||||||
|
* @param edit Edits
|
||||||
|
* @return Success Status
|
||||||
|
*/
|
||||||
|
default int permaEdit(UUID player, ObjectMap<String> edit) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Edits the Server (& Saves Changes)
|
||||||
|
*
|
||||||
|
* @param edit Edits
|
||||||
|
* @return Success Status
|
||||||
|
*/
|
||||||
|
default int permaEdit(ObjectMap<String> edit) {
|
||||||
|
return permaEdit(null, edit);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Waits for the Server to Stop
|
* Waits for the Server to Stop
|
||||||
*
|
*
|
||||||
|
@ -197,6 +209,22 @@ public interface SubServer extends Server {
|
||||||
*/
|
*/
|
||||||
boolean isRunning();
|
boolean isRunning();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the Server is Online<br>
|
||||||
|
* <b>This method can only be true when a SubData connection is made!</b>
|
||||||
|
*
|
||||||
|
* @return Online Status
|
||||||
|
*/
|
||||||
|
boolean isOnline();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the Server is Stopping<br>
|
||||||
|
* <b>This method can only be true when the server is stopped through the server manager!</b>
|
||||||
|
*
|
||||||
|
* @return Stopping Status
|
||||||
|
*/
|
||||||
|
boolean isStopping();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Grabs the Host of the Server
|
* Grabs the Host of the Server
|
||||||
*
|
*
|
||||||
|
@ -204,6 +232,34 @@ public interface SubServer extends Server {
|
||||||
*/
|
*/
|
||||||
Host getHost();
|
Host getHost();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grabs the Template this Server was created from
|
||||||
|
*
|
||||||
|
* @return The Template
|
||||||
|
*/
|
||||||
|
SubCreator.ServerTemplate getTemplate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the Template this Server was created from
|
||||||
|
*
|
||||||
|
* @param value Value
|
||||||
|
*/
|
||||||
|
void setTemplate(SubCreator.ServerTemplate value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the Template this Server was created from
|
||||||
|
*
|
||||||
|
* @param value Value
|
||||||
|
*/
|
||||||
|
void setTemplate(String value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this Host Available?
|
||||||
|
*
|
||||||
|
* @return Availability Status
|
||||||
|
*/
|
||||||
|
boolean isAvailable();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the Server is Enabled
|
* If the Server is Enabled
|
||||||
*
|
*
|
||||||
|
@ -221,12 +277,12 @@ public interface SubServer extends Server {
|
||||||
/**
|
/**
|
||||||
* If the Server is accepting requests to edit()
|
* If the Server is accepting requests to edit()
|
||||||
*
|
*
|
||||||
* @see #edit(YAMLSection)
|
* @see #permaEdit(ObjectMap<String>)
|
||||||
* @see #edit(UUID, YAMLSection)
|
* @see #permaEdit(UUID, ObjectMap<String>)
|
||||||
* @return Edit Status
|
* @return Edit Status
|
||||||
*/
|
*/
|
||||||
default boolean isEditable() {
|
default boolean isEditable() {
|
||||||
return edit(new YAMLSection()) >= 0;
|
return permaEdit(new ObjectMap<String>()) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -267,7 +323,9 @@ public interface SubServer extends Server {
|
||||||
*
|
*
|
||||||
* @return Full Server Directory Path
|
* @return Full Server Directory Path
|
||||||
*/
|
*/
|
||||||
String getFullPath();
|
default String getFullPath() {
|
||||||
|
return new File(getHost().getPath(), getPath()).getPath();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the Server's Executable String
|
* Get the Server's Executable String
|
||||||
|
|
|
@ -1,133 +0,0 @@
|
||||||
package net.ME1312.SubServers.Bungee.Host;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.NamedContainer;
|
|
||||||
import net.ME1312.SubServers.Bungee.SubAPI;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SubServer Layout Class
|
|
||||||
*/
|
|
||||||
public abstract class SubServerContainer extends ServerContainer implements SubServer {
|
|
||||||
private List<NamedContainer<String, String>> incompatibilities = new ArrayList<NamedContainer<String, String>>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a SubServer
|
|
||||||
*
|
|
||||||
* @param host Host
|
|
||||||
* @param name Server Name
|
|
||||||
* @param port Port Number
|
|
||||||
* @param motd Server MOTD
|
|
||||||
* @param restricted Players will need a permission to join if true
|
|
||||||
* @throws InvalidServerException
|
|
||||||
*/
|
|
||||||
public SubServerContainer(Host host, String name, int port, String motd, boolean hidden, boolean restricted) throws InvalidServerException {
|
|
||||||
super(name, new InetSocketAddress(host.getAddress().getHostAddress(), port), motd, hidden, restricted);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean start() {
|
|
||||||
return start(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean stop() {
|
|
||||||
return stop(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean terminate() {
|
|
||||||
return terminate(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean command(String command) {
|
|
||||||
return command(null, command);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int edit(YAMLSection edit) {
|
|
||||||
return edit(null, edit);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getFullPath() {
|
|
||||||
return new File(getHost().getPath(), getPath()).getPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void toggleCompatibility(SubServer... server) {
|
|
||||||
for (SubServer s : server) {
|
|
||||||
if (!equals(s)) {
|
|
||||||
NamedContainer<String, String> info = new NamedContainer<String, String>(s.getHost().getName(), s.getName());
|
|
||||||
if (isCompatible(s)) {
|
|
||||||
incompatibilities.add(info);
|
|
||||||
if (s.isCompatible(this)) toggleCompatibility(this);
|
|
||||||
} else {
|
|
||||||
incompatibilities.remove(info);
|
|
||||||
if (!s.isCompatible(this)) toggleCompatibility(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCompatible(SubServer server) {
|
|
||||||
return !incompatibilities.contains(new NamedContainer<String, String>(server.getHost().getName(), server.getName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<SubServer> getIncompatibilities() {
|
|
||||||
List<SubServer> servers = new ArrayList<SubServer>();
|
|
||||||
List<NamedContainer<String, String>> temp = new ArrayList<NamedContainer<String, String>>();
|
|
||||||
temp.addAll(incompatibilities);
|
|
||||||
for (NamedContainer<String, String> info : temp) {
|
|
||||||
try {
|
|
||||||
SubServer server = SubAPI.getInstance().getHost(info.name()).getSubServer(info.get());
|
|
||||||
if (server == null) throw new NullPointerException();
|
|
||||||
servers.add(server);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
incompatibilities.remove(info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return servers;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<SubServer> getCurrentIncompatibilities() {
|
|
||||||
List<SubServer> servers = new ArrayList<SubServer>();
|
|
||||||
for (SubServer server : getIncompatibilities()) {
|
|
||||||
if (server.isRunning()) servers.add(server);
|
|
||||||
}
|
|
||||||
return servers;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings({"deprecation", "unchecked"})
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
YAMLSection sinfo = new YAMLSection(new Gson().fromJson(super.toString(), Map.class));
|
|
||||||
sinfo.set("type", "SubServer");
|
|
||||||
sinfo.set("host", getHost().getName());
|
|
||||||
sinfo.set("enabled", isEnabled());
|
|
||||||
sinfo.set("editable", isEditable());
|
|
||||||
sinfo.set("log", isLogging());
|
|
||||||
sinfo.set("dir", getPath());
|
|
||||||
sinfo.set("exec", getExecutable());
|
|
||||||
sinfo.set("running", isRunning());
|
|
||||||
sinfo.set("stop-cmd", getStopCommand());
|
|
||||||
sinfo.set("stop-action", getStopAction().toString());
|
|
||||||
sinfo.set("auto-run", SubAPI.getInstance().getInternals().config.get().getSection("Servers").getSection(getName(), new YAMLSection()).getBoolean("Run-On-Launch", false));
|
|
||||||
List<String> incompatibleCurrent = new ArrayList<String>();
|
|
||||||
List<String> incompatible = new ArrayList<String>();
|
|
||||||
for (SubServer server : getCurrentIncompatibilities()) incompatibleCurrent.add(server.getName());
|
|
||||||
for (SubServer server : getIncompatibilities()) incompatible.add(server.getName());
|
|
||||||
sinfo.set("incompatible", incompatibleCurrent);
|
|
||||||
sinfo.set("incompatible-list", incompatible);
|
|
||||||
return sinfo.toJSON();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +1,16 @@
|
||||||
package net.ME1312.SubServers.Bungee.Host;
|
package net.ME1312.SubServers.Bungee.Host;
|
||||||
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.LinkedList;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API-Safe SubServer Layout Class
|
* API-Safe SubServer Layout Class
|
||||||
*/
|
*/
|
||||||
public abstract class SubServerController {
|
public abstract class SubServerController {
|
||||||
private final SubServerContainer control;
|
private final SubServerImpl control;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a SubServer
|
* Creates a SubServer
|
||||||
|
@ -22,132 +23,149 @@ public abstract class SubServerController {
|
||||||
* @throws InvalidServerException
|
* @throws InvalidServerException
|
||||||
*/
|
*/
|
||||||
public SubServerController(Host host, String name, int port, String motd, boolean hidden, boolean restricted) throws InvalidServerException {
|
public SubServerController(Host host, String name, int port, String motd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||||
control = new SubServerContainer(host, name, port, motd, hidden, restricted) {
|
SubServerImpl control;
|
||||||
@Override
|
try {
|
||||||
public boolean start() {
|
control = new ControlledSubServer(host, name, port, motd, hidden, restricted);
|
||||||
return SubServerController.this.start();
|
} catch (NoSuchMethodError e) {
|
||||||
}
|
control = new ControlledSubServer(host, name, (Integer) port, motd, hidden, restricted);
|
||||||
|
}
|
||||||
|
this.control = control;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
private final class ControlledSubServer extends SubServerImpl {
|
||||||
public boolean start(UUID player) {
|
public ControlledSubServer(Host host, String name, int port, String motd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||||
return SubServerController.this.start(player);
|
super(host, name, port, motd, hidden, restricted);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public ControlledSubServer(Host host, String name, Integer port, String motd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||||
public boolean stop() {
|
super(host, name, port, motd, hidden, restricted);
|
||||||
return SubServerController.this.stop();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean stop(UUID player) {
|
public boolean start() {
|
||||||
return SubServerController.this.stop(player);
|
if (SubServerController.this.start()) {
|
||||||
}
|
started = false;
|
||||||
|
return true;
|
||||||
|
} else return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean terminate() {
|
public boolean start(UUID player) {
|
||||||
return SubServerController.this.terminate();
|
if (SubServerController.this.start(player)) {
|
||||||
}
|
started = false;
|
||||||
|
return true;
|
||||||
|
} else return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean terminate(UUID player) {
|
public boolean stop() {
|
||||||
return SubServerController.this.terminate(player);
|
return SubServerController.this.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean command(String command) {
|
public boolean stop(UUID player) {
|
||||||
return SubServerController.this.command(command);
|
return SubServerController.this.stop(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean command(UUID player, String command) {
|
public boolean terminate() {
|
||||||
return SubServerController.this.command(player, command);
|
return SubServerController.this.terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int edit(YAMLSection edit) {
|
public boolean terminate(UUID player) {
|
||||||
return SubServerController.this.edit(edit);
|
return SubServerController.this.terminate(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int edit(UUID player, YAMLSection edit) {
|
public boolean command(String command) {
|
||||||
return SubServerController.this.edit(player, edit);
|
return SubServerController.this.command(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void waitFor() throws InterruptedException {
|
public boolean command(UUID player, String command) {
|
||||||
SubServerController.this.waitFor();
|
return SubServerController.this.command(player, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isRunning() {
|
public int edit(UUID player, ObjectMap<String> edit, boolean perma) {
|
||||||
return SubServerController.this.isRunning();
|
return SubServerController.this.edit(player, edit, perma);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Host getHost() {
|
public void waitFor() throws InterruptedException {
|
||||||
return SubServerController.this.getHost();
|
SubServerController.this.waitFor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabled() {
|
public boolean isRunning() {
|
||||||
return SubServerController.this.isEnabled();
|
return SubServerController.this.isRunning();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setEnabled(boolean value) {
|
public Host getHost() {
|
||||||
SubServerController.this.setEnabled(value);
|
return SubServerController.this.getHost();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLogging() {
|
public boolean isEnabled() {
|
||||||
return SubServerController.this.isLogging();
|
return SubServerController.this.isEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setLogging(boolean value) {
|
public void setEnabled(boolean value) {
|
||||||
SubServerController.this.setLogging(value);
|
SubServerController.this.setEnabled(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SubLogger getLogger() {
|
public boolean isLogging() {
|
||||||
return SubServerController.this.getLogger();
|
return SubServerController.this.isLogging();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LinkedList<LoggedCommand> getCommandHistory() {
|
public void setLogging(boolean value) {
|
||||||
return SubServerController.this.getCommandHistory();
|
SubServerController.this.setLogging(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPath() {
|
public SubLogger getLogger() {
|
||||||
return SubServerController.this.getPath();
|
return SubServerController.this.getLogger();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getExecutable() {
|
public LinkedList<LoggedCommand> getCommandHistory() {
|
||||||
return SubServerController.this.getExecutable();
|
return SubServerController.this.getCommandHistory();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getStopCommand() {
|
public String getPath() {
|
||||||
return SubServerController.this.getStopCommand();
|
return SubServerController.this.getPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setStopCommand(String value) {
|
public String getExecutable() {
|
||||||
SubServerController.this.setStopCommand(value);
|
return SubServerController.this.getExecutable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StopAction getStopAction() {
|
public String getStopCommand() {
|
||||||
return SubServerController.this.getStopAction();
|
return SubServerController.this.getStopCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setStopAction(StopAction action) {
|
public void setStopCommand(String value) {
|
||||||
SubServerController.this.setStopAction(action);
|
SubServerController.this.setStopCommand(value);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
@Override
|
||||||
|
public StopAction getStopAction() {
|
||||||
|
return SubServerController.this.getStopAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setStopAction(StopAction action) {
|
||||||
|
SubServerController.this.setStopAction(action);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -213,7 +231,7 @@ public abstract class SubServerController {
|
||||||
/**
|
/**
|
||||||
* Commands the Server
|
* Commands the Server
|
||||||
*
|
*
|
||||||
* @param player Player who Commanded
|
* @param player Player who's Commanding
|
||||||
* @param command Command to Send
|
* @param command Command to Send
|
||||||
* @return Success Status
|
* @return Success Status
|
||||||
*/
|
*/
|
||||||
|
@ -234,19 +252,10 @@ public abstract class SubServerController {
|
||||||
*
|
*
|
||||||
* @param player Player Editing
|
* @param player Player Editing
|
||||||
* @param edit Edits
|
* @param edit Edits
|
||||||
|
* @param perma Saves Changes
|
||||||
* @return Success Status
|
* @return Success Status
|
||||||
*/
|
*/
|
||||||
public int edit(UUID player, YAMLSection edit) {
|
protected int edit(UUID player, ObjectMap<String> edit, boolean perma) {
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Edits the Server
|
|
||||||
*
|
|
||||||
* @param edit Edits
|
|
||||||
* @return Success Status
|
|
||||||
*/
|
|
||||||
public int edit(YAMLSection edit) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,9 +361,4 @@ public abstract class SubServerController {
|
||||||
* @param action Stop Action
|
* @param action Stop Action
|
||||||
*/
|
*/
|
||||||
public abstract void setStopAction(SubServer.StopAction action);
|
public abstract void setStopAction(SubServer.StopAction action);
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return control.toString();
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -0,0 +1,203 @@
|
||||||
|
package net.ME1312.SubServers.Bungee.Host;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Container.ContainedPair;
|
||||||
|
import net.ME1312.Galaxi.Library.Container.Pair;
|
||||||
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
|
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
||||||
|
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.SocketAddress;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SubServer Layout Class
|
||||||
|
*/
|
||||||
|
public abstract class SubServerImpl extends ServerImpl implements SubServer {
|
||||||
|
protected static final Pattern DISALLOWED_COMMANDS = Pattern.compile("^/?(?:[^\\s]+:)?sub(?:servers?)?(?:\\s|$)", Pattern.CASE_INSENSITIVE & Pattern.UNICODE_CASE);
|
||||||
|
private List<Pair<String, String>> incompatibilities = new ArrayList<Pair<String, String>>();
|
||||||
|
private SubCreator.ServerTemplate templateV = null;
|
||||||
|
private String templateS = null;
|
||||||
|
protected boolean registered, started, stopping, updating;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a SubServer
|
||||||
|
*
|
||||||
|
* @param host Host
|
||||||
|
* @param name Server Name
|
||||||
|
* @param port Port Number
|
||||||
|
* @param motd Server MOTD
|
||||||
|
* @param hidden Hidden Status
|
||||||
|
* @param restricted Restricted Status
|
||||||
|
*
|
||||||
|
* @see ServerImpl#ServerImpl(String, SocketAddress, String, boolean, boolean) Super Method 2
|
||||||
|
* @throws InvalidServerException
|
||||||
|
*/
|
||||||
|
protected SubServerImpl(Host host, String name, int port, String motd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||||
|
super(name, (SocketAddress) new InetSocketAddress(host.getAddress().getHostAddress(), port), motd, hidden, restricted);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a SubServer
|
||||||
|
*
|
||||||
|
* @param host Host
|
||||||
|
* @param name Server Name
|
||||||
|
* @param port Port Number
|
||||||
|
* @param motd Server MOTD
|
||||||
|
* @param hidden Hidden Status
|
||||||
|
* @param restricted Restricted Status
|
||||||
|
*
|
||||||
|
* @see ServerImpl#ServerImpl(String, InetSocketAddress, String, boolean, boolean) Super Method 1
|
||||||
|
* @throws InvalidServerException
|
||||||
|
*/
|
||||||
|
protected SubServerImpl(Host host, String name, Integer port, String motd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||||
|
super(name, new InetSocketAddress(host.getAddress().getHostAddress(), port), motd, hidden, restricted);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int edit(UUID player, ObjectMap<String> edit) {
|
||||||
|
return edit(player, edit, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int permaEdit(UUID player, ObjectMap<String> edit) {
|
||||||
|
return edit(player, edit, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Edits the Server
|
||||||
|
*
|
||||||
|
* @param player Player Editing
|
||||||
|
* @param edit Edits
|
||||||
|
* @param perma Saves Changes
|
||||||
|
* @return Success Status
|
||||||
|
*/
|
||||||
|
protected int edit(UUID player, ObjectMap<String> edit, boolean perma) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected final boolean isRegistered() {
|
||||||
|
return registered;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAvailable() {
|
||||||
|
return registered && !updating && getHost().isAvailable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isOnline() {
|
||||||
|
return isRunning() && started;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isStopping() {
|
||||||
|
return isRunning() && stopping;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTemplate(String template) {
|
||||||
|
this.templateV = null;
|
||||||
|
this.templateS = template;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTemplate(SubCreator.ServerTemplate template) {
|
||||||
|
this.templateV = template;
|
||||||
|
this.templateS = (template != null)?template.getName():null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SubCreator.ServerTemplate getTemplate() {
|
||||||
|
if (templateV != null) {
|
||||||
|
return templateV;
|
||||||
|
} else if (templateS != null && getHost().getCreator().getTemplates().containsKey(templateS.toLowerCase())) {
|
||||||
|
return getHost().getCreator().getTemplate(templateS.toLowerCase());
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void toggleCompatibility(SubServer... server) {
|
||||||
|
for (SubServer s : server) {
|
||||||
|
if (!equals(s)) {
|
||||||
|
Pair<String, String> info = new ContainedPair<String, String>(s.getHost().getName(), s.getName());
|
||||||
|
if (isCompatible(s)) {
|
||||||
|
incompatibilities.add(info);
|
||||||
|
if (s.isCompatible(this)) toggleCompatibility(this);
|
||||||
|
} else {
|
||||||
|
incompatibilities.remove(info);
|
||||||
|
if (!s.isCompatible(this)) toggleCompatibility(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCompatible(SubServer server) {
|
||||||
|
return !incompatibilities.contains(new ContainedPair<String, String>(server.getHost().getName(), server.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<SubServer> getIncompatibilities() {
|
||||||
|
List<SubServer> servers = new ArrayList<SubServer>();
|
||||||
|
List<Pair<String, String>> temp = new ArrayList<Pair<String, String>>();
|
||||||
|
temp.addAll(incompatibilities);
|
||||||
|
for (Pair<String, String> info : temp) {
|
||||||
|
try {
|
||||||
|
SubServer server = SubAPI.getInstance().getHost(info.key()).getSubServer(info.value());
|
||||||
|
if (server == null) throw new NullPointerException();
|
||||||
|
servers.add(server);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
incompatibilities.remove(info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return servers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<SubServer> getCurrentIncompatibilities() {
|
||||||
|
List<SubServer> servers = new ArrayList<SubServer>();
|
||||||
|
for (SubServer server : getIncompatibilities()) {
|
||||||
|
if (server.isRunning()) servers.add(server);
|
||||||
|
}
|
||||||
|
return servers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return obj instanceof SubServerImpl && super.equals(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Override
|
||||||
|
public ObjectMap<String> forSubData() {
|
||||||
|
ObjectMap<String> sinfo = super.forSubData();
|
||||||
|
sinfo.set("type", "SubServer");
|
||||||
|
sinfo.set("host", getHost().getName());
|
||||||
|
sinfo.set("template", (getTemplate() != null)?getTemplate().getName():null);
|
||||||
|
sinfo.set("available", isAvailable());
|
||||||
|
sinfo.set("enabled", isEnabled());
|
||||||
|
sinfo.set("editable", isEditable());
|
||||||
|
sinfo.set("log", isLogging());
|
||||||
|
sinfo.set("dir", getPath());
|
||||||
|
sinfo.set("exec", getExecutable());
|
||||||
|
sinfo.set("running", isRunning());
|
||||||
|
sinfo.set("online", isOnline());
|
||||||
|
sinfo.set("stopping", isStopping());
|
||||||
|
sinfo.set("stop-cmd", getStopCommand());
|
||||||
|
sinfo.set("stop-action", getStopAction().toString());
|
||||||
|
sinfo.set("auto-run", SubAPI.getInstance().getInternals().servers.get().getMap("Servers").getMap(getName(), new ObjectMap<String>()).getBoolean("Run-On-Launch", false));
|
||||||
|
List<String> incompatibleCurrent = new ArrayList<String>();
|
||||||
|
List<String> incompatible = new ArrayList<String>();
|
||||||
|
for (SubServer server : getCurrentIncompatibilities()) incompatibleCurrent.add(server.getName());
|
||||||
|
for (SubServer server : getIncompatibilities()) incompatible.add(server.getName());
|
||||||
|
sinfo.set("incompatible", incompatibleCurrent);
|
||||||
|
sinfo.set("incompatible-list", incompatible);
|
||||||
|
return sinfo;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,8 @@
|
||||||
package net.ME1312.SubServers.Bungee;
|
package net.ME1312.SubServers.Bungee;
|
||||||
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Container;
|
import net.ME1312.Galaxi.Library.Platform;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
import net.ME1312.Galaxi.Library.Try;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Version.VersionType;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.security.Security;
|
import java.security.Security;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
@ -24,9 +21,11 @@ public final class Launch {
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"deprecation", "unchecked"})
|
@SuppressWarnings({"deprecation", "unchecked"})
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
|
System.setProperty("jdk.lang.Process.allowAmbiguousCommands", "true");
|
||||||
|
System.setProperty("jdk.util.jar.enableMultiRelease", "force");
|
||||||
System.setProperty("apple.laf.useScreenMenuBar", "true");
|
System.setProperty("apple.laf.useScreenMenuBar", "true");
|
||||||
|
|
||||||
if (Util.getDespiteException(() -> Class.forName("net.md_5.bungee.BungeeCord") == null, true)) {
|
if (Try.all.get(() -> Class.forName("net.md_5.bungee.BungeeCord") == null, true)) {
|
||||||
System.out.println("");
|
System.out.println("");
|
||||||
System.out.println("*******************************************");
|
System.out.println("*******************************************");
|
||||||
System.out.println("*** Error: BungeeCord.jar Doesn't Exist ***");
|
System.out.println("*** Error: BungeeCord.jar Doesn't Exist ***");
|
||||||
|
@ -48,38 +47,11 @@ public final class Launch {
|
||||||
parser.accepts("noconsole");
|
parser.accepts("noconsole");
|
||||||
joptsimple.OptionSet options = parser.parse(args);
|
joptsimple.OptionSet options = parser.parse(args);
|
||||||
if(options.has("version") || options.has("v")) {
|
if(options.has("version") || options.has("v")) {
|
||||||
String osarch;
|
|
||||||
if (System.getProperty("os.name").toLowerCase().startsWith("windows")) {
|
|
||||||
String arch = System.getenv("PROCESSOR_ARCHITECTURE");
|
|
||||||
String wow64Arch = System.getenv("PROCESSOR_ARCHITEW6432");
|
|
||||||
|
|
||||||
osarch = arch != null && arch.endsWith("64") || wow64Arch != null && wow64Arch.endsWith("64")?"x64":"x86";
|
|
||||||
} else if (System.getProperty("os.arch").endsWith("86")) {
|
|
||||||
osarch = "x86";
|
|
||||||
} else if (System.getProperty("os.arch").endsWith("64")) {
|
|
||||||
osarch = "x64";
|
|
||||||
} else {
|
|
||||||
osarch = System.getProperty("os.arch");
|
|
||||||
}
|
|
||||||
|
|
||||||
String javaarch = null;
|
|
||||||
switch (System.getProperty("sun.arch.data.model")) {
|
|
||||||
case "32":
|
|
||||||
javaarch = "x86";
|
|
||||||
break;
|
|
||||||
case "64":
|
|
||||||
javaarch = "x64";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (!System.getProperty("sun.arch.data.model").equalsIgnoreCase("unknown"))
|
|
||||||
javaarch = System.getProperty("sun.arch.data.model");
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println("");
|
System.out.println("");
|
||||||
System.out.println(System.getProperty("os.name") + ((!System.getProperty("os.name").toLowerCase().startsWith("windows"))?' ' + System.getProperty("os.version"):"") + ((osarch != null)?" [" + osarch + ']':"") + ',');
|
System.out.println(Platform.getSystemName() + ' ' + Platform.getSystemVersion() + ((Platform.getSystemBuild() != null)?" (" + Platform.getSystemBuild() + ')':"") + ((!Platform.getSystemArchitecture().equals("unknown"))?" [" + Platform.getSystemArchitecture() + ']':"") + ',');
|
||||||
System.out.println("Java " + System.getProperty("java.version") + ((javaarch != null)?" [" + javaarch + ']':"") + ',');
|
System.out.println("Java " + Platform.getJavaVersion() + ((!Platform.getJavaArchitecture().equals("unknown"))?" [" + Platform.getJavaArchitecture() + ']':"") + ',');
|
||||||
System.out.println("BungeeCord" + ((patched)?" [Patched] ":" ") + net.md_5.bungee.Bootstrap.class.getPackage().getImplementationVersion() + ',');
|
System.out.println("BungeeCord " + net.md_5.bungee.Bootstrap.class.getPackage().getImplementationVersion() + ((patched)?" [Patched]":"") + ',');
|
||||||
System.out.println("SubServers.Bungee v" + SubPlugin.version.toExtendedString() + ((SubPlugin.class.getPackage().getSpecificationTitle() != null)?" (" + SubPlugin.class.getPackage().getSpecificationTitle() + ')':""));
|
System.out.println("SubServers.Bungee v" + SubProxy.version.toExtendedString() + ((SubProxy.class.getPackage().getSpecificationTitle() != null)?" (" + SubProxy.class.getPackage().getSpecificationTitle() + ')':""));
|
||||||
System.out.println("");
|
System.out.println("");
|
||||||
} else {
|
} else {
|
||||||
System.out.println("");
|
System.out.println("");
|
||||||
|
@ -93,7 +65,7 @@ public final class Launch {
|
||||||
if (net.md_5.bungee.BungeeCord.class.getPackage().getSpecificationVersion() != null) {
|
if (net.md_5.bungee.BungeeCord.class.getPackage().getSpecificationVersion() != null) {
|
||||||
Date date = (new SimpleDateFormat("yyyyMMdd")).parse(net.md_5.bungee.BungeeCord.class.getPackage().getSpecificationVersion());
|
Date date = (new SimpleDateFormat("yyyyMMdd")).parse(net.md_5.bungee.BungeeCord.class.getPackage().getSpecificationVersion());
|
||||||
Calendar line = Calendar.getInstance();
|
Calendar line = Calendar.getInstance();
|
||||||
line.add(3, -4);
|
line.add(Calendar.WEEK_OF_YEAR, -8);
|
||||||
if (date.before(line.getTime())) {
|
if (date.before(line.getTime())) {
|
||||||
System.out.println("*** Warning: BungeeCord is outdated ***");
|
System.out.println("*** Warning: BungeeCord is outdated ***");
|
||||||
System.out.println("*** Please download a new build from: ***");
|
System.out.println("*** Please download a new build from: ***");
|
||||||
|
@ -111,16 +83,16 @@ public final class Launch {
|
||||||
}
|
}
|
||||||
System.out.println("");
|
System.out.println("");
|
||||||
|
|
||||||
SubPlugin plugin = new SubPlugin(System.out, patched);
|
SubProxy plugin = new SubProxy(System.out, patched);
|
||||||
net.md_5.bungee.api.ProxyServer.class.getMethod("setInstance", net.md_5.bungee.api.ProxyServer.class).invoke(null, plugin);
|
net.md_5.bungee.api.ProxyServer.class.getMethod("setInstance", net.md_5.bungee.api.ProxyServer.class).invoke(null, plugin);
|
||||||
plugin.getLogger().info("Enabled " + plugin.getBungeeName() + " version " + plugin.getVersion());
|
plugin.getLogger().info("Enabled " + plugin.getBungeeName() + " version " + plugin.getVersion());
|
||||||
plugin.start();
|
plugin.start();
|
||||||
|
|
||||||
if (!options.has("noconsole")) {
|
if (!options.has("noconsole")) {
|
||||||
try {
|
try {
|
||||||
if (Util.getDespiteException(() -> Class.forName("io.github.waterfallmc.waterfall.console.WaterfallConsole").getMethod("readCommands") != null, false)) {
|
if (Try.all.get(() -> Class.forName("io.github.waterfallmc.waterfall.console.WaterfallConsole").getMethod("readCommands") != null, false)) { // Waterfall Setup
|
||||||
Class.forName("io.github.waterfallmc.waterfall.console.WaterfallConsole").getMethod("readCommands").invoke(null);
|
Class.forName("io.github.waterfallmc.waterfall.console.WaterfallConsole").getMethod("readCommands").invoke(null);
|
||||||
} else if (Util.getDespiteException(() -> Class.forName("io.github.waterfallmc.waterfall.console.WaterfallConsole").getMethod("start") != null, false)) {
|
} else if (Try.all.get(() -> Class.forName("io.github.waterfallmc.waterfall.console.WaterfallConsole").getMethod("start") != null, false)) {
|
||||||
Class console = Class.forName("io.github.waterfallmc.waterfall.console.WaterfallConsole");
|
Class console = Class.forName("io.github.waterfallmc.waterfall.console.WaterfallConsole");
|
||||||
console.getMethod("start").invoke(console.getConstructor().newInstance());
|
console.getMethod("start").invoke(console.getConstructor().newInstance());
|
||||||
} else {
|
} else {
|
||||||
|
@ -133,7 +105,7 @@ public final class Launch {
|
||||||
}
|
}
|
||||||
} else if (line.equalsIgnoreCase("exit")) {
|
} else if (line.equalsIgnoreCase("exit")) {
|
||||||
plugin.sudo = null;
|
plugin.sudo = null;
|
||||||
System.out.println("SubServers > Reverting to the BungeeCord Console");
|
net.ME1312.SubServers.Bungee.Library.Compatibility.Logger.get("SubServers").info("Reverting to the BungeeCord Console");
|
||||||
} else {
|
} else {
|
||||||
plugin.sudo.command(line);
|
plugin.sudo.command(line);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
package net.ME1312.SubServers.Bungee.Library;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback Class
|
|
||||||
*/
|
|
||||||
public interface Callback<T> {
|
|
||||||
/**
|
|
||||||
* Run the Callback
|
|
||||||
*
|
|
||||||
* @param obj Object
|
|
||||||
*/
|
|
||||||
void run(T obj);
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
package net.ME1312.SubServers.Bungee.Library.Compatibility;
|
|
||||||
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.NamedContainer;
|
|
||||||
import net.md_5.bungee.api.CommandSender;
|
|
||||||
import net.md_5.bungee.api.plugin.Command;
|
|
||||||
import net.md_5.bungee.api.plugin.TabExecutor;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Command Layout Class that implements all possible features (Base Version)
|
|
||||||
*/
|
|
||||||
public abstract class CommandX extends Command implements TabExecutor {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a Command
|
|
||||||
*
|
|
||||||
* @param name Command Name
|
|
||||||
*/
|
|
||||||
public CommandX(String name) {
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a Command
|
|
||||||
*
|
|
||||||
* @param name Command Name
|
|
||||||
* @param permission Command Permission
|
|
||||||
* @param aliases Command Aliases
|
|
||||||
*/
|
|
||||||
public CommandX(String name, String permission, String... aliases) {
|
|
||||||
super(name, permission, aliases);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Suggest Arguments
|
|
||||||
*
|
|
||||||
* @param sender Sender
|
|
||||||
* @param args Arguments (including the final unfinished one)
|
|
||||||
* @return An Error Message (if there was one, otherwise null) and a List of Suggestions
|
|
||||||
*/
|
|
||||||
public abstract NamedContainer<String, List<String>> suggestArguments(CommandSender sender, String[] args);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Override the BungeeCord Method of {@link #suggestArguments(CommandSender, String[])}
|
|
||||||
*
|
|
||||||
* @param sender Sender
|
|
||||||
* @param args Arguments (including the final unfinished one)
|
|
||||||
* @return A Collection of Suggestions
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Iterable<String> onTabComplete(CommandSender sender, String[] args) {
|
|
||||||
return suggestArguments(sender, args).get();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +1,19 @@
|
||||||
package net.ME1312.SubServers.Bungee.Library.Compatibility;
|
package net.ME1312.SubServers.Bungee.Library.Compatibility;
|
||||||
|
|
||||||
import com.google.common.io.Resources;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.UniversalFile;
|
|
||||||
import net.ME1312.SubServers.Bungee.SubAPI;
|
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||||
|
|
||||||
|
import com.google.common.io.Resources;
|
||||||
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import static java.util.logging.Level.SEVERE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JNA Library Loader Class
|
* JNA Library Loader Class
|
||||||
|
@ -27,12 +33,13 @@ public class JNA {
|
||||||
public static ClassLoader get() {
|
public static ClassLoader get() {
|
||||||
if (JNA == null) {
|
if (JNA == null) {
|
||||||
boolean announced = false;
|
boolean announced = false;
|
||||||
UniversalFile library = new UniversalFile(SubAPI.getInstance().getInternals().dir, "SubServers:Cache:Libraries");
|
Logger log = ProxyServer.getInstance().getLogger();
|
||||||
UniversalFile jna = new UniversalFile(library, "jna-" + JNA_VERSION + ".jar");
|
File library = new File(SubAPI.getInstance().getInternals().dir, "SubServers/Cache/Libraries");
|
||||||
|
File jna = new File(library, "jna-" + JNA_VERSION + ".jar");
|
||||||
jna.getParentFile().mkdirs();
|
jna.getParentFile().mkdirs();
|
||||||
if (!jna.exists()) {
|
if (!jna.exists()) {
|
||||||
announced = true;
|
announced = true;
|
||||||
System.out.println(">> Downloading JNA Library v" + JNA_VERSION);
|
log.info(">> Downloading JNA v" + JNA_VERSION);
|
||||||
try (FileOutputStream fin = new FileOutputStream(jna)) {
|
try (FileOutputStream fin = new FileOutputStream(jna)) {
|
||||||
Resources.copy(new URL(JNA_DOWNLOAD.replace("$1", "jna")), fin);
|
Resources.copy(new URL(JNA_DOWNLOAD.replace("$1", "jna")), fin);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
@ -40,10 +47,10 @@ public class JNA {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UniversalFile platform = new UniversalFile(library, "jna-platform-" + JNA_VERSION + ".jar");
|
File platform = new File(library, "jna-platform-" + JNA_VERSION + ".jar");
|
||||||
platform.getParentFile().mkdirs();
|
platform.getParentFile().mkdirs();
|
||||||
if (!platform.exists()) {
|
if (!platform.exists()) {
|
||||||
if (!announced) System.out.println(">> Downloading JNA Library v" + JNA_VERSION);
|
if (!announced) log.info(">> Downloading JNA platform v" + JNA_VERSION);
|
||||||
announced = true;
|
announced = true;
|
||||||
try (FileOutputStream fin = new FileOutputStream(platform)) {
|
try (FileOutputStream fin = new FileOutputStream(platform)) {
|
||||||
Resources.copy(new URL(JNA_DOWNLOAD.replace("$1", "jna-platform")), fin);
|
Resources.copy(new URL(JNA_DOWNLOAD.replace("$1", "jna-platform")), fin);
|
||||||
|
@ -53,16 +60,14 @@ public class JNA {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (jna.exists() && platform.exists()) {
|
if (jna.exists() && platform.exists()) {
|
||||||
if (announced) System.out.println(">> Loading JNA Library");
|
if (announced) log.info(">> JNA download complete");
|
||||||
try {
|
try {
|
||||||
JNA = new URLClassLoader(new URL[]{jna.toURI().toURL(), platform.toURI().toURL()});
|
JNA = new URLClassLoader(new URL[]{jna.toURI().toURL(), platform.toURI().toURL()});
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
System.out.println(">> Could not load JNA Library:");
|
log.log(SEVERE, ">> Couldn't load JNA:", e);
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
System.out.println(">> Could not load JNA Library:");
|
log.log(SEVERE, ">> Couldn't load JNA:", new FileNotFoundException());
|
||||||
new FileNotFoundException().printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return JNA;
|
return JNA;
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
package net.ME1312.SubServers.Bungee.Library.Compatibility;
|
||||||
|
|
||||||
|
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.config.ServerInfo;
|
||||||
|
import net.md_5.bungee.util.CaseInsensitiveMap;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Legacy Server Map Translation Class
|
||||||
|
*/
|
||||||
|
public class LegacyServerMap extends CaseInsensitiveMap<ServerInfo> {
|
||||||
|
public LegacyServerMap() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public LegacyServerMap(Map<String, ServerInfo> map) {
|
||||||
|
for (Entry<String, ServerInfo> e : map.entrySet()) super.put(e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Override
|
||||||
|
public ServerInfo put(String key, ServerInfo value) {
|
||||||
|
if (value == null) throw new NullPointerException();
|
||||||
|
ServerInfo n = SubAPI.getInstance().addServer(value.getName(), value.getAddress().getAddress(), value.getAddress().getPort(), value.getMotd(), false, value.isRestricted()),
|
||||||
|
s = getOrDefault(key, null);
|
||||||
|
|
||||||
|
if (n != null)
|
||||||
|
super.put(n.getName(), n);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServerInfo remove(Object key) {
|
||||||
|
if (key instanceof String) {
|
||||||
|
ServerInfo s = getOrDefault(key, null);
|
||||||
|
if (s != null) {
|
||||||
|
if (SubAPI.getInstance().removeServer((String) key))
|
||||||
|
super.remove(key);
|
||||||
|
return s;
|
||||||
|
} else return null;
|
||||||
|
} else return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
// Disallow removing all servers
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,9 @@
|
||||||
package net.ME1312.SubServers.Bungee.Library.Compatibility;
|
package net.ME1312.SubServers.Bungee.Library.Compatibility;
|
||||||
|
|
||||||
public class Plugin extends net.md_5.bungee.api.plugin.Plugin {
|
public final class Plugin extends net.md_5.bungee.api.plugin.Plugin {
|
||||||
|
|
||||||
@Override
|
@Deprecated
|
||||||
public void onEnable() {
|
public Plugin() {
|
||||||
throw new IllegalStateException("SubServers.Bungee does not run as a plugin, but a wrapper. For more information on how to install, visit this page: https://github.com/ME1312/SubServers-2/wiki/Install");
|
throw new IllegalStateException("SubServers.Bungee does not run as a plugin, but a wrapper. For more information on how to install, please visit this page: https://github.com/ME1312/SubServers-2/wiki/Installation");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,74 +0,0 @@
|
||||||
package net.ME1312.SubServers.Bungee.Library.Compatibility.mc1_13;
|
|
||||||
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.NamedContainer;
|
|
||||||
import net.md_5.bungee.api.CommandSender;
|
|
||||||
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Command Layout Class that implements all possible features (1.13 Version)
|
|
||||||
*/
|
|
||||||
public class CommandX extends net.ME1312.SubServers.Bungee.Library.Compatibility.CommandX/* implements TabValidator */ {
|
|
||||||
public final net.ME1312.SubServers.Bungee.Library.Compatibility.CommandX command;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a Command
|
|
||||||
*
|
|
||||||
* @param other CommandX from previous version
|
|
||||||
*/
|
|
||||||
public CommandX(net.ME1312.SubServers.Bungee.Library.Compatibility.CommandX other) {
|
|
||||||
super(other.getName());
|
|
||||||
command = other;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Override BungeeCord Method for the previously used one
|
|
||||||
*
|
|
||||||
* @param sender Sender
|
|
||||||
* @param args Arguments
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void execute(CommandSender sender, String[] args) {
|
|
||||||
command.execute(sender, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NamedContainer<String, List<String>> suggestArguments(CommandSender sender, String[] args) {
|
|
||||||
return command.suggestArguments(sender, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate a Command (Override for custom)
|
|
||||||
*
|
|
||||||
* @param sender Sender
|
|
||||||
* @param command Command to validate
|
|
||||||
* @return NamedContainer with a String error message and a Integer that represents where the command was deemed invalid
|
|
||||||
*/
|
|
||||||
public NamedContainer<String, Integer> validateCommand(CommandSender sender, String command) {
|
|
||||||
List<NamedContainer<String, Integer>> split = new LinkedList<NamedContainer<String, Integer>>();
|
|
||||||
String cmd = command;
|
|
||||||
int i;
|
|
||||||
while ((i = cmd.indexOf((int) ' ')) < 0) {
|
|
||||||
i++;
|
|
||||||
String arg = cmd.substring(i);
|
|
||||||
split.add(new NamedContainer<>(arg.contains(" ")?arg.substring(0, arg.indexOf((int) ' ')):arg, i));
|
|
||||||
cmd = arg;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> args = new LinkedList<String>();
|
|
||||||
NamedContainer<String, Integer> response = null;
|
|
||||||
i = 0;
|
|
||||||
for (NamedContainer<String, Integer> arg : split) {
|
|
||||||
if (i > 0) {
|
|
||||||
args.add(arg.name());
|
|
||||||
NamedContainer<String, List<String>> suggestions = suggestArguments(sender, args.toArray(new String[args.size() - 1]));
|
|
||||||
if (suggestions.name() != null) response = new NamedContainer<>(suggestions.name(), arg.get());
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO Override the original validator method
|
|
||||||
}
|
|
|
@ -1,110 +0,0 @@
|
||||||
package net.ME1312.SubServers.Bungee.Library.Config;
|
|
||||||
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import org.yaml.snakeyaml.DumperOptions;
|
|
||||||
import org.yaml.snakeyaml.Yaml;
|
|
||||||
import org.yaml.snakeyaml.error.YAMLException;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* YAML Config Class
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public class YAMLConfig {
|
|
||||||
private File file;
|
|
||||||
private Yaml yaml;
|
|
||||||
private YAMLSection config;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates/Loads a YAML Formatted Config
|
|
||||||
*
|
|
||||||
* @param file
|
|
||||||
* @throws IOException
|
|
||||||
* @throws YAMLException
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public YAMLConfig(File file) throws IOException, YAMLException {
|
|
||||||
if (Util.isNull(file)) throw new NullPointerException();
|
|
||||||
this.file = file;
|
|
||||||
this.yaml = new Yaml(getDumperOptions());
|
|
||||||
if (file.exists()) {
|
|
||||||
InputStream stream = new FileInputStream(file);
|
|
||||||
this.config = new YAMLSection((LinkedHashMap<String, ?>) yaml.loadAs(stream, LinkedHashMap.class), null, null, yaml);
|
|
||||||
stream.close();
|
|
||||||
} else {
|
|
||||||
this.config = new YAMLSection(null, null, null, yaml);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Config Contents
|
|
||||||
*
|
|
||||||
* @return Config Contents
|
|
||||||
*/
|
|
||||||
public YAMLSection get() {
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set Config Contents
|
|
||||||
*
|
|
||||||
* @param value Value
|
|
||||||
*/
|
|
||||||
public void set(YAMLSection value) {
|
|
||||||
if (Util.isNull(value)) throw new NullPointerException();
|
|
||||||
config = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reload Config Contents
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void reload() throws IOException {
|
|
||||||
if (file.exists()) {
|
|
||||||
InputStream stream = new FileInputStream(file);
|
|
||||||
this.config = new YAMLSection((LinkedHashMap<String, ?>) yaml.loadAs(stream, LinkedHashMap.class), null, null, yaml);
|
|
||||||
stream.close();
|
|
||||||
} else {
|
|
||||||
this.config = new YAMLSection(null, null, null, yaml);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save Config Contents
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public void save() throws IOException {
|
|
||||||
if (!file.exists()) file.createNewFile();
|
|
||||||
FileWriter writer = new FileWriter(file);
|
|
||||||
yaml.dump(config.map, writer);
|
|
||||||
writer.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object object) {
|
|
||||||
if (object instanceof YAMLConfig) {
|
|
||||||
return get().equals(((YAMLConfig) object).get());
|
|
||||||
} else {
|
|
||||||
return super.equals(object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return yaml.dump(config.map);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static DumperOptions getDumperOptions() {
|
|
||||||
DumperOptions options = new DumperOptions();
|
|
||||||
options.setAllowUnicode(false);
|
|
||||||
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
|
||||||
options.setIndent(2);
|
|
||||||
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,397 +0,0 @@
|
||||||
package net.ME1312.SubServers.Bungee.Library.Config;
|
|
||||||
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
|
||||||
import net.md_5.bungee.api.ChatColor;
|
|
||||||
import org.yaml.snakeyaml.Yaml;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* YAML Value Class
|
|
||||||
*/
|
|
||||||
@SuppressWarnings({"unchecked", "unused"})
|
|
||||||
public class YAMLValue {
|
|
||||||
protected Object obj;
|
|
||||||
protected String label;
|
|
||||||
protected YAMLSection up;
|
|
||||||
private Yaml yaml;
|
|
||||||
|
|
||||||
protected YAMLValue(Object obj, YAMLSection up, String label, Yaml yaml) {
|
|
||||||
this.obj = obj;
|
|
||||||
this.label = label;
|
|
||||||
this.yaml = yaml;
|
|
||||||
this.up = up;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the YAML Section this Object was defined in
|
|
||||||
*
|
|
||||||
* @return YAML Section
|
|
||||||
*/
|
|
||||||
public YAMLSection getDefiningSection() {
|
|
||||||
return up;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Object
|
|
||||||
*
|
|
||||||
* @return Object
|
|
||||||
*/
|
|
||||||
public Object asObject() {
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Object as List
|
|
||||||
*
|
|
||||||
* @return List
|
|
||||||
*/
|
|
||||||
public List<?> asObjectList() {
|
|
||||||
return (List<?>) obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Object as Boolean
|
|
||||||
*
|
|
||||||
* @return Boolean
|
|
||||||
*/
|
|
||||||
public Boolean asBoolean() {
|
|
||||||
return (Boolean) obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Object as List
|
|
||||||
*
|
|
||||||
* @return List
|
|
||||||
*/
|
|
||||||
public List<Boolean> asBooleanList() {
|
|
||||||
return (List<Boolean>) obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Object as YAML Section
|
|
||||||
*
|
|
||||||
* @return YAML Section
|
|
||||||
*/
|
|
||||||
public YAMLSection asSection() {
|
|
||||||
if (obj != null) return new YAMLSection((Map<String, ?>) obj, up, label, yaml);
|
|
||||||
else return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Object as YAML Section List
|
|
||||||
*
|
|
||||||
* @return YAML Section List
|
|
||||||
*/
|
|
||||||
public List<YAMLSection> asSectionList() {
|
|
||||||
if (obj != null) {
|
|
||||||
List<YAMLSection> values = new ArrayList<YAMLSection>();
|
|
||||||
for (Map<String, ?> value : (List<? extends Map<String, ?>>) obj) {
|
|
||||||
values.add(new YAMLSection(value, null, null, yaml));
|
|
||||||
}
|
|
||||||
return values;
|
|
||||||
} else return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Object as Double
|
|
||||||
*
|
|
||||||
* @return Double
|
|
||||||
*/
|
|
||||||
public Double asDouble() {
|
|
||||||
return ((Number) obj).doubleValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Object as Double List
|
|
||||||
*
|
|
||||||
* @return Double List
|
|
||||||
*/
|
|
||||||
public List<Double> asDoubleList() {
|
|
||||||
return (List<Double>) obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Object as Float
|
|
||||||
*
|
|
||||||
* @return Float
|
|
||||||
*/
|
|
||||||
public Float asFloat() {
|
|
||||||
return ((Number) obj).floatValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Object as Float List
|
|
||||||
*
|
|
||||||
* @return Float List
|
|
||||||
*/
|
|
||||||
public List<Float> asFloatList() {
|
|
||||||
return (List<Float>) obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Object as Integer
|
|
||||||
*
|
|
||||||
* @return Integer
|
|
||||||
*/
|
|
||||||
public Integer asInt() {
|
|
||||||
return ((Number) obj).intValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Object as Integer List
|
|
||||||
*
|
|
||||||
* @return Integer List
|
|
||||||
*/
|
|
||||||
public List<Integer> asIntList() {
|
|
||||||
return (List<Integer>) obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Object as Long
|
|
||||||
*
|
|
||||||
* @return Long
|
|
||||||
*/
|
|
||||||
public Long asLong() {
|
|
||||||
return ((Number) obj).longValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Object as Long List
|
|
||||||
*
|
|
||||||
* @return Long List
|
|
||||||
*/
|
|
||||||
public List<Long> asLongList() {
|
|
||||||
return (List<Long>) obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a Short by Handle
|
|
||||||
*
|
|
||||||
* @return Short
|
|
||||||
*/
|
|
||||||
public Short asShort() {
|
|
||||||
return ((Number) obj).shortValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a Short List by Handle
|
|
||||||
*
|
|
||||||
* @return Short List
|
|
||||||
*/
|
|
||||||
public List<Short> asShortList() {
|
|
||||||
return (List<Short>) obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Object as Unparsed String
|
|
||||||
*
|
|
||||||
* @return Unparsed String
|
|
||||||
*/
|
|
||||||
public String asRawString() {
|
|
||||||
if (obj != null) return obj.toString();
|
|
||||||
else return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Object as Unparsed String List
|
|
||||||
*
|
|
||||||
* @return Unparsed String List
|
|
||||||
*/
|
|
||||||
public List<String> asRawStringList() {
|
|
||||||
if (obj != null) {
|
|
||||||
List<String> values = new ArrayList<String>();
|
|
||||||
for (Object value : (List<?>) obj) {
|
|
||||||
values.add(value.toString());
|
|
||||||
}
|
|
||||||
return values;
|
|
||||||
} else return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Object as String
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
public String asString() {
|
|
||||||
if (obj != null) return Util.unescapeJavaString(asRawString());
|
|
||||||
else return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Object as String List
|
|
||||||
*
|
|
||||||
* @return String List
|
|
||||||
*/
|
|
||||||
public List<String> asStringList() {
|
|
||||||
if (obj != null) {
|
|
||||||
List<String> values = new ArrayList<String>();
|
|
||||||
for (String value : asRawStringList()) {
|
|
||||||
values.add(Util.unescapeJavaString(value));
|
|
||||||
}
|
|
||||||
return values;
|
|
||||||
} else return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Object as Colored String
|
|
||||||
*
|
|
||||||
* @param color Color Char to parse
|
|
||||||
* @return Colored String
|
|
||||||
*/
|
|
||||||
public String asColoredString(char color) {
|
|
||||||
if (Util.isNull(color)) throw new NullPointerException();
|
|
||||||
if (obj != null) return ChatColor.translateAlternateColorCodes(color, asString());
|
|
||||||
else return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Object as Colored String List
|
|
||||||
*
|
|
||||||
* @param color Color Char to parse
|
|
||||||
* @return Colored String List
|
|
||||||
*/
|
|
||||||
public List<String> asColoredStringList(char color) {
|
|
||||||
if (obj != null) {
|
|
||||||
if (Util.isNull(color)) throw new NullPointerException();
|
|
||||||
List<String> values = new ArrayList<String>();
|
|
||||||
for (String value : asStringList()) {
|
|
||||||
values.add(ChatColor.translateAlternateColorCodes(color, value));
|
|
||||||
}
|
|
||||||
return values;
|
|
||||||
} else return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Object as UUID
|
|
||||||
*
|
|
||||||
* @return UUID
|
|
||||||
*/
|
|
||||||
public UUID asUUID() {
|
|
||||||
if (obj != null) return UUID.fromString(asRawString());
|
|
||||||
else return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Object as UUID List
|
|
||||||
*
|
|
||||||
* @return UUID List
|
|
||||||
*/
|
|
||||||
public List<UUID> asUUIDList() {
|
|
||||||
if (obj != null) {
|
|
||||||
List<UUID> values = new ArrayList<UUID>();
|
|
||||||
for (String value : (List<String>) obj) {
|
|
||||||
values.add(UUID.fromString(value));
|
|
||||||
}
|
|
||||||
return values;
|
|
||||||
} else return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Object as Version
|
|
||||||
*
|
|
||||||
* @return Version
|
|
||||||
*/
|
|
||||||
public Version asVersion() {
|
|
||||||
if (obj != null) return Version.fromString(asRawString());
|
|
||||||
else return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Object as Version List
|
|
||||||
*
|
|
||||||
* @return Version List
|
|
||||||
*/
|
|
||||||
public List<Version> asVersionList() {
|
|
||||||
if (obj != null) {
|
|
||||||
List<Version> values = new ArrayList<Version>();
|
|
||||||
for (String value : (List<String>) obj) {
|
|
||||||
values.add(Version.fromString(value));
|
|
||||||
}
|
|
||||||
return values;
|
|
||||||
} else return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if object is Null
|
|
||||||
*
|
|
||||||
* @return Null Status
|
|
||||||
*/
|
|
||||||
public boolean isNull() {
|
|
||||||
return obj == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if object is a Boolean
|
|
||||||
*
|
|
||||||
* @return Boolean Status
|
|
||||||
*/
|
|
||||||
public boolean isBoolean() {
|
|
||||||
return (obj instanceof Boolean);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if object is a YAML Section
|
|
||||||
*
|
|
||||||
* @return YAML Section Status
|
|
||||||
*/
|
|
||||||
public boolean isSection() {
|
|
||||||
return (obj instanceof Map);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if object is a List
|
|
||||||
*
|
|
||||||
* @return List Status
|
|
||||||
*/
|
|
||||||
public boolean isList() {
|
|
||||||
return (obj instanceof List);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if object is a Number
|
|
||||||
*
|
|
||||||
* @return Number Status
|
|
||||||
*/
|
|
||||||
public boolean isNumber() {
|
|
||||||
return (obj instanceof Number);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if object is a String
|
|
||||||
*
|
|
||||||
* @return String Status
|
|
||||||
*/
|
|
||||||
public boolean isString() {
|
|
||||||
return (obj instanceof String);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if object is a UUID
|
|
||||||
*
|
|
||||||
* @return UUID Status
|
|
||||||
*/
|
|
||||||
public boolean isUUID() {
|
|
||||||
return (obj instanceof String && !Util.isException(() -> UUID.fromString(asRawString())));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object object) {
|
|
||||||
if (obj == null) {
|
|
||||||
return object == null;
|
|
||||||
} else {
|
|
||||||
if (object instanceof YAMLValue) {
|
|
||||||
return obj.equals(((YAMLValue) object).obj);
|
|
||||||
} else {
|
|
||||||
return obj.equals(object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
if (obj != null) return obj.toString();
|
|
||||||
else return "null";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,562 @@
|
||||||
|
package net.ME1312.SubServers.Bungee.Library;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Config.YAMLConfig;
|
||||||
|
import net.ME1312.Galaxi.Library.Config.YAMLSection;
|
||||||
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
|
import net.ME1312.Galaxi.Library.Version.Version;
|
||||||
|
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
|
||||||
|
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SubServers Configuration Updater
|
||||||
|
*/
|
||||||
|
public class ConfigUpdater {
|
||||||
|
private static final Version UNSIGNED = new Version(new SimpleDateFormat("yy'w'ww'zz'").format(Calendar.getInstance().getTime()));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update SubServers' config.yml
|
||||||
|
*
|
||||||
|
* @param file File to bring up-to-date
|
||||||
|
*/
|
||||||
|
public static void updateConfig(File file) throws IOException {
|
||||||
|
YAMLConfig config = new YAMLConfig(file);
|
||||||
|
YAMLSection existing = config.get().clone();
|
||||||
|
YAMLSection updated = existing.clone();
|
||||||
|
YAMLSection rewritten = new YAMLSection();
|
||||||
|
|
||||||
|
Version was = existing.getMap("Settings", new ObjectMap<>()).getVersion("Version", new Version(0));
|
||||||
|
Version now = SubAPI.getInstance().getWrapperBuild();
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
if (now == null) now = UNSIGNED;
|
||||||
|
if (!existing.contains("Settings") || !existing.getMap("Settings").contains("Version")) {
|
||||||
|
YAMLSection hosts = new YAMLSection();
|
||||||
|
YAMLSection host = new YAMLSection();
|
||||||
|
host.set("Enabled", true);
|
||||||
|
host.set("Display", "Default");
|
||||||
|
hosts.set("~", host);
|
||||||
|
updated.set("Hosts", hosts);
|
||||||
|
|
||||||
|
i++;
|
||||||
|
Logger.get("SubServers").info("Created ./SubServers/config.yml");
|
||||||
|
} else {
|
||||||
|
if (was.compareTo(new Version("19w17a")) <= 0) {
|
||||||
|
if (existing.getMap("Settings", new YAMLSection()).contains("Log-Creator")) for (String name : existing.getMap("Hosts", new YAMLSection()).getKeys())
|
||||||
|
updated.getMap("Hosts").getMap(name).safeSet("Log-Creator", existing.getMap("Settings").getBoolean("Log-Creator"));
|
||||||
|
|
||||||
|
if (existing.getMap("Settings", new YAMLSection()).contains("SubData") && !existing.getMap("Settings", new YAMLSection()).getMap("SubData").contains("Encryption"))
|
||||||
|
updated.getMap("Settings").getMap("SubData").set("Encryption", "NONE");
|
||||||
|
|
||||||
|
if (existing.contains("Servers")) {
|
||||||
|
YAMLConfig sc = new YAMLConfig(new File(file.getParentFile(), "servers.yml"));
|
||||||
|
YAMLSection settings = new YAMLSection();
|
||||||
|
settings.set("Version", was.toString());
|
||||||
|
settings.set("Run-On-Launch-Timeout", (existing.getMap("Settings", new YAMLSection()).contains("Run-On-Launch-Timeout"))?existing.getMap("Settings").getInt("Run-On-Launch-Timeout"):0);
|
||||||
|
sc.get().safeSet("Settings", settings);
|
||||||
|
|
||||||
|
sc.get().safeSet("Servers", new YAMLSection());
|
||||||
|
sc.get().getMap("Servers").safeSetAll(existing.getMap("Servers"));
|
||||||
|
Logger.get("SubServers").info("Created ./SubServers/servers.yml (using existing data)");
|
||||||
|
sc.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
existing = updated.clone();
|
||||||
|
i++;
|
||||||
|
} if (was.compareTo(new Version("19w35c")) <= 0) {
|
||||||
|
if (existing.getMap("Settings", new YAMLSection()).contains("SubData")) {
|
||||||
|
LinkedList<String> whitelist = new LinkedList<>();
|
||||||
|
LinkedList<String> newWhitelist = new LinkedList<>();
|
||||||
|
whitelist.addAll(existing.getMap("Settings", new YAMLSection()).getMap("SubData", new YAMLSection()).getStringList("Allowed-Connections", Collections.emptyList()));
|
||||||
|
whitelist.addAll(existing.getMap("Settings", new YAMLSection()).getMap("SubData", new YAMLSection()).getStringList("Whitelist", Collections.emptyList()));
|
||||||
|
|
||||||
|
boolean warnPls = false;
|
||||||
|
for (String address : whitelist) {
|
||||||
|
Matcher regAddress = Pattern.compile("^(\\d{1,3}|%)\\.(\\d{1,3}|%)\\.(\\d{1,3}|%)\\.(\\d{1,3}|%)$").matcher(address);
|
||||||
|
if (regAddress.find()) {
|
||||||
|
StringBuilder newAddress = new StringBuilder();
|
||||||
|
int subnet = -1;
|
||||||
|
boolean warn = false;
|
||||||
|
for (int o = 1; o <= 4; o++) {
|
||||||
|
if (o > 1) newAddress.append('.');
|
||||||
|
if (subnet == -1) {
|
||||||
|
if (!regAddress.group(o).equals("%")) {
|
||||||
|
newAddress.append(regAddress.group(o));
|
||||||
|
} else {
|
||||||
|
subnet = 8 * (o - 1);
|
||||||
|
newAddress.append('0');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!regAddress.group(o).equals("%")) warn = warnPls = true;
|
||||||
|
newAddress.append('0');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (subnet < 0) subnet = 32;
|
||||||
|
if (warn) Logger.get("SubServers").warning("Updating non-standard mask: " + address);
|
||||||
|
newAddress.append('/');
|
||||||
|
newAddress.append(subnet);
|
||||||
|
newWhitelist.add(newAddress.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updated.getMap("Settings").getMap("SubData").set("Whitelist", newWhitelist);
|
||||||
|
if (warnPls) Logger.get("SubServers").warning("Non-standard masks have been updated. This may expose SubData to unintended networks!");
|
||||||
|
}
|
||||||
|
|
||||||
|
existing = updated.clone();
|
||||||
|
i++;
|
||||||
|
} if (was.compareTo(new Version("20w08d")) <= 0) {
|
||||||
|
if (existing.contains("Hosts")) {
|
||||||
|
for (String name : existing.getMap("Hosts", new YAMLSection()).getKeys()) {
|
||||||
|
if (existing.getMap("Hosts").getMap(name).getString("Driver", "BUILT_IN").replace('-', '_').replace(' ', '_').equalsIgnoreCase("BUILT_IN"))
|
||||||
|
updated.getMap("Hosts").getMap(name).set("Driver", "VIRTUAL");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
existing = updated.clone();
|
||||||
|
i++;
|
||||||
|
} if (was.compareTo(new Version("20w34a")) <= 0) {
|
||||||
|
if (existing.getMap("Settings", new YAMLSection()).contains("Smart-Fallback") && existing.getMap("Settings").isBoolean("Smart-Fallback")) {
|
||||||
|
YAMLSection smart_fallback = new YAMLSection();
|
||||||
|
smart_fallback.set("Enabled", existing.getMap("Settings").getBoolean("Smart-Fallback"));
|
||||||
|
smart_fallback.set("Fallback", existing.getMap("Settings").getBoolean("Smart-Fallback"));
|
||||||
|
updated.getMap("Settings").set("Smart-Fallback", smart_fallback);
|
||||||
|
}
|
||||||
|
if (existing.getMap("Settings", new YAMLSection()).contains("Override-Bungee-Commands") && existing.getMap("Settings").isBoolean("Override-Bungee-Commands")) {
|
||||||
|
List<String> overrides = new LinkedList<>();
|
||||||
|
if (!existing.getMap("Settings").getBoolean("Override-Bungee-Commands")) {
|
||||||
|
overrides.add("/server");
|
||||||
|
overrides.add("/glist");
|
||||||
|
}
|
||||||
|
updated.getMap("Settings").set("Disabled-Overrides", overrides);
|
||||||
|
}
|
||||||
|
|
||||||
|
existing = updated.clone();
|
||||||
|
i++;
|
||||||
|
} else if (was.compareTo(new Version("21w27b")) <= 0) {
|
||||||
|
|
||||||
|
//existing = updated.clone();
|
||||||
|
i++;
|
||||||
|
|
||||||
|
}// if (was.compareTo(new Version("99w99a")) <= 0) {
|
||||||
|
// // do something
|
||||||
|
// existing = updated.clone();
|
||||||
|
// i++
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (i > 0) Logger.get("SubServers").info("Updated ./SubServers/config.yml (" + i + " pass" + ((i != 1)?"es":"") + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i > 0) {
|
||||||
|
YAMLSection settings = new YAMLSection();
|
||||||
|
settings.set("Version", ((now.compareTo(was) <= 0)?was:now).toString());
|
||||||
|
if (updated.getMap("Settings", new YAMLSection()).contains("RPEC-Check-Interval")) settings.set("RPEC-Check-Interval", updated.getMap("Settings").getString("RPEC-Check-Interval"));
|
||||||
|
settings.set("Strict-Server-Linking", updated.getMap("Settings", new YAMLSection()).getBoolean("Strict-Server-Linking", true));
|
||||||
|
settings.set("Disabled-Overrides", updated.getMap("Settings", new YAMLSection()).getStringList("Disabled-Overrides", Collections.emptyList()));
|
||||||
|
|
||||||
|
YAMLSection smart_fallback = new YAMLSection();
|
||||||
|
smart_fallback.set("Enabled", updated.getMap("Settings", new YAMLSection()).getMap("Smart-Fallback", new YAMLSection()).getBoolean("Enabled", true));
|
||||||
|
smart_fallback.set("Fallback", updated.getMap("Settings", new YAMLSection()).getMap("Smart-Fallback", new YAMLSection()).getBoolean("Fallback", true));
|
||||||
|
smart_fallback.set("Reconnect", updated.getMap("Settings", new YAMLSection()).getMap("Smart-Fallback", new YAMLSection()).getBoolean("Reconnect", false));
|
||||||
|
smart_fallback.set("DNS-Forward", updated.getMap("Settings", new YAMLSection()).getMap("Smart-Fallback", new YAMLSection()).getBoolean("DNS-Forward", false));
|
||||||
|
settings.set("Smart-Fallback", smart_fallback);
|
||||||
|
|
||||||
|
YAMLSection upnp = new YAMLSection();
|
||||||
|
upnp.set("Forward-Proxy", updated.getMap("Settings", new YAMLSection()).getMap("UPnP", new YAMLSection()).getBoolean("Forward-Proxy", true));
|
||||||
|
upnp.set("Forward-SubData", updated.getMap("Settings", new YAMLSection()).getMap("UPnP", new YAMLSection()).getBoolean("Forward-SubData", false));
|
||||||
|
upnp.set("Forward-Servers", updated.getMap("Settings", new YAMLSection()).getMap("UPnP", new YAMLSection()).getBoolean("Forward-Servers", false));
|
||||||
|
settings.set("UPnP", upnp);
|
||||||
|
|
||||||
|
YAMLSection subdata = new YAMLSection();
|
||||||
|
subdata.set("Address", updated.getMap("Settings", new YAMLSection()).getMap("SubData", new YAMLSection()).getString("Address", "127.0.0.1:4391"));
|
||||||
|
if (updated.getMap("Settings", new YAMLSection()).getMap("SubData", new YAMLSection()).contains("Password")) subdata.set("Password", updated.getMap("Settings").getMap("SubData").getString("Password"));
|
||||||
|
subdata.set("Encryption", updated.getMap("Settings", new YAMLSection()).getMap("SubData", new YAMLSection()).getString("Encryption", "RSA/AES"));
|
||||||
|
subdata.set("Whitelist", updated.getMap("Settings", new YAMLSection()).getMap("SubData", new YAMLSection()).getStringList("Whitelist", Collections.emptyList()));
|
||||||
|
settings.set("SubData", subdata);
|
||||||
|
|
||||||
|
rewritten.set("Settings", settings);
|
||||||
|
|
||||||
|
|
||||||
|
YAMLSection hosts = new YAMLSection();
|
||||||
|
for (String name : updated.getMap("Hosts", new YAMLSection()).getKeys()) {
|
||||||
|
YAMLSection host = new YAMLSection();
|
||||||
|
host.set("Enabled", updated.getMap("Hosts").getMap(name).getBoolean("Enabled", false));
|
||||||
|
host.set("Display", updated.getMap("Hosts").getMap(name).getString("Display", ""));
|
||||||
|
host.set("Driver", updated.getMap("Hosts").getMap(name).getString("Driver", "VIRTUAL"));
|
||||||
|
host.set("Address", updated.getMap("Hosts").getMap(name).getString("Address", "127.0.0.1"));
|
||||||
|
host.set("Port-Range", updated.getMap("Hosts").getMap(name).getString("Port-Range", "25500-25559"));
|
||||||
|
host.set("Directory", updated.getMap("Hosts").getMap(name).getString("Directory", (host.getString("Driver").equalsIgnoreCase("VIRTUAL"))?"./SubServers/Servers":"./Servers"));
|
||||||
|
host.set("Git-Bash", updated.getMap("Hosts").getMap(name).getString("Git-Bash", "%ProgramFiles%\\Git"));
|
||||||
|
host.set("Log-Creator", updated.getMap("Hosts").getMap(name).getBoolean("Log-Creator", true));
|
||||||
|
if (updated.getMap("Hosts").getMap(name).contains("Extra")) host.set("Extra", updated.getMap("Hosts").getMap(name).getMap("Extra"));
|
||||||
|
hosts.set(name, host);
|
||||||
|
}
|
||||||
|
rewritten.set("Hosts", hosts);
|
||||||
|
|
||||||
|
config.set(rewritten);
|
||||||
|
config.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update SubServers' servers.yml
|
||||||
|
*
|
||||||
|
* @param file File to bring up-to-date
|
||||||
|
*/
|
||||||
|
public static void updateServers(File file) throws IOException {
|
||||||
|
YAMLConfig config = new YAMLConfig(file);
|
||||||
|
YAMLSection existing = config.get().clone();
|
||||||
|
YAMLSection updated = existing.clone();
|
||||||
|
YAMLSection rewritten = new YAMLSection();
|
||||||
|
|
||||||
|
Version was = existing.getMap("Settings", new ObjectMap<>()).getVersion("Version", new Version(0));
|
||||||
|
Version now = SubAPI.getInstance().getWrapperBuild();
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
if (now == null) now = UNSIGNED;
|
||||||
|
if (!existing.contains("Settings") || !existing.getMap("Settings").contains("Version")) {
|
||||||
|
YAMLSection servers = new YAMLSection();
|
||||||
|
servers.set("Example", new YAMLSection());
|
||||||
|
updated.set("Servers", servers);
|
||||||
|
|
||||||
|
i++;
|
||||||
|
Logger.get("SubServers").info("Created ./SubServers/servers.yml");
|
||||||
|
} else {
|
||||||
|
if (was.compareTo(new Version("19w17a")) <= 0) {
|
||||||
|
if (existing.contains("Servers")) {
|
||||||
|
for (String name : existing.getMap("Servers", new YAMLSection()).getKeys()) {
|
||||||
|
if (existing.getMap("Servers").getMap(name).getBoolean("Auto-Restart", true))
|
||||||
|
updated.getMap("Servers").getMap(name).safeSet("Stop-Action", "RESTART");
|
||||||
|
|
||||||
|
if (existing.getMap("Servers").getMap(name).getString("Stop-Action", "NONE").equalsIgnoreCase("DELETE_SERVER"))
|
||||||
|
updated.getMap("Servers").getMap(name).set("Stop-Action", "RECYCLE_SERVER");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
existing = updated.clone();
|
||||||
|
i++;
|
||||||
|
}// if (was.compareTo(new Version("99w99a")) <= 0) {
|
||||||
|
// // do something
|
||||||
|
// i++
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (i > 0) Logger.get("SubServers").info("Updated ./SubServers/servers.yml (" + i + " pass" + ((i != 1)?"es":"") + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i > 0) {
|
||||||
|
YAMLSection settings = new YAMLSection();
|
||||||
|
settings.set("Version", ((now.compareTo(was) <= 0)?was:now).toString());
|
||||||
|
settings.set("Run-On-Launch-Timeout", updated.getMap("Settings", new YAMLSection()).getInt("Run-On-Launch-Timeout", 0));
|
||||||
|
|
||||||
|
rewritten.set("Settings", settings);
|
||||||
|
|
||||||
|
|
||||||
|
YAMLSection servers = new YAMLSection();
|
||||||
|
for (String name : updated.getMap("Servers", new YAMLSection()).getKeys()) {
|
||||||
|
YAMLSection server = new YAMLSection();
|
||||||
|
server.set("Enabled", updated.getMap("Servers").getMap(name).getBoolean("Enabled", false));
|
||||||
|
server.set("Display", updated.getMap("Servers").getMap(name).getString("Display", ""));
|
||||||
|
server.set("Host", updated.getMap("Servers").getMap(name).getString("Host", "~"));
|
||||||
|
if (updated.getMap("Servers").getMap(name).contains("Template")) server.set("Template", updated.getMap("Servers").getMap(name).getString("Template"));
|
||||||
|
server.set("Group", updated.getMap("Servers").getMap(name).getStringList("Groups", Collections.emptyList()));
|
||||||
|
server.set("Port", updated.getMap("Servers").getMap(name).getInt("Port", 25567));
|
||||||
|
server.set("Motd", updated.getMap("Servers").getMap(name).getString("Motd", "Some SubServer"));
|
||||||
|
server.set("Log", updated.getMap("Servers").getMap(name).getBoolean("Log", true));
|
||||||
|
server.set("Directory", updated.getMap("Servers").getMap(name).getString("Directory", "." + File.separatorChar));
|
||||||
|
server.set("Executable", updated.getMap("Servers").getMap(name).getString("Executable", "java -Xmx1024M -Djline.terminal=jline.UnsupportedTerminal -jar Spigot.jar"));
|
||||||
|
server.set("Stop-Command", updated.getMap("Servers").getMap(name).getString("Stop-Command", "stop"));
|
||||||
|
server.set("Stop-Action", updated.getMap("Servers").getMap(name).getString("Stop-Action", "NONE"));
|
||||||
|
server.set("Run-On-Launch", updated.getMap("Servers").getMap(name).getBoolean("Run-On-Launch", false));
|
||||||
|
server.set("Restricted", updated.getMap("Servers").getMap(name).getBoolean("Restricted", false));
|
||||||
|
server.set("Incompatible", updated.getMap("Servers").getMap(name).getStringList("Incompatible", Collections.emptyList()));
|
||||||
|
server.set("Hidden", updated.getMap("Servers").getMap(name).getBoolean("Hidden", false));
|
||||||
|
if (updated.getMap("Servers").getMap(name).contains("Extra")) server.set("Extra", updated.getMap("Servers").getMap(name).getMap("Extra"));
|
||||||
|
servers.set(name, server);
|
||||||
|
}
|
||||||
|
rewritten.set("Servers", servers);
|
||||||
|
|
||||||
|
config.set(rewritten);
|
||||||
|
config.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update SubServers' lang.yml
|
||||||
|
*
|
||||||
|
* @param file File to bring up-to-date
|
||||||
|
*/
|
||||||
|
public static void updateLang(File file) throws IOException {
|
||||||
|
YAMLConfig config = new YAMLConfig(file);
|
||||||
|
YAMLSection existing = config.get().clone();
|
||||||
|
YAMLSection updated = existing.clone();
|
||||||
|
YAMLSection rewritten = new YAMLSection();
|
||||||
|
|
||||||
|
Version was = existing.getMap("Settings", new ObjectMap<>()).getVersion("Version", new Version(0));
|
||||||
|
Version now = SubAPI.getInstance().getWrapperBuild();
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
if (now == null) now = UNSIGNED;
|
||||||
|
if (!existing.contains("Settings") || !existing.getMap("Settings").contains("Version")) {
|
||||||
|
|
||||||
|
i++;
|
||||||
|
Logger.get("SubServers").info("Created ./SubServers/lang.yml");
|
||||||
|
} else {
|
||||||
|
if (was.compareTo(new Version("19w22b")) <= 0) {
|
||||||
|
if (existing.contains("Lang")) {
|
||||||
|
updated.getMap("Lang").remove("Interface.Host-Admin.SubServers");
|
||||||
|
updated.getMap("Lang").remove("Interface.Server-Admin.Command");
|
||||||
|
}
|
||||||
|
|
||||||
|
existing = updated.clone();
|
||||||
|
i++;
|
||||||
|
} if (was.compareTo(new Version("20w08d")) <= 0) {
|
||||||
|
if (existing.contains("Lang")) {
|
||||||
|
LinkedList<String> keys = new LinkedList<>(existing.getMap("Lang").getKeys());
|
||||||
|
for (String key : keys) if (key.startsWith("Command.")) {
|
||||||
|
updated.getMap("Lang").remove(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
existing = updated.clone();
|
||||||
|
i++;
|
||||||
|
} if (was.compareTo(new Version("22w07c")) <= 0) {
|
||||||
|
if (existing.contains("Lang")) {
|
||||||
|
updated.getMap("Lang").remove("Command.Teleport");
|
||||||
|
}
|
||||||
|
|
||||||
|
existing = updated.clone();
|
||||||
|
i++;
|
||||||
|
}// if (was.compareTo(new Version("99w99a")) <= 0) {
|
||||||
|
// // do something
|
||||||
|
// i++
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (i > 0) Logger.get("SubServers").info("Updated ./SubServers/lang.yml (" + i + " pass" + ((i != 1)?"es":"") + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i > 0) {
|
||||||
|
YAMLSection settings = new YAMLSection();
|
||||||
|
settings.set("Version", ((now.compareTo(was) <= 0)?was:now).toString());
|
||||||
|
|
||||||
|
rewritten.set("Settings", settings);
|
||||||
|
|
||||||
|
LinkedHashMap<String, String> def = new LinkedHashMap<String, String>();
|
||||||
|
def.put("Bungee.Feature.Smart-Fallback", "&6Returning from $str$: &r$msg$");
|
||||||
|
def.put("Bungee.Feature.Smart-Fallback.Result", "&6You are now on $str$.");
|
||||||
|
def.put("Bungee.Restricted", "&cYou don't have permission to access this server.");
|
||||||
|
def.put("Bungee.Ping.Offline", "&6&l[&e&lWarning&6&l] &7Backend server(s) are not running");
|
||||||
|
def.put("Bungee.Server.Current", "&6You are currently connected to $str$");
|
||||||
|
def.put("Bungee.Server.Available", "&6You may connect to the following servers at this time:");
|
||||||
|
def.put("Bungee.Server.List", "&6$str$");
|
||||||
|
def.put("Bungee.Server.Hover", "$int$ player(s)\\n&oClick to connect to the server");
|
||||||
|
def.put("Bungee.Server.Divider", "&6, ");
|
||||||
|
def.put("Bungee.Server.Offline", "&cThe specified server is not currently running.");
|
||||||
|
def.put("Bungee.Server.Invalid", "&cThe specified server does not exist.");
|
||||||
|
def.put("Bungee.List.Format", "&a[$str$] &e($int$)&r: ");
|
||||||
|
def.put("Bungee.List.List", "&f$str$");
|
||||||
|
def.put("Bungee.List.Divider", "&f, ");
|
||||||
|
def.put("Bungee.List.Total", "Total players online: $int$");
|
||||||
|
def.put("Signs.Create", "&aSubServers &2&l\\u00BB&a Server sign activated");
|
||||||
|
def.put("Signs.Delete", "&aSubServers &2&l\\u00BB&a Server sign removed");
|
||||||
|
def.put("Signs.Text.Unknown", "&f&oSubServers\\n&3$str$\\n&7Unknown Status\\n&8\\u2022 \\u2022 \\u2022 \\u2022 \\u2022 \\u2022 \\u2022");
|
||||||
|
def.put("Signs.Text.Offline", "&c&oSubServers\\n&3$str$\\n&4Offline\\n&7Click to Start");
|
||||||
|
def.put("Signs.Text.Starting", "&e&oSubServers\\n&3$str$\\n&6Starting\\n&8\\u2022 \\u2022 \\u2022 \\u2022 \\u2022 \\u2022 \\u2022");
|
||||||
|
def.put("Signs.Text.Online", "&a&oSubServers\\n&3$str$\\n&2$int$ Online\\n&7Click to Join");
|
||||||
|
def.put("Signs.Text.Stopping", "&e&oSubServers\\n&3$str$\\n&6Stopping\\n&8\\u2022 \\u2022 \\u2022 \\u2022 \\u2022 \\u2022 \\u2022");
|
||||||
|
def.put("Command.Generic.Player-Only", "&cSubServers &4&l\\u00BB&c The console cannot perform this command");
|
||||||
|
def.put("Command.Generic.Console-Only", "&cSubServers &4&l\\u00BB&c This command is for console use only");
|
||||||
|
def.put("Command.Generic.Usage", "&7SubServers &8&l\\u00BB&7 Usage: &f$str$");
|
||||||
|
def.put("Command.Generic.Exception", "&cSubServers &4&l\\u00BB&c An unexpected exception has occurred while parsing this command");
|
||||||
|
def.put("Command.Generic.Invalid-Subcommand", "&cSubServers &4&l\\u00BB&c Unknown sub-command: &4$str$");
|
||||||
|
def.put("Command.Generic.Invalid-Permission", "&cSubServers &4&l\\u00BB&c You need &4&n$str$&c to use this command");
|
||||||
|
def.put("Command.Generic.Invalid-Select-Permission", "&cSubServers &4&l\\u00BB&c You don't have permission to select &4$str$");
|
||||||
|
def.put("Command.Generic.Unknown-Proxy", "&cSubServers &4&l\\u00BB&c There is no proxy named &4$str$");
|
||||||
|
def.put("Command.Generic.Unknown-Host", "&cSubServers &4&l\\u00BB&c There is no host named &4$str$");
|
||||||
|
def.put("Command.Generic.Unknown-Group", "&cSubServers &4&l\\u00BB&c There is no group named &4$str$");
|
||||||
|
def.put("Command.Generic.Unknown-Server", "&cSubServers &4&l\\u00BB&c There is no server named &4$str$");
|
||||||
|
def.put("Command.Generic.Unknown-SubServer", "&cSubServers &4&l\\u00BB&c There is no subserver named &4$str$");
|
||||||
|
def.put("Command.Generic.Unknown-Player", "&cSubServers &4&l\\u00BB&c There is no player named &4$str$");
|
||||||
|
def.put("Command.Generic.No-Servers-On-Host", "&7SubServers &8&l\\u00BB&7 There are no servers on host &f$str$");
|
||||||
|
def.put("Command.Generic.No-SubServers-On-Host", "&7SubServers &8&l\\u00BB&7 There are no subservers on host &f$str$");
|
||||||
|
def.put("Command.Generic.No-Servers-In-Group", "&7SubServers &8&l\\u00BB&7 There are no servers in group &f$str$");
|
||||||
|
def.put("Command.Generic.No-SubServers-In-Group", "&7SubServers &8&l\\u00BB&7 There are no subservers in group &f$str$");
|
||||||
|
def.put("Command.Generic.No-Servers-Selected", "&cSubServers &4&l\\u00BB&c No servers were selected");
|
||||||
|
def.put("Command.Generic.No-SubServers-Selected", "&cSubServers &4&l\\u00BB&c No subservers were selected");
|
||||||
|
def.put("Command.Help.Header", "&7SubServers &8&l\\u00BB&7 Command Help:");
|
||||||
|
def.put("Command.Help.Help", " &7Help:&f $str$");
|
||||||
|
def.put("Command.Help.List", " &7List:&f $str$");
|
||||||
|
def.put("Command.Help.Version", " &7Version:&f $str$");
|
||||||
|
def.put("Command.Help.Info", " &7Info:&f $str$");
|
||||||
|
def.put("Command.Help.Host.Create", " &7Create Server:&f $str$");
|
||||||
|
def.put("Command.Help.SubServer.Start", " &7Start Server:&f $str$");
|
||||||
|
def.put("Command.Help.SubServer.Restart", " &7Restart Server:&f $str$");
|
||||||
|
def.put("Command.Help.SubServer.Stop", " &7Stop Server:&f $str$");
|
||||||
|
def.put("Command.Help.SubServer.Terminate", " &7Terminate Server:&f $str$");
|
||||||
|
def.put("Command.Help.SubServer.Command", " &7Command Server:&f $str$");
|
||||||
|
def.put("Command.Help.SubServer.Update", " &7Update Server:&f $str$");
|
||||||
|
def.put("Command.Version", "&7SubServers &8&l\\u00BB&7 These are the platforms and versions that are running &f$str$&7:");
|
||||||
|
def.put("Command.Version.Outdated", "&7$name$ &f$str$ &7is available. You are $int$ version(s) behind.");
|
||||||
|
def.put("Command.Version.Latest", "&7You are on the latest version.");
|
||||||
|
def.put("Command.List.Group-Header", "&7SubServers &8&l\\u00BB&7 Group/Server List:");
|
||||||
|
def.put("Command.List.Host-Header", "&7SubServers &8&l\\u00BB&7 Host/SubServer List:");
|
||||||
|
def.put("Command.List.Server-Header", "&7SubServers &8&l\\u00BB&7 Server List:");
|
||||||
|
def.put("Command.List.Proxy-Header", "&7SubServers &8&l\\u00BB&7 Proxy List:");
|
||||||
|
def.put("Command.List.Header", "&7: ");
|
||||||
|
def.put("Command.List.Divider", "&7, ");
|
||||||
|
def.put("Command.List.Empty", "&7(none)");
|
||||||
|
def.put("Command.Info", "&7SubServers &8&l\\u00BB&7 Info on $str$: &r");
|
||||||
|
def.put("Command.Info.Unknown", "&cSubServers &4&l\\u00BB&c There is no object with that name");
|
||||||
|
def.put("Command.Info.Unknown-Type", "&cSubServers &4&l\\u00BB&c There is no object type with that name");
|
||||||
|
def.put("Command.Info.Unknown-Proxy", "&cSubServers &4&l\\u00BB&c There is no proxy with that name");
|
||||||
|
def.put("Command.Info.Unknown-Host", "&cSubServers &4&l\\u00BB&c There is no host with that name");
|
||||||
|
def.put("Command.Info.Unknown-Group", "&cSubServers &4&l\\u00BB&c There is no group with that name");
|
||||||
|
def.put("Command.Info.Unknown-Server", "&cSubServers &4&l\\u00BB&c There is no server with that name");
|
||||||
|
def.put("Command.Info.Unknown-Player", "&cSubServers &4&l\\u00BB&c There is no player with that name");
|
||||||
|
def.put("Command.Info.Format", " -> &7$str$&7: &r");
|
||||||
|
def.put("Command.Info.List", " - ");
|
||||||
|
def.put("Command.Start", "&aSubServers &2&l\\u00BB&a Started &2$int$&a subserver(s)");
|
||||||
|
def.put("Command.Start.Disappeared", "&cSubServers &4&l\\u00BB&c Subserver &4$str$&c has disappeared");
|
||||||
|
def.put("Command.Start.Host-Unavailable", "&cSubServers &4&l\\u00BB&c The host for &4$str$&c is not available");
|
||||||
|
def.put("Command.Start.Host-Disabled", "&cSubServers &4&l\\u00BB&c The host for &4$str$&c is not enabled");
|
||||||
|
def.put("Command.Start.Server-Unavailable", "&cSubServers &4&l\\u00BB&c Subserver &4$str$&c is not available");
|
||||||
|
def.put("Command.Start.Server-Disabled", "&cSubServers &4&l\\u00BB&c Subserver &4$str$&c is not enabled");
|
||||||
|
def.put("Command.Start.Server-Incompatible", "&cSubServers &4&l\\u00BB&c Subserver &4$str$&c cannot start while incompatible server(s) are running");
|
||||||
|
def.put("Command.Start.Running", "&7SubServers &8&l\\u00BB&7 &f$int$&7 subserver(s) were already running");
|
||||||
|
def.put("Command.Restart", "&aSubServers &2&l\\u00BB&a Restarting &2$int$&a subserver(s)");
|
||||||
|
def.put("Command.Restart.Disappeared", "&cSubServers &4&l\\u00BB&c Could not restart server: Subserver &4$str$&c has disappeared");
|
||||||
|
def.put("Command.Restart.Host-Unavailable", "&cSubServers &4&l\\u00BB&c Could not restart server: The host for &4$str$&c is no longer available");
|
||||||
|
def.put("Command.Restart.Host-Disabled", "&cSubServers &4&l\\u00BB&c Could not restart server: The host for &4$str$&c is no longer enabled");
|
||||||
|
def.put("Command.Restart.Server-Unavailable", "&cSubServers &4&l\\u00BB&c Could not restart server: Subserver &4$str$&c is no longer available");
|
||||||
|
def.put("Command.Restart.Server-Disabled", "&cSubServers &4&l\\u00BB&c Could not restart server: Subserver &4$str$&c is no longer enabled");
|
||||||
|
def.put("Command.Restart.Server-Incompatible", "&cSubServers &4&l\\u00BB&c Could not restart server: Subserver &4$str$&c cannot start while incompatible server(s) are running");
|
||||||
|
def.put("Command.Stop", "&aSubServers &2&l\\u00BB&a Stopping &2$int$&a subserver(s)");
|
||||||
|
def.put("Command.Stop.Disappeared", "&cSubServers &4&l\\u00BB&c Subserver &4$str$&c has disappeared");
|
||||||
|
def.put("Command.Stop.Not-Running", "&7SubServers &8&l\\u00BB&7 &f$int$&7 subserver(s) were already offline");
|
||||||
|
def.put("Command.Terminate", "&aSubServers &2&l\\u00BB&a Terminated &2$int$&a subserver(s)");
|
||||||
|
def.put("Command.Terminate.Disappeared", "&cSubServers &4&l\\u00BB&c Subserver &4$str$&c has disappeared");
|
||||||
|
def.put("Command.Terminate.Not-Running", "&7SubServers &8&l\\u00BB&7 &f$int$&7 subserver(s) were already offline");
|
||||||
|
def.put("Command.Command", "&aSubServers &2&l\\u00BB&a Sent command to &2$int$&a server(s)");
|
||||||
|
def.put("Command.Command.Disappeared", "&cSubServers &4&l\\u00BB&c Server &4$str$&c has disappeared");
|
||||||
|
def.put("Command.Command.No-Command", "&cSubServers &4&l\\u00BB&c No command was entered");
|
||||||
|
def.put("Command.Command.Not-Running", "&7SubServers &8&l\\u00BB&7 &f$int$&7 server(s) were unavailable");
|
||||||
|
def.put("Command.Creator", "&aSubServers &2&l\\u00BB&a Creating subserver &2$str$&a");
|
||||||
|
def.put("Command.Creator.Exists", "&cSubServers &4&l\\u00BB&c There is already a subserver with that name");
|
||||||
|
def.put("Command.Creator.Unknown-Host", "&cSubServers &4&l\\u00BB&c There is no host with that name");
|
||||||
|
def.put("Command.Creator.Host-Unavailable", "&cSubServers &4&l\\u00BB&c That host is not available");
|
||||||
|
def.put("Command.Creator.Host-Disabled", "&cSubServers &4&l\\u00BB&c That host is not enabled");
|
||||||
|
def.put("Command.Creator.Unknown-Template", "&cSubServers &4&l\\u00BB&c There is no template with that name");
|
||||||
|
def.put("Command.Creator.Template-Disabled", "&cSubServers &4&l\\u00BB&c That template is not enabled");
|
||||||
|
def.put("Command.Creator.Template-Invalid", "&cSubServers &4&l\\u00BB&c That template does not support subserver updating");
|
||||||
|
def.put("Command.Creator.Version-Required", "&cSubServers &4&l\\u00BB&c That template requires a Minecraft version to be specified");
|
||||||
|
def.put("Command.Creator.Invalid-Port", "&cSubServers &4&l\\u00BB&c Invalid port number");
|
||||||
|
def.put("Command.Update", "&aSubServers &2&l\\u00BB&a Updating &2$int$&a subserver(s)");
|
||||||
|
def.put("Command.Update.Disappeared", "&cSubServers &4&l\\u00BB&c Subserver &4$str$&c has disappeared");
|
||||||
|
def.put("Command.Update.Host-Unavailable", "&cSubServers &4&l\\u00BB&c The host for &4$str$&c is not available");
|
||||||
|
def.put("Command.Update.Host-Disabled", "&cSubServers &4&l\\u00BB&c The host for &4$str$&c is not enabled");
|
||||||
|
def.put("Command.Update.Server-Unavailable", "&cSubServers &4&l\\u00BB&c Subserver &4$str$&c is not available");
|
||||||
|
def.put("Command.Update.Running", "&cSubServers &4&l\\u00BB&c Cannot update &4$str$&c while it is still running");
|
||||||
|
def.put("Command.Update.Unknown-Template", "&cSubServers &4&l\\u00BB&c We don't know which template created &4$str$");
|
||||||
|
def.put("Command.Update.Template-Disabled", "&cSubServers &4&l\\u00BB&c The template that created &4$str$&c is not enabled");
|
||||||
|
def.put("Command.Update.Template-Invalid", "&cSubServers &4&l\\u00BB&c The template that created &4$str$&c does not support subserver updating");
|
||||||
|
def.put("Command.Update.Version-Required", "&cSubServers &4&l\\u00BB&c The template that created &4$str$&c requires a Minecraft version to be specified");
|
||||||
|
def.put("Command.Delete.Disappeared", "&cSubServers &4&l\\u00BB&c Subserver &4$str$&c has disappeared");
|
||||||
|
def.put("Command.Delete.Running", "&cSubServers &4&l\\u00BB&c Cannot delete &4$str$&c while it is still running");
|
||||||
|
def.put("Command.Delete", "&aSubServers &2&l\\u00BB&a Deleting &2$int$&a subserver(s)");
|
||||||
|
def.put("Command.Teleport", "&aSubServers &2&l\\u00BB&a Teleporting to &2$str$");
|
||||||
|
def.put("Command.Teleport.Others", "&aSubServers &2&l\\u00BB&a Teleporting &2$name$&a to &2$str$");
|
||||||
|
def.put("Command.Teleport.Not-Running", "&cSubServers &4&l\\u00BB&c Subserver &4$str$&c is not running");
|
||||||
|
def.put("Interface.Generic.Back", "&cBack");
|
||||||
|
def.put("Interface.Generic.Back-Arrow", "&e&l<--");
|
||||||
|
def.put("Interface.Generic.Next-Arrow", "&e&l-->");
|
||||||
|
def.put("Interface.Generic.Undo", "&6Undo");
|
||||||
|
def.put("Interface.Generic.Downloading", "&7SubServers &8&l\\u00BB&7 Downloading:&f $str$");
|
||||||
|
def.put("Interface.Generic.Downloading.Title", "Downloading...");
|
||||||
|
def.put("Interface.Generic.Downloading.Title-Color", "&b");
|
||||||
|
def.put("Interface.Generic.Downloading.Title-Color-Alt", "&3");
|
||||||
|
def.put("Interface.Generic.Downloading.Response", "&eWaiting for response");
|
||||||
|
def.put("Interface.Generic.Invalid-Permission", "&4You need &n$str$");
|
||||||
|
def.put("Interface.Proxy-Menu.Proxy-Player-Count", "&2$int$ Player(s) Online");
|
||||||
|
def.put("Interface.Proxy-Menu.Proxy-Master", "&8Master Proxy");
|
||||||
|
def.put("Interface.Proxy-Menu.Proxy-Disconnected", "&4Disconnected");
|
||||||
|
def.put("Interface.Host-Menu.Title", "Host Menu");
|
||||||
|
def.put("Interface.Host-Menu.Host-Unavailable", "&4Unavailable");
|
||||||
|
def.put("Interface.Host-Menu.Host-Disabled", "&4Disabled");
|
||||||
|
def.put("Interface.Host-Menu.Host-Server-Count", "&9$int$ Server(s)");
|
||||||
|
def.put("Interface.Host-Menu.No-Hosts", "&c&oThere are No Hosts");
|
||||||
|
def.put("Interface.Host-Menu.Group-Menu", "&6&lView Servers by Group");
|
||||||
|
def.put("Interface.Host-Menu.Server-Menu", "&a&lView Servers");
|
||||||
|
def.put("Interface.Host-Admin.Title", "Host/$str$");
|
||||||
|
def.put("Interface.Host-Admin.Creator", "&eCreate a SubServer");
|
||||||
|
def.put("Interface.Host-Admin.SubServers", "&bView SubServers");
|
||||||
|
def.put("Interface.Host-Admin.Plugins", "&bPlugins...");
|
||||||
|
def.put("Interface.Host-Creator.Title", "Host/$str$/Create");
|
||||||
|
def.put("Interface.Host-Creator.Edit-Name", "Change Name");
|
||||||
|
def.put("Interface.Host-Creator.Edit-Name.Title", "&eSubCreator\\n&6Enter a Name for this Server");
|
||||||
|
def.put("Interface.Host-Creator.Edit-Name.Message", "&eSubCreator &6&l\\u00BB&e Enter a Name for this Server via Chat");
|
||||||
|
def.put("Interface.Host-Creator.Edit-Name.Exists", "&cSubCreator &4&l\\u00BB&c There is already a SubServer with that name");
|
||||||
|
def.put("Interface.Host-Creator.Edit-Name.Exists-Title", "&eSubCreator\\n&cThere is already a SubServer with that name");
|
||||||
|
def.put("Interface.Host-Creator.Edit-Name.Invalid", "&cSubCreator &4&l\\u00BB&c Invalid Server Name");
|
||||||
|
def.put("Interface.Host-Creator.Edit-Name.Invalid-Title", "&eSubCreator\\n&cInvalid Server Name");
|
||||||
|
def.put("Interface.Host-Creator.Edit-Template", "Change Server Template");
|
||||||
|
def.put("Interface.Host-Creator.Edit-Template.Title", "Host/$str$/Templates");
|
||||||
|
def.put("Interface.Host-Creator.Edit-Template.No-Templates", "&c&oThere are No Templates");
|
||||||
|
def.put("Interface.Host-Creator.Edit-Version", "Change Server Version");
|
||||||
|
def.put("Interface.Host-Creator.Edit-Version.Title", "&eSubCreator\\n&6Enter a Server Version");
|
||||||
|
def.put("Interface.Host-Creator.Edit-Version.Message", "&eSubCreator &6&l\\u00BB&e Enter a Server Version via Chat");
|
||||||
|
def.put("Interface.Host-Creator.Edit-Port", "Change Server Port");
|
||||||
|
def.put("Interface.Host-Creator.Edit-Port.Title", "&eSubCreator\\n&6Enter a Port Number");
|
||||||
|
def.put("Interface.Host-Creator.Edit-Port.Message", "&eSubCreator &6&l\\u00BB&e Enter a Port Number via Chat");
|
||||||
|
def.put("Interface.Host-Creator.Edit-Port.Invalid", "&cSubCreator &4&l\\u00BB&c Invalid Port Number");
|
||||||
|
def.put("Interface.Host-Creator.Edit-Port.Invalid-Title", "&eSubCreator\\n&cInvalid Port Number");
|
||||||
|
def.put("Interface.Host-Creator.Submit", "&eCreate SubServer");
|
||||||
|
def.put("Interface.Host-Creator.Form-Incomplete", "&4Buttons above must be green");
|
||||||
|
def.put("Interface.Host-Plugin.Title", "Host/$str$/Plugins");
|
||||||
|
def.put("Interface.Host-Plugin.No-Plugins", "&c&oThere are No Plugins Available");
|
||||||
|
def.put("Interface.Host-SubServer.Title", "Host/$str$/SubServers");
|
||||||
|
def.put("Interface.Group-Menu.Title", "Group Menu");
|
||||||
|
def.put("Interface.Group-Menu.Group-Server-Count", "&9$int$ Server(s)");
|
||||||
|
def.put("Interface.Group-Menu.Ungrouped", "&7(ungrouped)");
|
||||||
|
def.put("Interface.Group-Menu.Server-Menu", "&a&lView All Servers");
|
||||||
|
def.put("Interface.Group-SubServer.Title", "Group/$str$/Servers");
|
||||||
|
def.put("Interface.Group-SubServer.Title-Ungrouped", "Ungrouped Server Menu");
|
||||||
|
def.put("Interface.Server-Menu.Title", "Server Menu");
|
||||||
|
def.put("Interface.Server-Menu.Server-Player-Count", "&2$int$ Player(s) Online");
|
||||||
|
def.put("Interface.Server-Menu.Server-External", "&7External Server");
|
||||||
|
def.put("Interface.Server-Menu.SubServer-Temporary", "&9Temporary");
|
||||||
|
def.put("Interface.Server-Menu.SubServer-Offline", "&6Offline");
|
||||||
|
def.put("Interface.Server-Menu.SubServer-Incompatible", "&4Incompatible with $str$");
|
||||||
|
def.put("Interface.Server-Menu.SubServer-Unavailable", "&4Unavailable");
|
||||||
|
def.put("Interface.Server-Menu.SubServer-Disabled", "&4Disabled");
|
||||||
|
def.put("Interface.Server-Menu.No-Servers", "&c&oThere are No Servers");
|
||||||
|
def.put("Interface.Server-Menu.Host-Menu", "&b&lView Hosts");
|
||||||
|
def.put("Interface.Server-Admin.Title", "Server/$str$");
|
||||||
|
def.put("Interface.Server-Admin.Start", "&aStart SubServer");
|
||||||
|
def.put("Interface.Server-Admin.Start.Title", "&aStarting SubServer");
|
||||||
|
def.put("Interface.Server-Admin.Stop", "&cStop SubServer");
|
||||||
|
def.put("Interface.Server-Admin.Stop.Title", "&cStopping $str$");
|
||||||
|
def.put("Interface.Server-Admin.Terminate", "&4Terminate SubServer");
|
||||||
|
def.put("Interface.Server-Admin.Terminate.Title", "&cTerminating $str$");
|
||||||
|
def.put("Interface.Server-Admin.Command", "&bSend a Command to the Server");
|
||||||
|
def.put("Interface.Server-Admin.Command.Title", "&eSubServers\\n&6Enter a Command to send via Chat");
|
||||||
|
def.put("Interface.Server-Admin.Command.Message", "&eSubServers &6&l\\u00BB&e Enter a Command to send via Chat");
|
||||||
|
def.put("Interface.Server-Admin.Update", "&eUpdate SubServer");
|
||||||
|
def.put("Interface.Server-Admin.Update.Title", "&eSubServers\\n&6Enter a Server Version to update to");
|
||||||
|
def.put("Interface.Server-Admin.Update.Message", "&eSubServers &6&l\\u00BB&e Enter a Server Version to update to via Chat");
|
||||||
|
def.put("Interface.Server-Admin.Plugins", "&bPlugins...");
|
||||||
|
def.put("Interface.SubServer-Plugin.Title", "Server/$str$/Plugins");
|
||||||
|
def.put("Interface.SubServer-Plugin.No-Plugins", "&c&oThere are No Plugins Available");
|
||||||
|
|
||||||
|
YAMLSection lang = new YAMLSection();
|
||||||
|
for (String key : def.keySet()) lang.set(key, updated.getMap("Lang", new YAMLSection()).getString(key, def.get(key)));
|
||||||
|
rewritten.set("Lang", lang);
|
||||||
|
|
||||||
|
config.set(rewritten);
|
||||||
|
config.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,50 +0,0 @@
|
||||||
package net.ME1312.SubServers.Bungee.Library;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Container Class
|
|
||||||
*
|
|
||||||
* @param <V> Item
|
|
||||||
*/
|
|
||||||
public class Container<V> {
|
|
||||||
private V obj;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Container
|
|
||||||
*
|
|
||||||
* @param item Object to Store
|
|
||||||
*/
|
|
||||||
public Container(V item) {
|
|
||||||
obj = item;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Grabs the Object
|
|
||||||
*
|
|
||||||
* @return The Object
|
|
||||||
*/
|
|
||||||
public V get() {
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Overwrite the Object
|
|
||||||
*
|
|
||||||
* @param value Object to Store
|
|
||||||
*/
|
|
||||||
public void set(V value) {
|
|
||||||
obj = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object object) {
|
|
||||||
if (object instanceof Container) {
|
|
||||||
if (obj == null || ((Container) object).get() == null) {
|
|
||||||
return obj == ((Container) object).get();
|
|
||||||
} else {
|
|
||||||
return obj.equals(((Container) object).get());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return super.equals(object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
package net.ME1312.SubServers.Bungee.Library;
|
|
||||||
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLValue;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extra Data Handler Layout Class
|
|
||||||
*/
|
|
||||||
public interface ExtraDataHandler {
|
|
||||||
/**
|
|
||||||
* Add an extra value to this Object
|
|
||||||
*
|
|
||||||
* @param handle Handle
|
|
||||||
* @param value Value
|
|
||||||
*/
|
|
||||||
void addExtra(String handle, Object value);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if an extra value exists
|
|
||||||
*
|
|
||||||
* @param handle Handle
|
|
||||||
* @return Value Status
|
|
||||||
*/
|
|
||||||
boolean hasExtra(String handle);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an extra value
|
|
||||||
*
|
|
||||||
* @param handle Handle
|
|
||||||
* @return Value
|
|
||||||
*/
|
|
||||||
YAMLValue getExtra(String handle);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the extra value section
|
|
||||||
*
|
|
||||||
* @return Extra Value Section
|
|
||||||
*/
|
|
||||||
YAMLSection getExtra();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove an extra value from this Object
|
|
||||||
*
|
|
||||||
* @param handle Handle
|
|
||||||
*/
|
|
||||||
void removeExtra(String handle);
|
|
||||||
}
|
|
|
@ -0,0 +1,135 @@
|
||||||
|
package net.ME1312.SubServers.Bungee.Library;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Directories;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.PrimitiveIterator;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File Scanner Base Class
|
||||||
|
*/
|
||||||
|
public abstract class FileScanner {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scan a Directory
|
||||||
|
*
|
||||||
|
* @param dir Directory
|
||||||
|
* @param whitelist File Whitelist
|
||||||
|
*/
|
||||||
|
protected void scan(File dir, String... whitelist) throws IOException {
|
||||||
|
List<String> files = Directories.search(dir);
|
||||||
|
if (files.size() <= 0 || whitelist.length <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
boolean csfs = false;
|
||||||
|
{
|
||||||
|
long stamp = Math.round(Math.random() * 100000);
|
||||||
|
File test1 = new File(dir, '.' + stamp + ".ss_fsc");
|
||||||
|
File test2 = new File(dir, '.' + stamp + ".SS_FSC");
|
||||||
|
|
||||||
|
test1.createNewFile();
|
||||||
|
if (test2.createNewFile()) {
|
||||||
|
csfs = true;
|
||||||
|
test2.delete();
|
||||||
|
}
|
||||||
|
test1.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkedHashMap<Pattern, Boolean> rules = new LinkedHashMap<Pattern, Boolean>();
|
||||||
|
for (String entry : whitelist) {
|
||||||
|
boolean mode = !entry.startsWith("!");
|
||||||
|
if (!mode) entry = entry.substring(1);
|
||||||
|
|
||||||
|
String pattern;
|
||||||
|
if (!entry.startsWith("%")) {
|
||||||
|
if (entry.startsWith("./"))
|
||||||
|
entry = entry.substring(1);
|
||||||
|
|
||||||
|
StringBuilder rule = new StringBuilder();
|
||||||
|
if (entry.startsWith("**")) {
|
||||||
|
entry = entry.substring(2);
|
||||||
|
rule.append("^.*");
|
||||||
|
} else if (entry.startsWith("/")) {
|
||||||
|
rule.append("^");
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean greedyEnding = false;
|
||||||
|
if (entry.endsWith("**")) {
|
||||||
|
entry = entry.substring(0, entry.length() - 2);
|
||||||
|
greedyEnding = true;
|
||||||
|
} else if (entry.endsWith("/")) {
|
||||||
|
greedyEnding = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder literal = new StringBuilder();
|
||||||
|
for (PrimitiveIterator.OfInt i = entry.codePoints().iterator(); i.hasNext(); ) {
|
||||||
|
int c = i.next();
|
||||||
|
if ((c == '*' || c == '?' || c == '[') && literal.length() > 0) {
|
||||||
|
rule.append(Pattern.quote(literal.toString()));
|
||||||
|
literal = new StringBuilder();
|
||||||
|
}
|
||||||
|
switch (c) {
|
||||||
|
case '[':
|
||||||
|
for (boolean escaped = false; i.hasNext() && (c != ']' || escaped); c = i.next()) {
|
||||||
|
if (c == '\\') escaped = !escaped;
|
||||||
|
else escaped = false;
|
||||||
|
literal.appendCodePoint(c);
|
||||||
|
}
|
||||||
|
if (c == ']' && literal.length() > 1) {
|
||||||
|
literal.appendCodePoint(c);
|
||||||
|
rule.append(literal.toString());
|
||||||
|
}
|
||||||
|
literal = new StringBuilder();
|
||||||
|
break;
|
||||||
|
case '*':
|
||||||
|
rule.append("[^/]+");
|
||||||
|
break;
|
||||||
|
case '?':
|
||||||
|
rule.append("[^/]");
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
if (i.hasNext()) c = i.next();
|
||||||
|
default:
|
||||||
|
literal.appendCodePoint(c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (literal.length() > 0)
|
||||||
|
rule.append(Pattern.quote(literal.toString()));
|
||||||
|
|
||||||
|
if (greedyEnding)
|
||||||
|
rule.append(".*");
|
||||||
|
rule.append("$");
|
||||||
|
pattern = rule.toString();
|
||||||
|
} else {
|
||||||
|
pattern = entry.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (csfs) rules.put(Pattern.compile(pattern), mode);
|
||||||
|
else rules.put(Pattern.compile(pattern, Pattern.CASE_INSENSITIVE), mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String file : files) {
|
||||||
|
boolean act = false;
|
||||||
|
|
||||||
|
for (Map.Entry<Pattern, Boolean> rule : rules.entrySet()) {
|
||||||
|
if (rule.getKey().matcher('/' + file.replace(File.separatorChar, '/')).find()) act = rule.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (act) act(dir, file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform an action on an included file
|
||||||
|
*
|
||||||
|
* @param dir Parent Directory
|
||||||
|
* @param name File Name
|
||||||
|
*/
|
||||||
|
protected abstract void act(File dir, String name) throws IOException;
|
||||||
|
}
|
|
@ -1,41 +0,0 @@
|
||||||
Settings:
|
|
||||||
Version: '2.11.2a+'
|
|
||||||
Override-Bungee-Commands: true
|
|
||||||
UPnP:
|
|
||||||
Forward-Proxy: true
|
|
||||||
Forward-SubData: false
|
|
||||||
Forward-Servers: false
|
|
||||||
SubData:
|
|
||||||
Address: '127.0.0.1:4391'
|
|
||||||
Password: 'default'
|
|
||||||
Encryption: 'AES'
|
|
||||||
Allowed-Connections: []
|
|
||||||
|
|
||||||
Hosts:
|
|
||||||
'~':
|
|
||||||
Enabled: true
|
|
||||||
Display: 'Default'
|
|
||||||
Driver: 'BUILT-IN'
|
|
||||||
Address: '127.0.0.1'
|
|
||||||
Port-Range: '25500-25559'
|
|
||||||
Directory: './SubServers/Servers'
|
|
||||||
Git-Bash: '%ProgramFiles%\Git'
|
|
||||||
Log-Creator: true
|
|
||||||
|
|
||||||
Servers:
|
|
||||||
'Example':
|
|
||||||
Enabled: false
|
|
||||||
Display: ''
|
|
||||||
Host: '~'
|
|
||||||
Group: []
|
|
||||||
Port: 25567
|
|
||||||
Motd: '&aThis is a SubServer'
|
|
||||||
Log: true
|
|
||||||
Directory: './Example'
|
|
||||||
Executable: 'java -Djline.terminal=jline.UnsupportedTerminal -jar Spigot.jar'
|
|
||||||
Stop-Command: 'stop'
|
|
||||||
Stop-Action: 'NONE'
|
|
||||||
Run-On-Launch: false
|
|
||||||
Restricted: false
|
|
||||||
Incompatible: []
|
|
||||||
Hidden: false
|
|
|
@ -1,172 +0,0 @@
|
||||||
Version: '2.13.2c+'
|
|
||||||
Lang:
|
|
||||||
'Bungee.Feature.Return': '&6Returning to $str$: &r$msg$'
|
|
||||||
'Bungee.Server.Current': '&6You are currently connected to $str$'
|
|
||||||
'Bungee.Server.Available': '&6You may connect to the following servers at this time:'
|
|
||||||
'Bungee.Server.List': '&6$str$'
|
|
||||||
'Bungee.Server.Hover': '$int$ player(s)\n&oClick to connect to the server'
|
|
||||||
'Bungee.Server.Divider': '&6, '
|
|
||||||
'Bungee.Server.Invalid': '&cThe specified server does not exist.'
|
|
||||||
'Bungee.List.Format': '&a[$str$] &e($int$)&r: '
|
|
||||||
'Bungee.List.List': '&f$str$'
|
|
||||||
'Bungee.List.Divider': '&f, '
|
|
||||||
'Bungee.List.Total': 'Total players online: $int$'
|
|
||||||
'Command.Generic.Player-Only': '&cSubServers &4&l\u00BB&c Console cannot run this command'
|
|
||||||
'Command.Generic.Console-Only': '&cSubServers &4&l\u00BB&c This command is for console use only'
|
|
||||||
'Command.Generic.Usage': '&7SubServers &8&l\u00BB&7 Usage: &f$str$'
|
|
||||||
'Command.Generic.Exception': '&cSubServers &4&l\u00BB&c An unexpected exception has occurred while parsing this command'
|
|
||||||
'Command.Generic.Invalid-Subcommand': '&cSubServers &4&l\u00BB&c Unknown sub-command: $str$'
|
|
||||||
'Command.Generic.Invalid-Permission': '&cSubServers &4&l\u00BB&c You need &4&n$str$&c to use this command'
|
|
||||||
'Command.Generic.Unknown-Proxy': '&cSubServers &4&l\u00BB&c There is no proxy with that name'
|
|
||||||
'Command.Generic.Unknown-Host': '&cSubServers &4&l\u00BB&c There is no host with that name'
|
|
||||||
'Command.Generic.Unknown-Group': '&cSubServers &4&l\u00BB&c There is no group with that name'
|
|
||||||
'Command.Generic.Unknown-Server': '&cSubServers &4&l\u00BB&c There is no server with that name'
|
|
||||||
'Command.Generic.Unknown-SubServer': '&cSubServers &4&l\u00BB&c There is no subserver with that name'
|
|
||||||
'Command.Help.Header': '&7SubServers &8&l\u00BB&7 Command Help:'
|
|
||||||
'Command.Help.Help': ' &7Help:&f $str$'
|
|
||||||
'Command.Help.List': ' &7List:&f $str$'
|
|
||||||
'Command.Help.Version': ' &7Version:&f $str$'
|
|
||||||
'Command.Help.Info': ' &7Info:&f $str$'
|
|
||||||
'Command.Help.Host.Create': ' &7Create Server:&f $str$'
|
|
||||||
'Command.Help.SubServer.Start': ' &7Start Server:&f $str$'
|
|
||||||
'Command.Help.SubServer.Restart': ' &7Restart Server:&f $str$'
|
|
||||||
'Command.Help.SubServer.Stop': ' &7Stop Server:&f $str$'
|
|
||||||
'Command.Help.SubServer.Terminate': ' &7Terminate Server:&f $str$'
|
|
||||||
'Command.Help.SubServer.Command': ' &7Command Server:&f $str$'
|
|
||||||
'Command.Version': '&7SubServers &8&l\u00BB&7 These are the platforms and versions that are running &f$str$&7:'
|
|
||||||
'Command.Version.Outdated': '&7$name$ &f$str$ &7is available. You are $int$ version(s) behind.'
|
|
||||||
'Command.Version.Latest': '&7You are on the latest version.'
|
|
||||||
'Command.List.Group-Header': '&7SubServers &8&l\u00BB&7 Group/Server List:'
|
|
||||||
'Command.List.Host-Header': '&7SubServers &8&l\u00BB&7 Host/SubServer List:'
|
|
||||||
'Command.List.Server-Header': '&7SubServers &8&l\u00BB&7 Server List:'
|
|
||||||
'Command.List.Proxy-Header': '&7SubServers &8&l\u00BB&7 Proxy List:'
|
|
||||||
'Command.List.Header': '&7: '
|
|
||||||
'Command.List.Divider': '&7, '
|
|
||||||
'Command.List.Empty': '&7(none)'
|
|
||||||
'Command.Info': '&7SubServers &8&l\u00BB&7 Info on $str$&7: &r'
|
|
||||||
'Command.Info.Unknown': '&cSubServers &4&l\u00BB&c There is no object with that name'
|
|
||||||
'Command.Info.Unknown-Type': '&cSubServers &4&l\u00BB&c There is no object type with that name'
|
|
||||||
'Command.Info.Unknown-Proxy': '&cSubServers &4&l\u00BB&c There is no proxy with that name'
|
|
||||||
'Command.Info.Unknown-Host': '&cSubServers &4&l\u00BB&c There is no host with that name'
|
|
||||||
'Command.Info.Unknown-Group': '&cSubServers &4&l\u00BB&c There is no group with that name'
|
|
||||||
'Command.Info.Unknown-Server': '&cSubServers &4&l\u00BB&c There is no server with that name'
|
|
||||||
'Command.Info.Format': ' -> &7$str$&7: &r'
|
|
||||||
'Command.Info.List': ' - '
|
|
||||||
'Command.Start': '&aSubServers &2&l\u00BB&a Starting SubServer'
|
|
||||||
'Command.Start.Unknown': '&cSubServers &4&l\u00BB&c There is no Server with that name'
|
|
||||||
'Command.Start.Invalid': '&cSubServers &4&l\u00BB&c That Server is not a SubServer'
|
|
||||||
'Command.Start.Host-Unavailable': '&cSubServers &4&l\u00BB&c That SubServer\u0027s Host is not available'
|
|
||||||
'Command.Start.Host-Disabled': '&cSubServers &4&l\u00BB&c That SubServer\u0027s Host is not enabled'
|
|
||||||
'Command.Start.Server-Disabled': '&cSubServers &4&l\u00BB&c That SubServer is not enabled'
|
|
||||||
'Command.Start.Server-Incompatible': '&cSubServers &4&l\u00BB&c That SubServer cannot start while these server(s) are running: &4$str$'
|
|
||||||
'Command.Start.Running': '&cSubServers &4&l\u00BB&c That SubServer is already running'
|
|
||||||
'Command.Restart': '&aSubServers &2&l\u00BB&a Stopping SubServer'
|
|
||||||
'Command.Restart.Finish': '&aSubServers &2&l\u00BB&a Starting SubServer'
|
|
||||||
'Command.Restart.Unknown': '&cSubServers &4&l\u00BB&c There is no Server with that name'
|
|
||||||
'Command.Restart.Invalid': '&cSubServers &4&l\u00BB&c That Server is not a SubServer'
|
|
||||||
'Command.Restart.Disappeared': '&cSubServers &4&l\u00BB&c Could not restart server: That SubServer has disappeared'
|
|
||||||
'Command.Restart.Host-Unavailable': '&cSubServers &4&l\u00BB&c Could not restart server: That SubServer\u0027s Host is no longer available'
|
|
||||||
'Command.Restart.Host-Disabled': '&cSubServers &4&l\u00BB&c Could not restart server: That SubServer\u0027s Host is no longer enabled'
|
|
||||||
'Command.Restart.Server-Disabled': '&cSubServers &4&l\u00BB&c Could not restart server: That SubServer is no longer enabled'
|
|
||||||
'Command.Restart.Server-Incompatible': '&cSubServers &4&l\u00BB&c Could not restart server: That SubServer cannot start while these server(s) are running: &4$str$'
|
|
||||||
'Command.Stop': '&aSubServers &2&l\u00BB&a Stopping SubServer'
|
|
||||||
'Command.Stop.Unknown': '&cSubServers &4&l\u00BB&c There is no Server with that name'
|
|
||||||
'Command.Stop.Invalid': '&cSubServers &4&l\u00BB&c That Server is not a SubServer'
|
|
||||||
'Command.Stop.Not-Running': '&cSubServers &4&l\u00BB&c That SubServer is not running'
|
|
||||||
'Command.Terminate': '&aSubServers &2&l\u00BB&a Stopping SubServer'
|
|
||||||
'Command.Terminate.Unknown': '&cSubServers &4&l\u00BB&c There is no Server with that name'
|
|
||||||
'Command.Terminate.Invalid': '&cSubServers &4&l\u00BB&c That Server is not a SubServer'
|
|
||||||
'Command.Terminate.Not-Running': '&cSubServers &4&l\u00BB&c That SubServer is not running'
|
|
||||||
'Command.Command': '&aSubServers &2&l\u00BB&a Sending command to SubServer'
|
|
||||||
'Command.Command.Unknown': '&cSubServers &4&l\u00BB&c There is no Server with that name'
|
|
||||||
'Command.Command.Invalid': '&cSubServers &4&l\u00BB&c That Server is not a SubServer'
|
|
||||||
'Command.Command.Not-Running': '&cSubServers &4&l\u00BB&c That SubServer is not running'
|
|
||||||
'Command.Creator': '&aSubServers &2&l\u00BB&a Creating SubServer'
|
|
||||||
'Command.Creator.Exists': '&cSubServers &4&l\u00BB&c There is already a SubServer with that name'
|
|
||||||
'Command.Creator.Unknown-Host': '&cSubServers &4&l\u00BB&c There is no Host with that name'
|
|
||||||
'Command.Creator.Host-Unavailable': '&cSubServers &4&l\u00BB&c That Host is not available'
|
|
||||||
'Command.Creator.Host-Disabled': '&cSubServers &4&l\u00BB&c That Host is not enabled'
|
|
||||||
'Command.Creator.Unknown-Template': '&cSubServers &4&l\u00BB&c There is no Template with that name'
|
|
||||||
'Command.Creator.Template-Disabled': '&cSubServers &4&l\u00BB&c That Template is not enabled'
|
|
||||||
'Command.Creator.Invalid-Version': '&cSubServers &4&l\u00BB&c SubCreator cannot create servers before Minecraft 1.8'
|
|
||||||
'Command.Creator.Invalid-Port': '&cSubServers &4&l\u00BB&c Invalid Port Number'
|
|
||||||
'Interface.Generic.Back': '&cBack'
|
|
||||||
'Interface.Generic.Back-Arrow': '&e&l<--'
|
|
||||||
'Interface.Generic.Next-Arrow': '&e&l-->'
|
|
||||||
'Interface.Generic.Undo': '&6Undo'
|
|
||||||
'Interface.Generic.Downloading': '&7SubServers &8&l\u00BB&7 Downloading:&f $str$'
|
|
||||||
'Interface.Generic.Downloading.Title': 'Downloading...'
|
|
||||||
'Interface.Generic.Downloading.Title-Color': '&b'
|
|
||||||
'Interface.Generic.Downloading.Title-Color-Alt': '&3'
|
|
||||||
'Interface.Generic.Downloading.Response': '&eWaiting for response'
|
|
||||||
'Interface.Generic.Invalid-Permission': '&4You need &n$str$'
|
|
||||||
'Interface.Proxy-Menu.Proxy-Player-Count': '&2$int$ Player(s) Online'
|
|
||||||
'Interface.Proxy-Menu.Proxy-Master': '&8Master Proxy'
|
|
||||||
'Interface.Proxy-Menu.Proxy-SubData': '&9SubData Only'
|
|
||||||
'Interface.Proxy-Menu.Proxy-Redis': '&7Redis Only'
|
|
||||||
'Interface.Proxy-Menu.Proxy-Disconnected': '&4Disconnected'
|
|
||||||
'Interface.Host-Menu.Title': 'Host Menu'
|
|
||||||
'Interface.Host-Menu.Host-Unavailable': '&4Unavailable'
|
|
||||||
'Interface.Host-Menu.Host-Disabled': '&4Disabled'
|
|
||||||
'Interface.Host-Menu.Host-Server-Count': '&9$int$ Server(s)'
|
|
||||||
'Interface.Host-Menu.No-Hosts': '&c&oThere are No Hosts'
|
|
||||||
'Interface.Host-Menu.Group-Menu': '&6&lView Servers by Group'
|
|
||||||
'Interface.Host-Menu.Server-Menu': '&a&lView Servers'
|
|
||||||
'Interface.Host-Admin.Title': 'Host/$str$'
|
|
||||||
'Interface.Host-Admin.Creator': '&eCreate a SubServer'
|
|
||||||
'Interface.Host-Admin.SubServers': '&aView SubServers'
|
|
||||||
'Interface.Host-Admin.Plugins': '&bPlugins...'
|
|
||||||
'Interface.Host-Creator.Title': 'Host/$str$/Create'
|
|
||||||
'Interface.Host-Creator.Edit-Name': 'Change Name'
|
|
||||||
'Interface.Host-Creator.Edit-Name.Title': '&eSubCreator\n&6Enter a Name for this Server'
|
|
||||||
'Interface.Host-Creator.Edit-Name.Message': '&eSubCreator &6&l\u00BB&e Enter a Name for this Server via Chat'
|
|
||||||
'Interface.Host-Creator.Edit-Name.Exists': '&cSubCreator &4&l\u00BB&c There is already a SubServer with that name'
|
|
||||||
'Interface.Host-Creator.Edit-Name.Exists-Title': '&eSubCreator\n&cThere is already a SubServer with that name'
|
|
||||||
'Interface.Host-Creator.Edit-Name.Invalid': '&cSubCreator &4&l\u00BB&c Invalid Server Name'
|
|
||||||
'Interface.Host-Creator.Edit-Name.Invalid-Title': '&eSubCreator\n&cInvalid Server Name'
|
|
||||||
'Interface.Host-Creator.Edit-Template': 'Change Server Template'
|
|
||||||
'Interface.Host-Creator.Edit-Template.Title': 'Host/$str$/Templates'
|
|
||||||
'Interface.Host-Creator.Edit-Template.No-Templates': '&c&oThere are No Templates'
|
|
||||||
'Interface.Host-Creator.Edit-Version': 'Change Server Version'
|
|
||||||
'Interface.Host-Creator.Edit-Version.Title': '&eSubCreator\n&6Enter a Server Version'
|
|
||||||
'Interface.Host-Creator.Edit-Version.Message': '&eSubCreator &6&l\u00BB&e Enter a Server Version via Chat'
|
|
||||||
'Interface.Host-Creator.Edit-Version.Unavailable': '&cSubCreator &4&l\u00BB&c SubCreator cannot create servers before Minecraft 1.8'
|
|
||||||
'Interface.Host-Creator.Edit-Version.Unavailable-Title': '&eSubCreator\n&cCannot create servers before MC 1.8'
|
|
||||||
'Interface.Host-Creator.Edit-Port': 'Change Server Port'
|
|
||||||
'Interface.Host-Creator.Edit-Port.Title': '&eSubCreator\n&6Enter a Port Number'
|
|
||||||
'Interface.Host-Creator.Edit-Port.Message': '&eSubCreator &6&l\u00BB&e Enter a Port Number via Chat'
|
|
||||||
'Interface.Host-Creator.Edit-Port.Invalid': '&cSubCreator &4&l\u00BB&c Invalid Port Number'
|
|
||||||
'Interface.Host-Creator.Edit-Port.Invalid-Title': '&eSubCreator\n&cInvalid Port Number'
|
|
||||||
'Interface.Host-Creator.Submit': '&eCreate SubServer'
|
|
||||||
'Interface.Host-Creator.Form-Incomplete': '&4Buttons above must be green'
|
|
||||||
'Interface.Host-Plugin.Title': 'Host/$str$/Plugins'
|
|
||||||
'Interface.Host-Plugin.No-Plugins': '&c&oThere are No Plugins Available'
|
|
||||||
'Interface.Host-SubServer.Title': 'Host/$str$/SubServers'
|
|
||||||
'Interface.Group-Menu.Title': 'Group Menu'
|
|
||||||
'Interface.Group-Menu.Group-Server-Count': '&9$int$ Server(s)'
|
|
||||||
'Interface.Group-Menu.No-Groups': '&c&oThere are No Groups'
|
|
||||||
'Interface.Group-Menu.Server-Menu': '&a&lView All Servers'
|
|
||||||
'Interface.Group-SubServer.Title': 'Group/$str$/Servers'
|
|
||||||
'Interface.Server-Menu.Title': 'Server Menu'
|
|
||||||
'Interface.Server-Menu.Server-Player-Count': '&2$int$ Player(s) Online'
|
|
||||||
'Interface.Server-Menu.Server-External': '&7External Server'
|
|
||||||
'Interface.Server-Menu.SubServer-Temporary': '&9Temporary'
|
|
||||||
'Interface.Server-Menu.SubServer-Offline': '&6Offline'
|
|
||||||
'Interface.Server-Menu.SubServer-Incompatible': '&4Incompatible with $str$'
|
|
||||||
'Interface.Server-Menu.SubServer-Disabled': '&4Disabled'
|
|
||||||
'Interface.Server-Menu.SubServer-Invalid': '&4Cannot be managed by SubServers'
|
|
||||||
'Interface.Server-Menu.No-Servers': '&c&oThere are No Servers'
|
|
||||||
'Interface.Server-Menu.Host-Menu': '&b&lView Hosts'
|
|
||||||
'Interface.SubServer-Admin.Title': 'SubServer/$str$'
|
|
||||||
'Interface.SubServer-Admin.Start': '&aStart SubServer'
|
|
||||||
'Interface.SubServer-Admin.Start.Title': '&aStarting SubServer'
|
|
||||||
'Interface.SubServer-Admin.Stop': '&cStop SubServer'
|
|
||||||
'Interface.SubServer-Admin.Stop.Title': '&cStopping $str$'
|
|
||||||
'Interface.SubServer-Admin.Terminate': '&4Terminate SubServer'
|
|
||||||
'Interface.SubServer-Admin.Terminate.Title': '&cTerminating $str$'
|
|
||||||
'Interface.SubServer-Admin.Command': '&eSend a Command to the SubServer'
|
|
||||||
'Interface.SubServer-Admin.Command.Title': '&eSubServers\n&6Enter a Command to send via Chat'
|
|
||||||
'Interface.SubServer-Admin.Command.Message': '&eSubServers &6&l\u00BB&e Enter a Command to send via Chat'
|
|
||||||
'Interface.SubServer-Admin.Plugins': '&bPlugins...'
|
|
||||||
'Interface.SubServer-Plugin.Title': 'SubServer/$str$/Plugins'
|
|
||||||
'Interface.SubServer-Plugin.No-Plugins': '&c&oThere are No Plugins Available'
|
|
|
@ -1,457 +0,0 @@
|
||||||
package net.ME1312.SubServers.Bungee.Library;
|
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonPrimitive;
|
|
||||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
|
||||||
import net.md_5.bungee.config.Configuration;
|
|
||||||
import net.md_5.bungee.config.ConfigurationProvider;
|
|
||||||
import net.md_5.bungee.config.YamlConfiguration;
|
|
||||||
|
|
||||||
import javax.net.ssl.HttpsURLConnection;
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.BufferedWriter;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
import java.util.zip.GZIPOutputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bStats collects some data for plugin authors.
|
|
||||||
*
|
|
||||||
* Check out https://bStats.org/ to learn more about bStats!
|
|
||||||
*/
|
|
||||||
public class Metrics {
|
|
||||||
|
|
||||||
static {
|
|
||||||
// You can use the property to disable the check in your test environment
|
|
||||||
if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false")) {
|
|
||||||
// Maven's Relocate is clever and changes strings, too. So we have to use this little "trick" ... :D
|
|
||||||
final String defaultPackage = new String(
|
|
||||||
new byte[]{'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'n', 'g', 'e', 'e', 'c', 'o', 'r', 'd'});
|
|
||||||
final String examplePackage = new String(new byte[]{'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
|
|
||||||
// We want to make sure nobody just copy & pastes the example and use the wrong package names
|
|
||||||
if (Metrics.class.getPackage().getName().equals(defaultPackage) || Metrics.class.getPackage().getName().equals(examplePackage)) {
|
|
||||||
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The version of this bStats class
|
|
||||||
public static final int B_STATS_VERSION = 1;
|
|
||||||
|
|
||||||
// The url to which the data is sent
|
|
||||||
private static final String URL = "https://bStats.org/submitData/bungeecord";
|
|
||||||
|
|
||||||
// The plugin
|
|
||||||
private final SubPlugin plugin;
|
|
||||||
|
|
||||||
// Is bStats enabled on this server?
|
|
||||||
private boolean enabled;
|
|
||||||
|
|
||||||
// The uuid of the server
|
|
||||||
private String serverUUID;
|
|
||||||
|
|
||||||
// Should failed requests be logged?
|
|
||||||
private boolean logFailedRequests = false;
|
|
||||||
|
|
||||||
// A list with all known metrics class objects including this one
|
|
||||||
private static final List<Object> knownMetricsInstances = new ArrayList<>();
|
|
||||||
|
|
||||||
public Metrics(SubPlugin plugin) {
|
|
||||||
this.plugin = plugin;
|
|
||||||
|
|
||||||
try {
|
|
||||||
loadConfig();
|
|
||||||
} catch (IOException e) {
|
|
||||||
// Failed to load configuration
|
|
||||||
plugin.getLogger().log(Level.WARNING, "Failed to load bStats config!", e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We are not allowed to send data about this server :(
|
|
||||||
if (!enabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Class<?> usedMetricsClass = getFirstBStatsClass();
|
|
||||||
if (usedMetricsClass == null) {
|
|
||||||
// Failed to get first metrics class
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (usedMetricsClass == getClass()) {
|
|
||||||
// We are the first! :)
|
|
||||||
linkMetrics(this);
|
|
||||||
startSubmitting();
|
|
||||||
} else {
|
|
||||||
// We aren't the first so we link to the first metrics class
|
|
||||||
try {
|
|
||||||
usedMetricsClass.getMethod("linkMetrics", Object.class).invoke(null,this);
|
|
||||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
|
|
||||||
if (logFailedRequests) {
|
|
||||||
plugin.getLogger().log(Level.WARNING, "Failed to link to first metrics class " + usedMetricsClass.getName() + "!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Links an other metrics class with this class.
|
|
||||||
* This method is called using Reflection.
|
|
||||||
*
|
|
||||||
* @param metrics An object of the metrics class to link.
|
|
||||||
*/
|
|
||||||
public static void linkMetrics(Object metrics) {
|
|
||||||
knownMetricsInstances.add(metrics);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the plugin specific data.
|
|
||||||
* This method is called using Reflection.
|
|
||||||
*
|
|
||||||
* @return The plugin specific data.
|
|
||||||
*/
|
|
||||||
public JsonObject getPluginData() {
|
|
||||||
JsonObject data = new JsonObject();
|
|
||||||
|
|
||||||
String pluginName = "SubServers 2";
|
|
||||||
String pluginVersion = plugin.version.toString();
|
|
||||||
|
|
||||||
data.addProperty("pluginName", pluginName);
|
|
||||||
data.addProperty("pluginVersion", pluginVersion);
|
|
||||||
|
|
||||||
JsonArray customCharts = new JsonArray();
|
|
||||||
customCharts.add(new SingleLineChart("managed_hosts", new Callable<Integer>() {
|
|
||||||
@Override
|
|
||||||
public Integer call() throws Exception {
|
|
||||||
return plugin.api.getHosts().size();
|
|
||||||
}
|
|
||||||
}).getRequestJsonObject(plugin.getLogger(), logFailedRequests));
|
|
||||||
customCharts.add(new SingleLineChart("subdata_connected", new Callable<Integer>() {
|
|
||||||
@Override
|
|
||||||
public Integer call() throws Exception {
|
|
||||||
return (plugin.subdata != null)?plugin.subdata.getClients().size():0;
|
|
||||||
}
|
|
||||||
}).getRequestJsonObject(plugin.getLogger(), logFailedRequests));
|
|
||||||
data.add("customCharts", customCharts);
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startSubmitting() {
|
|
||||||
new Timer("SubServers.Bungee::Metrics_Uploader").schedule( new TimerTask() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
// The data collection is async, as well as sending the data
|
|
||||||
// Bungeecord does not have a main thread, everything is async
|
|
||||||
submitData();
|
|
||||||
}
|
|
||||||
}, TimeUnit.MINUTES.toMillis(2), TimeUnit.MINUTES.toMillis(30));
|
|
||||||
// Submit the data every 30 minutes, first time after 2 minutes to give other plugins enough time to start
|
|
||||||
// WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted!
|
|
||||||
// WARNING: Just don't do it!
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the server specific data.
|
|
||||||
*
|
|
||||||
* @return The server specific data.
|
|
||||||
*/
|
|
||||||
private JsonObject getServerData() {
|
|
||||||
// Minecraft specific data
|
|
||||||
int playerAmount = plugin.getOnlineCount();
|
|
||||||
playerAmount = playerAmount > 500 ? 500 : playerAmount;
|
|
||||||
int onlineMode = plugin.getConfig().isOnlineMode() ? 1 : 0;
|
|
||||||
String bungeecordVersion = (plugin.getName().equals("SubServers Platform"))?"SubServers-Bungee-Patched":plugin.getVersion();
|
|
||||||
int managedServers = plugin.getServers().size();
|
|
||||||
|
|
||||||
// OS/Java specific data
|
|
||||||
String javaVersion = System.getProperty("java.version");
|
|
||||||
String osName = System.getProperty("os.name");
|
|
||||||
String osArch = System.getProperty("os.arch");
|
|
||||||
String osVersion = System.getProperty("os.version");
|
|
||||||
int coreCount = Runtime.getRuntime().availableProcessors();
|
|
||||||
|
|
||||||
JsonObject data = new JsonObject();
|
|
||||||
|
|
||||||
data.addProperty("serverUUID", serverUUID);
|
|
||||||
|
|
||||||
data.addProperty("playerAmount", playerAmount);
|
|
||||||
data.addProperty("managedServers", managedServers);
|
|
||||||
data.addProperty("onlineMode", onlineMode);
|
|
||||||
data.addProperty("bungeecordVersion", bungeecordVersion);
|
|
||||||
|
|
||||||
data.addProperty("javaVersion", javaVersion);
|
|
||||||
data.addProperty("osName", osName);
|
|
||||||
data.addProperty("osArch", osArch);
|
|
||||||
data.addProperty("osVersion", osVersion);
|
|
||||||
data.addProperty("coreCount", coreCount);
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Collects the data and sends it afterwards.
|
|
||||||
*/
|
|
||||||
private void submitData() {
|
|
||||||
final JsonObject data = getServerData();
|
|
||||||
|
|
||||||
final JsonArray pluginData = new JsonArray();
|
|
||||||
// Search for all other bStats Metrics classes to get their plugin data
|
|
||||||
for (Object metrics : knownMetricsInstances) {
|
|
||||||
try {
|
|
||||||
Object plugin = metrics.getClass().getMethod("getPluginData").invoke(metrics);
|
|
||||||
if (plugin instanceof JsonObject) {
|
|
||||||
pluginData.add((JsonObject) plugin);
|
|
||||||
}
|
|
||||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
data.add("plugins", pluginData);
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Send the data
|
|
||||||
sendData(data);
|
|
||||||
} catch (Exception e) {
|
|
||||||
// Something went wrong! :(
|
|
||||||
if (logFailedRequests) {
|
|
||||||
plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads the bStats configuration.
|
|
||||||
*
|
|
||||||
* @throws IOException If something did not work :(
|
|
||||||
*/
|
|
||||||
private void loadConfig() throws IOException {
|
|
||||||
Path configPath = new File(plugin.dir, "plugins").toPath().resolve("bStats");
|
|
||||||
configPath.toFile().mkdirs();
|
|
||||||
File configFile = new File(configPath.toFile(), "config.yml");
|
|
||||||
if (!configFile.exists()) {
|
|
||||||
writeFile(configFile,
|
|
||||||
"#bStats collects some data for plugin authors like how many servers are using their plugins.",
|
|
||||||
"#To honor their work, you should not disable it.",
|
|
||||||
"#This has nearly no effect on the server performance!",
|
|
||||||
"#Check out https://bStats.org/ to learn more :)",
|
|
||||||
"enabled: true",
|
|
||||||
"serverUuid: \"" + UUID.randomUUID().toString() + "\"",
|
|
||||||
"logFailedRequests: false");
|
|
||||||
}
|
|
||||||
|
|
||||||
Configuration configuration = ConfigurationProvider.getProvider(YamlConfiguration.class).load(configFile);
|
|
||||||
|
|
||||||
// Load configuration
|
|
||||||
enabled = configuration.getBoolean("enabled", true);
|
|
||||||
serverUUID = configuration.getString("serverUuid");
|
|
||||||
logFailedRequests = configuration.getBoolean("logFailedRequests", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the first bStat Metrics class.
|
|
||||||
*
|
|
||||||
* @return The first bStats metrics class.
|
|
||||||
*/
|
|
||||||
private Class<?> getFirstBStatsClass() {
|
|
||||||
Path configPath = new File(plugin.dir, "plugins").toPath().resolve("bStats");
|
|
||||||
configPath.toFile().mkdirs();
|
|
||||||
File tempFile = new File(configPath.toFile(), "temp.txt");
|
|
||||||
|
|
||||||
try {
|
|
||||||
String className = readFile(tempFile);
|
|
||||||
if (className != null) {
|
|
||||||
try {
|
|
||||||
// Let's check if a class with the given name exists.
|
|
||||||
return Class.forName(className);
|
|
||||||
} catch (ClassNotFoundException ignored) { }
|
|
||||||
}
|
|
||||||
writeFile(tempFile, getClass().getName());
|
|
||||||
return getClass();
|
|
||||||
} catch (IOException e) {
|
|
||||||
if (logFailedRequests) {
|
|
||||||
plugin.getLogger().log(Level.WARNING, "Failed to get first bStats class!", e);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads the first line of the file.
|
|
||||||
*
|
|
||||||
* @param file The file to read. Cannot be null.
|
|
||||||
* @return The first line of the file or <code>null</code> if the file does not exist or is empty.
|
|
||||||
* @throws IOException If something did not work :(
|
|
||||||
*/
|
|
||||||
private String readFile(File file) throws IOException {
|
|
||||||
if (!file.exists()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
try (
|
|
||||||
FileReader fileReader = new FileReader(file);
|
|
||||||
BufferedReader bufferedReader = new BufferedReader(fileReader);
|
|
||||||
) {
|
|
||||||
return bufferedReader.readLine();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes a String to a file. It also adds a note for the user,
|
|
||||||
*
|
|
||||||
* @param file The file to write to. Cannot be null.
|
|
||||||
* @param lines The lines to write.
|
|
||||||
* @throws IOException If something did not work :(
|
|
||||||
*/
|
|
||||||
private void writeFile(File file, String... lines) throws IOException {
|
|
||||||
if (!file.exists()) {
|
|
||||||
file.createNewFile();
|
|
||||||
}
|
|
||||||
try (
|
|
||||||
FileWriter fileWriter = new FileWriter(file);
|
|
||||||
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)
|
|
||||||
) {
|
|
||||||
for (String line : lines) {
|
|
||||||
bufferedWriter.write(line);
|
|
||||||
bufferedWriter.newLine();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends the data to the bStats server.
|
|
||||||
*
|
|
||||||
* @param data The data to send.
|
|
||||||
* @throws Exception If the request failed.
|
|
||||||
*/
|
|
||||||
private static void sendData(JsonObject data) throws Exception {
|
|
||||||
if (data == null) {
|
|
||||||
throw new IllegalArgumentException("Data cannot be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection();
|
|
||||||
|
|
||||||
// Compress the data to save bandwidth
|
|
||||||
byte[] compressedData = compress(data.toString());
|
|
||||||
|
|
||||||
// Add headers
|
|
||||||
connection.setRequestMethod("POST");
|
|
||||||
connection.addRequestProperty("Accept", "application/json");
|
|
||||||
connection.addRequestProperty("Connection", "close");
|
|
||||||
connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request
|
|
||||||
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
|
|
||||||
connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format
|
|
||||||
connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION);
|
|
||||||
|
|
||||||
// Send data
|
|
||||||
connection.setDoOutput(true);
|
|
||||||
DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
|
|
||||||
outputStream.write(compressedData);
|
|
||||||
outputStream.flush();
|
|
||||||
outputStream.close();
|
|
||||||
|
|
||||||
connection.getInputStream().close(); // We don't care about the response - Just send our data :)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gzips the given String.
|
|
||||||
*
|
|
||||||
* @param str The string to gzip.
|
|
||||||
* @return The gzipped String.
|
|
||||||
* @throws IOException If the compression failed.
|
|
||||||
*/
|
|
||||||
private static byte[] compress(final String str) throws IOException {
|
|
||||||
if (str == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
|
||||||
GZIPOutputStream gzip = new GZIPOutputStream(outputStream);
|
|
||||||
gzip.write(str.getBytes("UTF-8"));
|
|
||||||
gzip.close();
|
|
||||||
return outputStream.toByteArray();
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Represents a custom chart.
|
|
||||||
*/
|
|
||||||
private static abstract class CustomChart {
|
|
||||||
|
|
||||||
// The id of the chart
|
|
||||||
private final String chartId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class constructor.
|
|
||||||
*
|
|
||||||
* @param chartId The id of the chart.
|
|
||||||
*/
|
|
||||||
CustomChart(String chartId) {
|
|
||||||
if (chartId == null || chartId.isEmpty()) {
|
|
||||||
throw new IllegalArgumentException("ChartId cannot be null or empty!");
|
|
||||||
}
|
|
||||||
this.chartId = chartId;
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonObject getRequestJsonObject(Logger logger, boolean logFailedRequests) {
|
|
||||||
JsonObject chart = new JsonObject();
|
|
||||||
chart.addProperty("chartId", chartId);
|
|
||||||
try {
|
|
||||||
JsonObject data = getChartData();
|
|
||||||
if (data == null) {
|
|
||||||
// If the data is null we don't send the chart.
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
chart.add("data", data);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
if (logFailedRequests) {
|
|
||||||
logger.log(Level.WARNING, "Failed to get data for custom chart with id " + chartId, t);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return chart;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract JsonObject getChartData() throws Exception;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a custom single line chart.
|
|
||||||
*/
|
|
||||||
private static class SingleLineChart extends CustomChart {
|
|
||||||
|
|
||||||
private final Callable<Integer> callable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class constructor.
|
|
||||||
*
|
|
||||||
* @param chartId The id of the chart.
|
|
||||||
* @param callable The callable which is used to request the chart data.
|
|
||||||
*/
|
|
||||||
public SingleLineChart(String chartId, Callable<Integer> callable) {
|
|
||||||
super(chartId);
|
|
||||||
this.callable = callable;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected JsonObject getChartData() throws Exception {
|
|
||||||
JsonObject data = new JsonObject();
|
|
||||||
int value = callable.call();
|
|
||||||
if (value == 0) {
|
|
||||||
// Null = skip the chart
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
data.addProperty("value", value);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
package net.ME1312.SubServers.Bungee.Library;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Named Container Class
|
|
||||||
* @param <T> Name
|
|
||||||
* @param <V> Item
|
|
||||||
*/
|
|
||||||
public class NamedContainer<T, V> extends Container<V> {
|
|
||||||
private T name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a TaggedContainer
|
|
||||||
*
|
|
||||||
* @param name Tag to Bind
|
|
||||||
* @param item Object to Store
|
|
||||||
*/
|
|
||||||
public NamedContainer(T name, V item) {
|
|
||||||
super(item);
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the name of the Container
|
|
||||||
*
|
|
||||||
* @return Container name
|
|
||||||
*/
|
|
||||||
public T name() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renames the Container
|
|
||||||
*
|
|
||||||
* @param name New Container Name
|
|
||||||
*/
|
|
||||||
public void rename(T name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object object) {
|
|
||||||
if (object instanceof NamedContainer) {
|
|
||||||
if (name == null || ((NamedContainer) object).name() == null) {
|
|
||||||
return name == ((NamedContainer) object).name() && super.equals(object);
|
|
||||||
} else {
|
|
||||||
return name.equals(((NamedContainer) object).name()) && super.equals(object);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return super.equals(object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
package net.ME1312.SubServers.Bungee.Library;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File Replacement Scanner
|
||||||
|
*/
|
||||||
|
public class ReplacementScanner extends FileScanner {
|
||||||
|
private final Map<String, String> replacements = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
public ReplacementScanner(Map<String, String> replacements) {
|
||||||
|
TreeMap<Integer, LinkedList<String>> order = new TreeMap<Integer, LinkedList<String>>(Comparator.reverseOrder());
|
||||||
|
for (String key : replacements.keySet()) {
|
||||||
|
int length = key.length();
|
||||||
|
if (!order.containsKey(length)) order.put(length, new LinkedList<>());
|
||||||
|
order.get(length).add(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Integer length : order.keySet()) {
|
||||||
|
for (String key : order.get(length)) {
|
||||||
|
this.replacements.put(key, replacements.get(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the replacements
|
||||||
|
*
|
||||||
|
* @return Replacement Map
|
||||||
|
*/
|
||||||
|
public Map<String, String> getReplacements() {
|
||||||
|
return new HashMap<>(replacements);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make replacements in a File or Directory
|
||||||
|
*
|
||||||
|
* @param dir File or Directory
|
||||||
|
* @param whitelist File Whitelist
|
||||||
|
*/
|
||||||
|
public void replace(File dir, String... whitelist) throws IOException {
|
||||||
|
super.scan(dir, whitelist);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void act(File dir, String name) throws IOException {
|
||||||
|
File file = new File(dir, name);
|
||||||
|
FileInputStream stream = new FileInputStream(file);
|
||||||
|
String string = Util.readAll(new InputStreamReader(stream));
|
||||||
|
stream.close();
|
||||||
|
|
||||||
|
boolean update = false;
|
||||||
|
for (Map.Entry<String, String> replacement : replacements.entrySet()) {
|
||||||
|
String placeholder = "SubServers::" + replacement.getKey();
|
||||||
|
if (string.contains(placeholder)) {
|
||||||
|
string = string.replace(placeholder, replacement.getValue());
|
||||||
|
update = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (update) {
|
||||||
|
FileWriter writer = new FileWriter(file, false);
|
||||||
|
writer.write(string);
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make replacements in an Object
|
||||||
|
*
|
||||||
|
* @param value Map, Collection, Array, or String
|
||||||
|
* @return Object with replaced variables
|
||||||
|
*/
|
||||||
|
public Object replace(Object value) {
|
||||||
|
if (value instanceof Map) {
|
||||||
|
List<String> list = new ArrayList<String>();
|
||||||
|
list.addAll(((Map<String, Object>) value).keySet());
|
||||||
|
for (String key : list) ((Map<String, Object>) value).put(key, replace(((Map<String, Object>) value).get(key)));
|
||||||
|
return value;
|
||||||
|
} else if (value instanceof Collection) {
|
||||||
|
List<Object> list = new ArrayList<Object>();
|
||||||
|
for (Object val : (Collection<Object>) value) list.add(replace(val));
|
||||||
|
return list;
|
||||||
|
} else if (value.getClass().isArray()) {
|
||||||
|
List<Object> list = new ArrayList<Object>();
|
||||||
|
for (int i = 0; i < ((Object[]) value).length; i++) list.add(replace(((Object[]) value)[i]));
|
||||||
|
return list;
|
||||||
|
} else if (value instanceof String) {
|
||||||
|
return replaceObj((String) value);
|
||||||
|
} else {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
} private String replaceObj(String string) {
|
||||||
|
for (Map.Entry<String, String> replacement : replacements.entrySet()) string = string.replace('$' + replacement.getKey() + '$', replacement.getValue());
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,70 +0,0 @@
|
||||||
package net.ME1312.SubServers.Bungee.Library;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Universal File Class
|
|
||||||
*/
|
|
||||||
public class UniversalFile extends File {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a File Link. Path names are separated by ':'
|
|
||||||
*
|
|
||||||
* @param pathname Path name
|
|
||||||
*/
|
|
||||||
public UniversalFile(String pathname) {
|
|
||||||
super(pathname.replace(".:", System.getProperty("user.dir") + ":").replace(':', File.separatorChar));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a File Link. Path names are separated by the divider
|
|
||||||
*
|
|
||||||
* @param pathname Path name
|
|
||||||
* @param divider Divider to use
|
|
||||||
*/
|
|
||||||
public UniversalFile(String pathname, char divider) {
|
|
||||||
super(pathname.replace("." + divider, System.getProperty("user.dir") + divider).replace(divider, File.separatorChar));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a File Link.
|
|
||||||
*
|
|
||||||
* @see File
|
|
||||||
* @param file File
|
|
||||||
*/
|
|
||||||
public UniversalFile(File file) {
|
|
||||||
super(file.getPath());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a File. Path names are separated by the ':'
|
|
||||||
*
|
|
||||||
* @see File
|
|
||||||
* @param parent Parent File
|
|
||||||
* @param child Path name
|
|
||||||
*/
|
|
||||||
public UniversalFile(File parent, String child) {
|
|
||||||
super(parent, child.replace(':', File.separatorChar));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a File. Path names are separated by the divider
|
|
||||||
*
|
|
||||||
* @see File
|
|
||||||
* @param parent Parent File
|
|
||||||
* @param child Path name
|
|
||||||
* @param divider Divider to use
|
|
||||||
*/
|
|
||||||
public UniversalFile(File parent, String child, char divider) {
|
|
||||||
super(parent, child.replace(divider, File.separatorChar));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the Universal File Path (separated by ':')
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public String getUniversalPath() {
|
|
||||||
return getPath().replace(File.separatorChar, ':');
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,476 +0,0 @@
|
||||||
package net.ME1312.SubServers.Bungee.Library;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.LinkOption;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.zip.ZipEntry;
|
|
||||||
import java.util.zip.ZipInputStream;
|
|
||||||
import java.util.zip.ZipOutputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SubServers Utility Class
|
|
||||||
*/
|
|
||||||
public final class Util {
|
|
||||||
private Util(){}
|
|
||||||
public interface ExceptionReturnRunnable<R> {
|
|
||||||
R run() throws Throwable;
|
|
||||||
}
|
|
||||||
public interface ExceptionRunnable {
|
|
||||||
void run() throws Throwable;
|
|
||||||
}
|
|
||||||
public interface ReturnRunnable<R> {
|
|
||||||
R run();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks values to make sure they're not null
|
|
||||||
*
|
|
||||||
* @param values Values to check
|
|
||||||
* @return If any are null
|
|
||||||
*/
|
|
||||||
public static boolean isNull(Object... values) {
|
|
||||||
boolean ret = false;
|
|
||||||
for (Object value : values) {
|
|
||||||
if (value == null) ret = true;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get keys by value from map
|
|
||||||
*
|
|
||||||
* @param map Map to search
|
|
||||||
* @param value Value to search for
|
|
||||||
* @param <K> Key
|
|
||||||
* @param <V> Value
|
|
||||||
* @return Search results
|
|
||||||
*/
|
|
||||||
public static <K, V> List<K> getBackwards(Map<K, V> map, V value) {
|
|
||||||
List<K> values = new ArrayList<K>();
|
|
||||||
|
|
||||||
for (K key : map.keySet()) {
|
|
||||||
if (map.get(key).equals(value)) {
|
|
||||||
values.add(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an item from a map ignoring case
|
|
||||||
*
|
|
||||||
* @param map Map to search
|
|
||||||
* @param key Key to search with
|
|
||||||
* @param <V> Value
|
|
||||||
* @return Search Result
|
|
||||||
*/
|
|
||||||
public static <V> V getCaseInsensitively(Map<String, V> map, String key) {
|
|
||||||
HashMap<String, String> insensitivity = new HashMap<String, String>();
|
|
||||||
for (String item : map.keySet()) if (!insensitivity.keySet().contains(item.toLowerCase())) insensitivity.put(item.toLowerCase(), item);
|
|
||||||
if (insensitivity.keySet().contains(key.toLowerCase())) {
|
|
||||||
return map.get(insensitivity.get(key.toLowerCase()));
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a new Variable that doesn't match the existing Variables
|
|
||||||
*
|
|
||||||
* @param existing Existing Variables
|
|
||||||
* @param generator Variable Generator
|
|
||||||
* @param <V> Variable Type
|
|
||||||
* @return Variable
|
|
||||||
*/
|
|
||||||
public static <V> V getNew(Collection<? extends V> existing, ReturnRunnable<V> generator) {
|
|
||||||
V result = null;
|
|
||||||
while (result == null) {
|
|
||||||
V tmp = generator.run();
|
|
||||||
if (!existing.contains(tmp)) result = tmp;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read Everything from Reader
|
|
||||||
*
|
|
||||||
* @param rd Reader
|
|
||||||
* @return Reader Contents
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public static String readAll(Reader rd) throws IOException {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
int cp;
|
|
||||||
while ((cp = rd.read()) != -1) {
|
|
||||||
sb.append((char) cp);
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy from the Class Loader
|
|
||||||
*
|
|
||||||
* @param loader ClassLoader
|
|
||||||
* @param resource Location From
|
|
||||||
* @param destination Location To
|
|
||||||
*/
|
|
||||||
public static void copyFromJar(ClassLoader loader, String resource, String destination) {
|
|
||||||
InputStream resStreamIn = loader.getResourceAsStream(resource);
|
|
||||||
File resDestFile = new File(destination);
|
|
||||||
try {
|
|
||||||
OutputStream resStreamOut = new FileOutputStream(resDestFile);
|
|
||||||
int readBytes;
|
|
||||||
byte[] buffer = new byte[4096];
|
|
||||||
while ((readBytes = resStreamIn.read(buffer)) > 0) {
|
|
||||||
resStreamOut.write(buffer, 0, readBytes);
|
|
||||||
}
|
|
||||||
resStreamOut.close();
|
|
||||||
resStreamIn.close();
|
|
||||||
} catch (Exception ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a Field's value using Reflection
|
|
||||||
*
|
|
||||||
* @param field Field to grab
|
|
||||||
* @param instance Object Instance (Null for static fields)
|
|
||||||
* @param <R> Return Type
|
|
||||||
* @return Field Value
|
|
||||||
* @throws IllegalAccessException
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static <R> R reflect(Field field, Object instance) throws IllegalAccessException {
|
|
||||||
R value;
|
|
||||||
field.setAccessible(true);
|
|
||||||
value = (R) field.get(instance);
|
|
||||||
field.setAccessible(false);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a Field's value using Reflection
|
|
||||||
*
|
|
||||||
* @param field Field to write to
|
|
||||||
* @param instance Object Instance (Null for static fields)
|
|
||||||
* @param value Value to write
|
|
||||||
* @throws IllegalAccessException
|
|
||||||
*/
|
|
||||||
public static void reflect(Field field, Object instance, Object value) throws IllegalAccessException {
|
|
||||||
field.setAccessible(true);
|
|
||||||
field.set(instance, value);
|
|
||||||
field.setAccessible(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call a method using Reflection
|
|
||||||
*
|
|
||||||
* @param method Method to call
|
|
||||||
* @param instance Object Instance (Null for static methods)
|
|
||||||
* @param arguments Method Arguments
|
|
||||||
* @param <R> Return Type
|
|
||||||
* @return Returned Value
|
|
||||||
* @throws InvocationTargetException
|
|
||||||
* @throws IllegalAccessException
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static <R> R reflect(Method method, Object instance, Object... arguments) throws InvocationTargetException, IllegalAccessException {
|
|
||||||
R value;
|
|
||||||
method.setAccessible(true);
|
|
||||||
value = (R) method.invoke(instance, arguments);
|
|
||||||
method.setAccessible(false);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct an object using Reflection
|
|
||||||
*
|
|
||||||
* @param constructor Constructor to use
|
|
||||||
* @param arguments Constructor Arguments
|
|
||||||
* @param <R> Return Type
|
|
||||||
* @return New Instance
|
|
||||||
* @throws InvocationTargetException
|
|
||||||
* @throws IllegalAccessException
|
|
||||||
* @throws InstantiationException
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static <R> R reflect(Constructor<?> constructor, Object... arguments) throws InvocationTargetException, IllegalAccessException, InstantiationException {
|
|
||||||
R value;
|
|
||||||
constructor.setAccessible(true);
|
|
||||||
value = (R) constructor.newInstance(arguments);
|
|
||||||
constructor.setAccessible(false);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a variable from a method which may throw an exception
|
|
||||||
*
|
|
||||||
* @param runnable Runnable
|
|
||||||
* @param def Default value when an exception is thrown
|
|
||||||
* @param <R> Variable Type
|
|
||||||
* @return Returns value or default depending on if an exception is thrown
|
|
||||||
*/
|
|
||||||
public static <R> R getDespiteException(ExceptionReturnRunnable<R> runnable, R def) {
|
|
||||||
try {
|
|
||||||
return runnable.run();
|
|
||||||
} catch (Throwable e) {
|
|
||||||
return def;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines if an Exception will occur
|
|
||||||
*
|
|
||||||
* @param runnable Runnable
|
|
||||||
* @return If an Exception occured
|
|
||||||
*/
|
|
||||||
public static boolean isException(ExceptionRunnable runnable) {
|
|
||||||
try {
|
|
||||||
runnable.run();
|
|
||||||
return false;
|
|
||||||
} catch (Throwable e) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete Directory
|
|
||||||
*
|
|
||||||
* @param folder Location
|
|
||||||
*/
|
|
||||||
public static void deleteDirectory(File folder) {
|
|
||||||
File[] files = folder.listFiles();
|
|
||||||
if(files!=null) {
|
|
||||||
for(File f : files) {
|
|
||||||
if(f.isDirectory() && !Files.isSymbolicLink(f.toPath())) {
|
|
||||||
deleteDirectory(f);
|
|
||||||
} else try {
|
|
||||||
Files.delete(f.toPath());
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
folder.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy a Directory
|
|
||||||
*
|
|
||||||
* @param from Source
|
|
||||||
* @param to Destination
|
|
||||||
*/
|
|
||||||
public static void copyDirectory(File from, File to) {
|
|
||||||
if (from.isDirectory() && !Files.isSymbolicLink(from.toPath())) {
|
|
||||||
if (!to.exists()) {
|
|
||||||
to.mkdirs();
|
|
||||||
}
|
|
||||||
|
|
||||||
String files[] = from.list();
|
|
||||||
|
|
||||||
for (String file : files) {
|
|
||||||
File srcFile = new File(from, file);
|
|
||||||
File destFile = new File(to, file);
|
|
||||||
|
|
||||||
copyDirectory(srcFile, destFile);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
Files.copy(from.toPath(), to.toPath(), LinkOption.NOFOLLOW_LINKS);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<String> zipsearch(File origin, File file) {
|
|
||||||
List<String> list = new LinkedList<String>();
|
|
||||||
if (file.isFile()) {
|
|
||||||
list.add(file.getAbsoluteFile().toString().substring(origin.getAbsoluteFile().toString().length()+1, file.getAbsoluteFile().toString().length()));
|
|
||||||
}
|
|
||||||
if (file.isDirectory()) for (File next : file.listFiles()) {
|
|
||||||
list.addAll(zipsearch(origin, next));
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void zip(File file, OutputStream zip) {
|
|
||||||
byte[] buffer = new byte[1024];
|
|
||||||
|
|
||||||
try{
|
|
||||||
ZipOutputStream zos = new ZipOutputStream(zip);
|
|
||||||
|
|
||||||
for(String next : zipsearch(file, file)){
|
|
||||||
ZipEntry ze= new ZipEntry(next);
|
|
||||||
zos.putNextEntry(ze);
|
|
||||||
|
|
||||||
FileInputStream in = new FileInputStream(file.getAbsolutePath() + File.separator + next);
|
|
||||||
|
|
||||||
int len;
|
|
||||||
while ((len = in.read(buffer)) > 0) {
|
|
||||||
zos.write(buffer, 0, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
in.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
zos.closeEntry();
|
|
||||||
zos.close();
|
|
||||||
} catch(IOException ex){
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void unzip(InputStream zip, File dir) {
|
|
||||||
byte[] buffer = new byte[1024];
|
|
||||||
try{
|
|
||||||
ZipInputStream zis = new ZipInputStream(zip);
|
|
||||||
ZipEntry ze;
|
|
||||||
while ((ze = zis.getNextEntry()) != null) {
|
|
||||||
File newFile = new File(dir + File.separator + ze.getName());
|
|
||||||
if (newFile.exists()) {
|
|
||||||
if (newFile.isDirectory()) {
|
|
||||||
Util.deleteDirectory(newFile);
|
|
||||||
} else {
|
|
||||||
newFile.delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ze.isDirectory()) {
|
|
||||||
newFile.mkdirs();
|
|
||||||
continue;
|
|
||||||
} else if (!newFile.getParentFile().exists()) {
|
|
||||||
newFile.getParentFile().mkdirs();
|
|
||||||
}
|
|
||||||
FileOutputStream fos = new FileOutputStream(newFile);
|
|
||||||
int len;
|
|
||||||
while ((len = zis.read(buffer)) > 0) {
|
|
||||||
fos.write(buffer, 0, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
fos.close();
|
|
||||||
}
|
|
||||||
zis.closeEntry();
|
|
||||||
zis.close();
|
|
||||||
} catch(IOException ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a Random Integer
|
|
||||||
*
|
|
||||||
* @param min Minimum Value
|
|
||||||
* @param max Maximum Value
|
|
||||||
* @return Random Integer
|
|
||||||
*/
|
|
||||||
public static int random(int min, int max) {
|
|
||||||
return new Random().nextInt((max - min) + 1) + min;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse escapes in a Java String
|
|
||||||
*
|
|
||||||
* @param str String
|
|
||||||
* @return Unescaped String
|
|
||||||
*/
|
|
||||||
public static String unescapeJavaString(String str) {
|
|
||||||
StringBuilder sb = new StringBuilder(str.length());
|
|
||||||
|
|
||||||
for (int i = 0; i < str.length(); i++) {
|
|
||||||
int ch = str.codePointAt(i);
|
|
||||||
if (ch == '\\') {
|
|
||||||
int nextChar = (i == str.length() - 1) ? '\\' : str
|
|
||||||
.codePointAt(i + 1);
|
|
||||||
// Octal escape?
|
|
||||||
if (nextChar >= '0' && nextChar <= '7') {
|
|
||||||
StringBuilder code = new StringBuilder();
|
|
||||||
code.appendCodePoint(nextChar);
|
|
||||||
i++;
|
|
||||||
if ((i < str.length() - 1) && str.codePointAt(i + 1) >= '0'
|
|
||||||
&& str.codePointAt(i + 1) <= '7') {
|
|
||||||
code.appendCodePoint(str.codePointAt(i + 1));
|
|
||||||
i++;
|
|
||||||
if ((i < str.length() - 1) && str.codePointAt(i + 1) >= '0'
|
|
||||||
&& str.codePointAt(i + 1) <= '7') {
|
|
||||||
code.appendCodePoint(str.codePointAt(i + 1));
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sb.append((char) Integer.parseInt(code.toString(), 8));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
switch (nextChar) {
|
|
||||||
case '\\':
|
|
||||||
ch = '\\';
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
ch = '\b';
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
ch = '\f';
|
|
||||||
break;
|
|
||||||
case 'n':
|
|
||||||
ch = '\n';
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
ch = '\r';
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
ch = '\t';
|
|
||||||
break;
|
|
||||||
case '\"':
|
|
||||||
ch = '\"';
|
|
||||||
break;
|
|
||||||
case '\'':
|
|
||||||
ch = '\'';
|
|
||||||
break;
|
|
||||||
// Hex Unicode Char: u????
|
|
||||||
// Hex Unicode Codepoint: u{??????}
|
|
||||||
case 'u':
|
|
||||||
try {
|
|
||||||
if (i >= str.length() - 4) throw new IllegalStateException();
|
|
||||||
StringBuilder escape = new StringBuilder();
|
|
||||||
int offset = 2;
|
|
||||||
|
|
||||||
if (str.codePointAt(i + 2) != '{') {
|
|
||||||
if (i >= str.length() - 5) throw new IllegalStateException();
|
|
||||||
while (offset <= 5) {
|
|
||||||
Integer.toString(str.codePointAt(i + offset), 16);
|
|
||||||
escape.appendCodePoint(str.codePointAt(i + offset));
|
|
||||||
offset++;
|
|
||||||
}
|
|
||||||
offset--;
|
|
||||||
} else {
|
|
||||||
offset++;
|
|
||||||
while (str.codePointAt(i + offset) != '}') {
|
|
||||||
Integer.toString(str.codePointAt(i + offset), 16);
|
|
||||||
escape.appendCodePoint(str.codePointAt(i + offset));
|
|
||||||
offset++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sb.append(new String(new int[]{
|
|
||||||
Integer.parseInt(escape.toString(), 16)
|
|
||||||
}, 0, 1));
|
|
||||||
|
|
||||||
i += offset;
|
|
||||||
continue;
|
|
||||||
} catch (Throwable e){
|
|
||||||
sb.append('\\');
|
|
||||||
ch = 'u';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
sb.appendCodePoint(ch);
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,411 +0,0 @@
|
||||||
package net.ME1312.SubServers.Bungee.Library.Version;
|
|
||||||
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Version Class
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("serial")
|
|
||||||
public class Version implements Serializable, Comparable<Version> {
|
|
||||||
private final Version parent;
|
|
||||||
private final VersionType type;
|
|
||||||
private final String string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Version
|
|
||||||
*
|
|
||||||
* @param string Version String
|
|
||||||
*/
|
|
||||||
public Version(String string) {
|
|
||||||
this(VersionType.VERSION, string);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Version
|
|
||||||
*
|
|
||||||
* @param type Version Type
|
|
||||||
* @param string Version String
|
|
||||||
*/
|
|
||||||
public Version(VersionType type, String string) {
|
|
||||||
this(null, type, string);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Version (Appending the parent)
|
|
||||||
*
|
|
||||||
* @param parent Parent Version
|
|
||||||
* @param string Version String
|
|
||||||
*/
|
|
||||||
public Version(Version parent, String string) {
|
|
||||||
this(parent, VersionType.VERSION, string);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Version (Appending the parent)
|
|
||||||
*
|
|
||||||
* @param parent Parent Version
|
|
||||||
* @param type Version Type
|
|
||||||
* @param string Version String
|
|
||||||
*/
|
|
||||||
public Version(Version parent, VersionType type, String string) {
|
|
||||||
if (Util.isNull(string, type)) throw new NullPointerException();
|
|
||||||
this.parent = parent;
|
|
||||||
this.type = type;
|
|
||||||
this.string = string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Version
|
|
||||||
*
|
|
||||||
* @param ints Version Numbers (Will be separated with dots)
|
|
||||||
*/
|
|
||||||
public Version(int... ints) {
|
|
||||||
this(VersionType.VERSION, ints);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Version
|
|
||||||
*
|
|
||||||
* @param type Version Type
|
|
||||||
* @param ints Version Numbers (Will be separated with dots)
|
|
||||||
*/
|
|
||||||
public Version(VersionType type, int... ints) {
|
|
||||||
this(null, type, ints);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Version (Appending the parent)
|
|
||||||
*
|
|
||||||
* @param parent Parent Version
|
|
||||||
* @param ints Version Numbers (Will be separated with dots)
|
|
||||||
*/
|
|
||||||
public Version(Version parent, int... ints) {
|
|
||||||
this(parent, VersionType.VERSION, ints);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Version (Appending the parent)
|
|
||||||
*
|
|
||||||
* @param parent Parent Version
|
|
||||||
* @param type Version Type
|
|
||||||
* @param ints Version Numbers (Will be separated with dots)
|
|
||||||
*/
|
|
||||||
public Version(Version parent, VersionType type, int... ints) {
|
|
||||||
if (Util.isNull(type)) throw new NullPointerException();
|
|
||||||
this.parent = parent;
|
|
||||||
this.type = type;
|
|
||||||
String string = Integer.toString(ints[0]);
|
|
||||||
int i = 0;
|
|
||||||
if (ints.length != 1) {
|
|
||||||
do {
|
|
||||||
i++;
|
|
||||||
string = string + "." + ints[i];
|
|
||||||
} while ((i + 1) != ints.length);
|
|
||||||
}
|
|
||||||
this.string = string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse a Version from a string
|
|
||||||
*
|
|
||||||
* @param string String to parse
|
|
||||||
* @see #toFullString() <b>#toFullString()</b> returns a valid string
|
|
||||||
* @see #toFullString() <b>#toString()</b> returns a valid string
|
|
||||||
*/
|
|
||||||
public static Version fromString(String string) {
|
|
||||||
Matcher regex = Pattern.compile("(rv|p?[abrv]|[su])?([^/]+)", Pattern.CASE_INSENSITIVE).matcher(string);
|
|
||||||
Version current = null;
|
|
||||||
while (regex.find()) {
|
|
||||||
try {
|
|
||||||
VersionType type = VersionType.VERSION;
|
|
||||||
if (regex.group(1) != null) switch (regex.group(1).toLowerCase()) {
|
|
||||||
case "pa":
|
|
||||||
type = VersionType.PRE_ALPHA;
|
|
||||||
break;
|
|
||||||
case "a":
|
|
||||||
type = VersionType.ALPHA;
|
|
||||||
break;
|
|
||||||
case "pv":
|
|
||||||
type = VersionType.PREVIEW;
|
|
||||||
break;
|
|
||||||
case "pb":
|
|
||||||
type = VersionType.PRE_BETA;
|
|
||||||
break;
|
|
||||||
case "b":
|
|
||||||
type = VersionType.BETA;
|
|
||||||
break;
|
|
||||||
case "s":
|
|
||||||
type = VersionType.SNAPSHOT;
|
|
||||||
break;
|
|
||||||
case "pr":
|
|
||||||
type = VersionType.PRE_RELEASE;
|
|
||||||
break;
|
|
||||||
case "r":
|
|
||||||
type = VersionType.RELEASE;
|
|
||||||
break;
|
|
||||||
case "rv":
|
|
||||||
type = VersionType.REVISION;
|
|
||||||
break;
|
|
||||||
case "u":
|
|
||||||
type = VersionType.UPDATE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
current = new Version(current, type, regex.group(2));
|
|
||||||
} catch (Throwable e) {}
|
|
||||||
}
|
|
||||||
if (current == null) throw new IllegalArgumentException("Could not find version in string: " + string);
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The default toString() method<br>
|
|
||||||
* <br>
|
|
||||||
* <b style="font-family: consolas">new Version(new Version("1.0.0"), VersionType.PRE_ALPHA, "7")</b> would return:<br>
|
|
||||||
* <b style="font-family: consolas">1.0.0/pa7</b>
|
|
||||||
*
|
|
||||||
* @return Version as a String
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return ((parent == null)?"":parent.toString()+'/'+type.shortname) + string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The full toString() method<br>
|
|
||||||
* <br>
|
|
||||||
* <b style="font-family: consolas">new Version(new Version("1.0.0"), VersionType.PRE_ALPHA, "7")</b> would return:<br>
|
|
||||||
* <b style="font-family: consolas">r1.0.0/pa7</b>
|
|
||||||
*
|
|
||||||
* @return Version as a String
|
|
||||||
*/
|
|
||||||
public String toFullString() {
|
|
||||||
return ((parent == null)?"":parent.toFullString()+'/') + type.shortname + string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The extended toString() method<br>
|
|
||||||
* <br>
|
|
||||||
* <b style="font-family: consolas">new Version(new Version("1.0.0"), VersionType.PRE_ALPHA, "7")</b> would return:<br>
|
|
||||||
* <b style="font-family: consolas">1.0.0 pre-alpha 7</b>
|
|
||||||
*
|
|
||||||
* @return Version as a String
|
|
||||||
*/
|
|
||||||
public String toExtendedString() {
|
|
||||||
return ((parent == null)?"":parent.toExtendedString()+' '+type.longname+' ') + string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The full extended toString() method<br>
|
|
||||||
* <br>
|
|
||||||
* <b style="font-family: consolas">new Version(new Version("1.0.0"), VersionType.PRE_ALPHA, "7")</b> would return:<br>
|
|
||||||
* <b style="font-family: consolas">release 1.0.0 pre-alpha 7</b>
|
|
||||||
*
|
|
||||||
* @return Version as a String
|
|
||||||
*/
|
|
||||||
public String toFullExtendedString() {
|
|
||||||
return ((parent == null)?"":parent.toFullExtendedString()+' ') + type.longname + ' ' + string;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object object) {
|
|
||||||
if (object instanceof Version) {
|
|
||||||
return equals((Version) object);
|
|
||||||
} else {
|
|
||||||
return super.equals(object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* See if Versions are Equal
|
|
||||||
*
|
|
||||||
* @param version Version to Compare to
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public boolean equals(Version version) {
|
|
||||||
return compareTo(version) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns 1 if Greater than
|
|
||||||
* Returns 0 if Equal
|
|
||||||
* Returns -1 if Less than
|
|
||||||
*//**
|
|
||||||
*
|
|
||||||
* Compare Versions
|
|
||||||
*
|
|
||||||
* @param version Version to Compare to
|
|
||||||
*/
|
|
||||||
public int compareTo(Version version) {
|
|
||||||
return compare(this, version);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* See if Versions are Equal
|
|
||||||
*
|
|
||||||
* @param ver1 Version to Compare
|
|
||||||
* @param ver2 Version to Compare
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static boolean equals(Version ver1, Version ver2) {
|
|
||||||
return compare(ver1, ver2) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns 1 if Greater than
|
|
||||||
* Returns 0 if Equal
|
|
||||||
* Returns -1 if Less than
|
|
||||||
*//**
|
|
||||||
* Compare Versions
|
|
||||||
*
|
|
||||||
* @param ver1 Version to Compare
|
|
||||||
* @param ver2 Version to Compare
|
|
||||||
*/
|
|
||||||
public static int compare(Version ver1, Version ver2) {
|
|
||||||
if (ver1 == null && ver2 == null) {
|
|
||||||
// Both versions are null
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ver1 == null) {
|
|
||||||
// Version one is null
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ver2 == null) {
|
|
||||||
// Version two is null
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
LinkedList<Version> stack1 = new LinkedList<Version>();
|
|
||||||
stack1.add(ver1);
|
|
||||||
while (ver1.parent != null) {
|
|
||||||
ver1 = ver1.parent;
|
|
||||||
stack1.add(ver1);
|
|
||||||
}
|
|
||||||
Collections.reverse(stack1);
|
|
||||||
|
|
||||||
LinkedList<Version> stack2 = new LinkedList<Version>();
|
|
||||||
stack2.add(ver2);
|
|
||||||
while (ver2.parent != null) {
|
|
||||||
ver2 = ver2.parent;
|
|
||||||
stack2.add(ver2);
|
|
||||||
}
|
|
||||||
Collections.reverse(stack2);
|
|
||||||
|
|
||||||
int id;
|
|
||||||
for (id = 0; id < stack1.size(); id++) {
|
|
||||||
if (id >= stack2.size()) {
|
|
||||||
// Version one still has children when version two does not...
|
|
||||||
if (stack1.get(id).type.stageid < 0) {
|
|
||||||
// ...making version two the official version
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
// ...however the direct child of version one has a stageid higher than or equal to a release
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int result = stack1.get(id).compare(stack2.get(id));
|
|
||||||
if (result != 0) {
|
|
||||||
// Versions are not the same, return the result
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (id < stack2.size()) {
|
|
||||||
// Version one does not children when version two still does...
|
|
||||||
if (stack2.get(id).type.stageid < 0) {
|
|
||||||
// ...making version one the official version
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
// ...however the direct child of version two has a stageid higher than or equal to a release
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Compares versions ignoring parent/child relationships
|
|
||||||
*/
|
|
||||||
private int compare(Version version) {
|
|
||||||
if (this.type.stageid > version.type.stageid) {
|
|
||||||
// Version one has a type of a later stage than version two
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.type.stageid < version.type.stageid) {
|
|
||||||
// Version one has a type of an earlier stage than version two
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
VersionTokenizer tokenizer1 = new VersionTokenizer(string);
|
|
||||||
VersionTokenizer tokenizer2 = new VersionTokenizer(version.string);
|
|
||||||
|
|
||||||
int number1, number2;
|
|
||||||
String suffix1, suffix2;
|
|
||||||
|
|
||||||
while (tokenizer1.MoveNext()) {
|
|
||||||
if (!tokenizer2.MoveNext()) {
|
|
||||||
do {
|
|
||||||
number1 = tokenizer1.getNumber();
|
|
||||||
suffix1 = tokenizer1.getSuffix();
|
|
||||||
if (number1 != 0 || suffix1.length() != 0) {
|
|
||||||
// Version one is longer than number two, and non-zero
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (tokenizer1.MoveNext());
|
|
||||||
|
|
||||||
// Version one is longer than version two, but zero
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
number1 = tokenizer1.getNumber();
|
|
||||||
suffix1 = tokenizer1.getSuffix();
|
|
||||||
number2 = tokenizer2.getNumber();
|
|
||||||
suffix2 = tokenizer2.getSuffix();
|
|
||||||
|
|
||||||
if (number1 < number2) {
|
|
||||||
// Number one is less than number two
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (number1 > number2) {
|
|
||||||
// Number one is greater than number two
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean empty1 = suffix1.length() == 0;
|
|
||||||
boolean empty2 = suffix2.length() == 0;
|
|
||||||
|
|
||||||
if (empty1 && empty2) continue; // No suffixes
|
|
||||||
if (empty1) return 1; // First suffix is empty (1.2 > 1.2b)
|
|
||||||
if (empty2) return -1; // Second suffix is empty (1.2a < 1.2)
|
|
||||||
|
|
||||||
// Lexical comparison of suffixes
|
|
||||||
int result = suffix1.compareTo(suffix2);
|
|
||||||
if (result != 0) return result;
|
|
||||||
|
|
||||||
}
|
|
||||||
if (tokenizer2.MoveNext()) {
|
|
||||||
do {
|
|
||||||
number2 = tokenizer2.getNumber();
|
|
||||||
suffix2 = tokenizer2.getSuffix();
|
|
||||||
if (number2 != 0 || suffix2.length() != 0) {
|
|
||||||
// Version one is longer than version two, and non-zero
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (tokenizer2.MoveNext());
|
|
||||||
|
|
||||||
// Version two is longer than version one, but zero
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
package net.ME1312.SubServers.Bungee.Library.Version;
|
|
||||||
|
|
||||||
final class VersionTokenizer {
|
|
||||||
private final String _versionString;
|
|
||||||
private final int _length;
|
|
||||||
|
|
||||||
private int _position;
|
|
||||||
private int _number;
|
|
||||||
private String _suffix;
|
|
||||||
private boolean _hasValue;
|
|
||||||
|
|
||||||
protected int getNumber() {
|
|
||||||
return _number;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String getSuffix() {
|
|
||||||
return _suffix;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean hasValue() {
|
|
||||||
return _hasValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected VersionTokenizer(String versionString) {
|
|
||||||
if (versionString == null)
|
|
||||||
throw new IllegalArgumentException("versionString is null");
|
|
||||||
|
|
||||||
_versionString = versionString;
|
|
||||||
_length = versionString.length();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean MoveNext() {
|
|
||||||
_number = 0;
|
|
||||||
_suffix = "";
|
|
||||||
_hasValue = false;
|
|
||||||
|
|
||||||
// No more characters
|
|
||||||
if (_position >= _length)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
_hasValue = true;
|
|
||||||
|
|
||||||
while (_position < _length) {
|
|
||||||
char c = _versionString.charAt(_position);
|
|
||||||
if (c < '0' || c > '9') break;
|
|
||||||
_number = _number * 10 + (c - '0');
|
|
||||||
_position++;
|
|
||||||
}
|
|
||||||
|
|
||||||
int suffixStart = _position;
|
|
||||||
|
|
||||||
while (_position < _length) {
|
|
||||||
char c = _versionString.charAt(_position);
|
|
||||||
if (c == '.') break;
|
|
||||||
_position++;
|
|
||||||
}
|
|
||||||
|
|
||||||
_suffix = _versionString.substring(suffixStart, _position);
|
|
||||||
|
|
||||||
if (_position < _length) _position++;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
package net.ME1312.SubServers.Bungee.Library.Version;
|
|
||||||
|
|
||||||
public enum VersionType {
|
|
||||||
PRE_ALPHA(-6, "pa", "pre-alpha"),
|
|
||||||
ALPHA(-5, "a", "alpha"),
|
|
||||||
PREVIEW(-4, "pv", "preview"),
|
|
||||||
PRE_BETA(-4, "pb", "pre-beta"),
|
|
||||||
BETA(-3, "b", "beta"),
|
|
||||||
SNAPSHOT(-2, "s", "snapshot"),
|
|
||||||
PRE_RELEASE(-1, "pr", "pre-release"),
|
|
||||||
RELEASE(0, "r", "release"),
|
|
||||||
REVISION(0, "rv", "revision"),
|
|
||||||
VERSION(0, "v", "version"),
|
|
||||||
UPDATE(0, "u", "update"),
|
|
||||||
;
|
|
||||||
final short stageid;
|
|
||||||
final String shortname, longname;
|
|
||||||
VersionType(int stageid, String shortname, String longname) {
|
|
||||||
this.stageid = (short) stageid;
|
|
||||||
this.shortname = shortname;
|
|
||||||
this.longname = longname;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
package net.ME1312.SubServers.Bungee.Network;
|
|
||||||
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
|
||||||
import org.msgpack.value.Value;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SubData Cipher Layout Class
|
|
||||||
*/
|
|
||||||
public interface Cipher {
|
|
||||||
/**
|
|
||||||
* Get the name of this Cipher
|
|
||||||
*
|
|
||||||
* @return Cipher Name
|
|
||||||
*/
|
|
||||||
String getName();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encrypt JSON Data
|
|
||||||
*
|
|
||||||
* @param key Key to Encrypt Data with
|
|
||||||
* @param data Data to Encrypt
|
|
||||||
* @return Encrypted Data Array
|
|
||||||
*/
|
|
||||||
Value encrypt(String key, YAMLSection data) throws Exception;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decrypt Encrypted JSON Data
|
|
||||||
*
|
|
||||||
* @param key Key to Decrypt Data with
|
|
||||||
* @param data Encrypted Data Array
|
|
||||||
* @return JSON Data
|
|
||||||
*/
|
|
||||||
YAMLSection decrypt(String key, Value data) throws Exception;
|
|
||||||
}
|
|
|
@ -1,225 +0,0 @@
|
||||||
package net.ME1312.SubServers.Bungee.Network;
|
|
||||||
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Exception.IllegalPacketException;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketAuthorization;
|
|
||||||
import org.msgpack.core.MessageInsufficientBufferException;
|
|
||||||
import org.msgpack.core.MessagePack;
|
|
||||||
import org.msgpack.core.MessagePacker;
|
|
||||||
import org.msgpack.core.MessageUnpacker;
|
|
||||||
import org.msgpack.value.Value;
|
|
||||||
import org.yaml.snakeyaml.error.YAMLException;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.net.Socket;
|
|
||||||
import java.net.SocketException;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Network Client Class
|
|
||||||
*/
|
|
||||||
public class Client {
|
|
||||||
private Socket socket;
|
|
||||||
private InetSocketAddress address;
|
|
||||||
private ClientHandler handler;
|
|
||||||
private MessagePacker out;
|
|
||||||
private Timer authorized;
|
|
||||||
private SubDataServer subdata;
|
|
||||||
boolean closed;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Network Client
|
|
||||||
*
|
|
||||||
* @param subdata SubData Direct Server
|
|
||||||
* @param client Socket to Bind
|
|
||||||
*/
|
|
||||||
public Client(SubDataServer subdata, Socket client) throws IOException {
|
|
||||||
if (Util.isNull(subdata, client)) throw new NullPointerException();
|
|
||||||
this.subdata = subdata;
|
|
||||||
closed = false;
|
|
||||||
socket = client;
|
|
||||||
out = MessagePack.newDefaultPacker(client.getOutputStream());
|
|
||||||
address = new InetSocketAddress(client.getInetAddress(), client.getPort());
|
|
||||||
authorized = new Timer("SubServers.Bungee::SubData_Authorization_Timeout(" + address.toString() + ')');
|
|
||||||
authorized.schedule(new TimerTask() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (!socket.isClosed()) try {
|
|
||||||
subdata.removeClient(Client.this);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 15000);
|
|
||||||
loop();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Network Loop
|
|
||||||
*/
|
|
||||||
private void loop() {
|
|
||||||
new Thread(() -> {
|
|
||||||
try {
|
|
||||||
MessageUnpacker in = MessagePack.newDefaultUnpacker(socket.getInputStream());
|
|
||||||
Value input;
|
|
||||||
while ((input = in.unpackValue()) != null) {
|
|
||||||
recievePacket(input);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
subdata.removeClient(Client.this);
|
|
||||||
} catch (IOException e1) {
|
|
||||||
e1.printStackTrace();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
if (!(e instanceof SocketException || e instanceof MessageInsufficientBufferException)) e.printStackTrace();
|
|
||||||
try {
|
|
||||||
subdata.removeClient(Client.this);
|
|
||||||
} catch (IOException e1) {
|
|
||||||
e1.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, "SubServers.Bungee::SubData_Packet_Listener(" + address.toString() + ')').start();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void recievePacket(Value input) {
|
|
||||||
try {
|
|
||||||
YAMLSection data = subdata.getCipher().decrypt(subdata.plugin.config.get().getSection("Settings").getSection("SubData").getRawString("Password"), input);
|
|
||||||
for (PacketIn packet : SubDataServer.decodePacket(this, data)) {
|
|
||||||
boolean auth = authorized == null;
|
|
||||||
if (auth || packet instanceof PacketAuthorization) {
|
|
||||||
try {
|
|
||||||
if (data.contains("f")) {
|
|
||||||
if (data.getString("f").length() <= 0) {
|
|
||||||
List<Client> clients = new ArrayList<Client>();
|
|
||||||
clients.addAll(subdata.getClients());
|
|
||||||
for (Client client : clients) {
|
|
||||||
client.out.packValue(input);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Client client = subdata.getClient(data.getString("f"));
|
|
||||||
if (client != null) {
|
|
||||||
client.out.packValue(input);
|
|
||||||
} else {
|
|
||||||
throw new IllegalPacketException(getAddress().toString() + ": Unknown Forward Address: " + data.getString("f"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
packet.execute(Client.this, (data.contains("c")) ? data.getSection("c") : null);
|
|
||||||
}
|
|
||||||
} catch (Throwable e) {
|
|
||||||
new InvocationTargetException(e, getAddress().toString() + ": Exception while executing PacketIn").printStackTrace();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sendPacket(new PacketAuthorization(-1, "Unauthorized"));
|
|
||||||
throw new IllegalPacketException(getAddress().toString() + ": Unauthorized call to packet type: " + data.getSection("h"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (YAMLException e) { // TODO
|
|
||||||
new IllegalPacketException(getAddress().toString() + ": Unknown Packet Format: " + input).printStackTrace();
|
|
||||||
} catch (IllegalPacketException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (Exception e) {
|
|
||||||
new InvocationTargetException(e, getAddress().toString() + ": Exception while decoding packet").printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send Packet to Client
|
|
||||||
*
|
|
||||||
* @param packet Packet to send
|
|
||||||
*/
|
|
||||||
public void sendPacket(PacketOut packet) {
|
|
||||||
if (Util.isNull(packet)) throw new NullPointerException();
|
|
||||||
if (!isClosed()) try {
|
|
||||||
out.packValue(subdata.getCipher().encrypt(subdata.plugin.config.get().getSection("Settings").getSection("SubData").getRawString("Password"), SubDataServer.encodePacket(this, packet)));
|
|
||||||
out.flush();
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Authorize Connection
|
|
||||||
*/
|
|
||||||
public void authorize() {
|
|
||||||
if (authorized != null) {
|
|
||||||
authorized.cancel();
|
|
||||||
System.out.println("SubData > " + socket.getRemoteSocketAddress().toString() + " logged in");
|
|
||||||
}
|
|
||||||
authorized = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Raw Connection
|
|
||||||
*
|
|
||||||
* @return Socket
|
|
||||||
*/
|
|
||||||
public Socket getConnection() {
|
|
||||||
return socket;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get if the connection has been closed
|
|
||||||
*
|
|
||||||
* @return Closed Stauts
|
|
||||||
*/
|
|
||||||
public boolean isClosed() {
|
|
||||||
return closed && socket.isClosed();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Remote Address
|
|
||||||
*
|
|
||||||
* @return Address
|
|
||||||
*/
|
|
||||||
public InetSocketAddress getAddress() {
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the connection is authorized
|
|
||||||
*
|
|
||||||
* @return Authorization Status
|
|
||||||
*/
|
|
||||||
public boolean isAuthorized() {
|
|
||||||
return authorized == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the Linked Handler
|
|
||||||
*
|
|
||||||
* @return Handler
|
|
||||||
*/
|
|
||||||
public ClientHandler getHandler() {
|
|
||||||
return handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the Handler
|
|
||||||
*
|
|
||||||
* @param obj Handler
|
|
||||||
*/
|
|
||||||
public void setHandler(ClientHandler obj) {
|
|
||||||
if (handler != null && handler.getSubData() != null && equals(handler.getSubData())) handler.setSubData(null);
|
|
||||||
handler = obj;
|
|
||||||
if (handler != null && (handler.getSubData() == null || !equals(handler.getSubData()))) handler.setSubData(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Disconnects the Client
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public void disconnect() throws IOException {
|
|
||||||
if (!socket.isClosed()) getConnection().close();
|
|
||||||
if (handler != null) {
|
|
||||||
setHandler(null);
|
|
||||||
handler = null;
|
|
||||||
}
|
|
||||||
closed = true;
|
|
||||||
if (subdata.getClients().contains(this)) subdata.removeClient(this);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package net.ME1312.SubServers.Bungee.Network;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Client Handler Layout Class
|
|
||||||
*/
|
|
||||||
public interface ClientHandler {
|
|
||||||
/**
|
|
||||||
* Gets the SubData Client
|
|
||||||
*
|
|
||||||
* @return SubData Client (or null if not linked)
|
|
||||||
*/
|
|
||||||
Client getSubData();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Link a SubData Client to this Object
|
|
||||||
*
|
|
||||||
* @see Client#setHandler(ClientHandler)
|
|
||||||
* @param client Client to Link
|
|
||||||
*/
|
|
||||||
void setSubData(Client client);
|
|
||||||
}
|
|
|
@ -1,333 +0,0 @@
|
||||||
package net.ME1312.SubServers.Bungee.Network.Encryption;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
|
||||||
import org.msgpack.core.MessageBufferPacker;
|
|
||||||
import org.msgpack.core.MessagePack;
|
|
||||||
import org.msgpack.core.MessagePacker;
|
|
||||||
import org.msgpack.value.Value;
|
|
||||||
import org.msgpack.value.ValueFactory;
|
|
||||||
|
|
||||||
import javax.crypto.*;
|
|
||||||
import javax.crypto.spec.IvParameterSpec;
|
|
||||||
import javax.crypto.spec.PBEKeySpec;
|
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
|
||||||
import java.io.*;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.security.InvalidAlgorithmParameterException;
|
|
||||||
import java.security.InvalidKeyException;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.SecureRandom;
|
|
||||||
import java.security.spec.InvalidKeySpecException;
|
|
||||||
import java.security.spec.InvalidParameterSpecException;
|
|
||||||
import java.security.spec.KeySpec;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A class to perform password-based AES encryption and decryption in CBC mode.
|
|
||||||
* 128, 192, and 256-bit encryption are supported, provided that the latter two
|
|
||||||
* are permitted by the Java runtime's jurisdiction policy files.
|
|
||||||
* <br/>
|
|
||||||
* The public interface for this class consists of the static methods
|
|
||||||
* {@link #encrypt} and {@link #decrypt}, which encrypt and decrypt arbitrary
|
|
||||||
* streams of data, respectively.
|
|
||||||
*
|
|
||||||
* @author dweymouth@gmail.com
|
|
||||||
*/
|
|
||||||
public final class AES implements net.ME1312.SubServers.Bungee.Network.Cipher {
|
|
||||||
|
|
||||||
// AES specification
|
|
||||||
private static final String CIPHER_SPEC = "AES/CBC/PKCS5Padding";
|
|
||||||
|
|
||||||
// Key derivation specification
|
|
||||||
private static final String KEYGEN_SPEC = "PBKDF2WithHmacSHA1";
|
|
||||||
private static final int SALT_LENGTH = 16; // in bytes
|
|
||||||
private static final int AUTH_KEY_LENGTH = 8; // in bytes
|
|
||||||
private static final int ITERATIONS = 32768;
|
|
||||||
|
|
||||||
// Process input/output streams in chunks
|
|
||||||
private static final int BUFFER_SIZE = 1024;
|
|
||||||
|
|
||||||
// Hold Data for use by SubData Cipher methods
|
|
||||||
private final int keyLength;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor for use as a SubData Cipher
|
|
||||||
*/
|
|
||||||
public AES(int keyLength) {
|
|
||||||
this.keyLength = keyLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return a new pseudorandom salt of the specified length
|
|
||||||
*/
|
|
||||||
private static byte[] generateSalt(int length) {
|
|
||||||
Random r = new SecureRandom();
|
|
||||||
byte[] salt = new byte[length];
|
|
||||||
r.nextBytes(salt);
|
|
||||||
return salt;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Derive an AES encryption key and authentication key from given password and salt,
|
|
||||||
* using PBKDF2 key stretching. The authentication key is 64 bits long.
|
|
||||||
* @param keyLength
|
|
||||||
* length of the AES key in bits (128, 192, or 256)
|
|
||||||
* @param password
|
|
||||||
* the password from which to derive the keys
|
|
||||||
* @param salt
|
|
||||||
* the salt from which to derive the keys
|
|
||||||
* @return a Keys object containing the two generated keys
|
|
||||||
*/
|
|
||||||
private static Keys keygen(int keyLength, char[] password, byte[] salt) {
|
|
||||||
SecretKeyFactory factory;
|
|
||||||
try {
|
|
||||||
factory = SecretKeyFactory.getInstance(KEYGEN_SPEC);
|
|
||||||
} catch (NoSuchAlgorithmException impossible) { return null; }
|
|
||||||
// derive a longer key, then split into AES key and authentication key
|
|
||||||
KeySpec spec = new PBEKeySpec(password, salt, ITERATIONS, keyLength + AUTH_KEY_LENGTH * 8);
|
|
||||||
SecretKey tmp = null;
|
|
||||||
try {
|
|
||||||
tmp = factory.generateSecret(spec);
|
|
||||||
} catch (InvalidKeySpecException impossible) { }
|
|
||||||
byte[] fullKey = tmp.getEncoded();
|
|
||||||
SecretKey authKey = new SecretKeySpec( // key for password authentication
|
|
||||||
Arrays.copyOfRange(fullKey, 0, AUTH_KEY_LENGTH), "AES");
|
|
||||||
SecretKey encKey = new SecretKeySpec( // key for AES encryption
|
|
||||||
Arrays.copyOfRange(fullKey, AUTH_KEY_LENGTH, fullKey.length), "AES");
|
|
||||||
return new Keys(encKey, authKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encrypts a stream of data. The encrypted stream consists of a header
|
|
||||||
* followed by the raw AES data. The header is broken down as follows:<br/>
|
|
||||||
* <ul>
|
|
||||||
* <li><b>keyLength</b>: AES key length in bytes (valid for 16, 24, 32) (1 byte)</li>
|
|
||||||
* <li><b>salt</b>: pseudorandom salt used to derive keys from password (16 bytes)</li>
|
|
||||||
* <li><b>authentication key</b> (derived from password and salt, used to
|
|
||||||
* check validity of password upon decryption) (8 bytes)</li>
|
|
||||||
* <li><b>IV</b>: pseudorandom AES initialization vector (16 bytes)</li>
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* @param keyLength
|
|
||||||
* key length to use for AES encryption (must be 128, 192, or 256)
|
|
||||||
* @param password
|
|
||||||
* password to use for encryption
|
|
||||||
* @param input
|
|
||||||
* an arbitrary byte stream to encrypt
|
|
||||||
* @param output
|
|
||||||
* stream to which encrypted data will be written
|
|
||||||
* @throws AES.InvalidKeyLengthException
|
|
||||||
* if keyLength is not 128, 192, or 256
|
|
||||||
* @throws AES.StrongEncryptionNotAvailableException
|
|
||||||
* if keyLength is 192 or 256, but the Java runtime's jurisdiction
|
|
||||||
* policy files do not allow 192- or 256-bit encryption
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public static void encrypt(int keyLength, String password, InputStream input, OutputStream output)
|
|
||||||
throws InvalidKeyLengthException, StrongEncryptionNotAvailableException, IOException {
|
|
||||||
// Check validity of key length
|
|
||||||
if (keyLength != 128 && keyLength != 192 && keyLength != 256) {
|
|
||||||
throw new InvalidKeyLengthException(keyLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate salt and derive keys for authentication and encryption
|
|
||||||
byte[] salt = generateSalt(SALT_LENGTH);
|
|
||||||
Keys keys = keygen(keyLength, password.toCharArray(), salt);
|
|
||||||
|
|
||||||
// initialize AES encryption
|
|
||||||
Cipher encrypt = null;
|
|
||||||
try {
|
|
||||||
encrypt = Cipher.getInstance(CIPHER_SPEC);
|
|
||||||
encrypt.init(Cipher.ENCRYPT_MODE, keys.encryption);
|
|
||||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException impossible) { }
|
|
||||||
catch (InvalidKeyException e) { // 192 or 256-bit AES not available
|
|
||||||
throw new StrongEncryptionNotAvailableException(keyLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
// get initialization vector
|
|
||||||
byte[] iv = null;
|
|
||||||
try {
|
|
||||||
iv = encrypt.getParameters().getParameterSpec(IvParameterSpec.class).getIV();
|
|
||||||
} catch (InvalidParameterSpecException impossible) { }
|
|
||||||
|
|
||||||
// write authentication and AES initialization data
|
|
||||||
output.write(keyLength / 8);
|
|
||||||
output.write(salt);
|
|
||||||
output.write(keys.authentication.getEncoded());
|
|
||||||
output.write(iv);
|
|
||||||
|
|
||||||
// read data from input into buffer, encrypt and write to output
|
|
||||||
byte[] buffer = new byte[BUFFER_SIZE];
|
|
||||||
int numRead;
|
|
||||||
byte[] encrypted = null;
|
|
||||||
while ((numRead = input.read(buffer)) > 0) {
|
|
||||||
encrypted = encrypt.update(buffer, 0, numRead);
|
|
||||||
if (encrypted != null) {
|
|
||||||
output.write(encrypted);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try { // finish encryption - do final block
|
|
||||||
encrypted = encrypt.doFinal();
|
|
||||||
} catch (IllegalBlockSizeException | BadPaddingException impossible) { }
|
|
||||||
if (encrypted != null) {
|
|
||||||
output.write(encrypted);
|
|
||||||
}
|
|
||||||
output.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method calls to {@link #encrypt(int, String, InputStream, OutputStream)}, simplified for the {@link net.ME1312.SubServers.Bungee.Network.Cipher} interface.
|
|
||||||
*
|
|
||||||
* @param key Key to Encrypt Data with
|
|
||||||
* @param data Data to Encrypt
|
|
||||||
* @return Encrypted Data Array
|
|
||||||
*/
|
|
||||||
public Value encrypt(String key, YAMLSection data) throws Exception {
|
|
||||||
ByteArrayOutputStream unencrypted = new ByteArrayOutputStream();
|
|
||||||
MessagePacker packer = MessagePack.newDefaultPacker(unencrypted);
|
|
||||||
packer.packValue(data.msgPack());
|
|
||||||
packer.close();
|
|
||||||
|
|
||||||
ByteArrayOutputStream encrypted = new ByteArrayOutputStream();
|
|
||||||
encrypt(keyLength, key, new ByteArrayInputStream(unencrypted.toByteArray()), encrypted);
|
|
||||||
return ValueFactory.newBinary(encrypted.toByteArray(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return "AES_" + keyLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decrypts a stream of data that was encrypted by {@link #encrypt}.
|
|
||||||
* @param password
|
|
||||||
* the password used to encrypt/decrypt the stream
|
|
||||||
* @param input
|
|
||||||
* stream of encrypted data to be decrypted
|
|
||||||
* @param output
|
|
||||||
* stream to which decrypted data will be written
|
|
||||||
* @return the key length for the decrypted stream (128, 192, or 256)
|
|
||||||
* @throws AES.InvalidPasswordException
|
|
||||||
* if the given password was not used to encrypt the data
|
|
||||||
* @throws AES.InvalidAESStreamException
|
|
||||||
* if the given input stream is not a valid AES-encrypted stream
|
|
||||||
* @throws AES.StrongEncryptionNotAvailableException
|
|
||||||
* if the stream is 192 or 256-bit encrypted, and the Java runtime's
|
|
||||||
* jurisdiction policy files do not allow for AES-192 or 256
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public static int decrypt(String password, InputStream input, OutputStream output)
|
|
||||||
throws InvalidPasswordException, InvalidAESStreamException, IOException,
|
|
||||||
StrongEncryptionNotAvailableException {
|
|
||||||
int keyLength = input.read() * 8;
|
|
||||||
// Check validity of key length
|
|
||||||
if (keyLength != 128 && keyLength != 192 && keyLength != 256) {
|
|
||||||
throw new InvalidAESStreamException();
|
|
||||||
}
|
|
||||||
|
|
||||||
// read salt, generate keys, and authenticate password
|
|
||||||
byte[] salt = new byte[SALT_LENGTH];
|
|
||||||
input.read(salt);
|
|
||||||
Keys keys = keygen(keyLength, password.toCharArray(), salt);
|
|
||||||
byte[] authRead = new byte[AUTH_KEY_LENGTH];
|
|
||||||
input.read(authRead);
|
|
||||||
if (!Arrays.equals(keys.authentication.getEncoded(), authRead)) {
|
|
||||||
throw new InvalidPasswordException();
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialize AES decryption
|
|
||||||
byte[] iv = new byte[16]; // 16-byte I.V. regardless of key size
|
|
||||||
input.read(iv);
|
|
||||||
Cipher decrypt = null;
|
|
||||||
try {
|
|
||||||
decrypt = Cipher.getInstance(CIPHER_SPEC);
|
|
||||||
decrypt.init(Cipher.DECRYPT_MODE, keys.encryption, new IvParameterSpec(iv));
|
|
||||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException
|
|
||||||
| InvalidAlgorithmParameterException impossible) { }
|
|
||||||
catch (InvalidKeyException e) { // 192 or 256-bit AES not available
|
|
||||||
throw new StrongEncryptionNotAvailableException(keyLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
// read data from input into buffer, decrypt and write to output
|
|
||||||
byte[] buffer = new byte[BUFFER_SIZE];
|
|
||||||
int numRead;
|
|
||||||
byte[] decrypted;
|
|
||||||
while ((numRead = input.read(buffer)) > 0) {
|
|
||||||
decrypted = decrypt.update(buffer, 0, numRead);
|
|
||||||
if (decrypted != null) {
|
|
||||||
output.write(decrypted);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try { // finish decryption - do final block
|
|
||||||
decrypted = decrypt.doFinal();
|
|
||||||
} catch (IllegalBlockSizeException | BadPaddingException e) {
|
|
||||||
throw new InvalidAESStreamException(e);
|
|
||||||
}
|
|
||||||
if (decrypted != null) {
|
|
||||||
output.write(decrypted);
|
|
||||||
}
|
|
||||||
|
|
||||||
output.flush();
|
|
||||||
return keyLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method calls to {@link #decrypt(String, InputStream, OutputStream)}), simplified for the {@link net.ME1312.SubServers.Bungee.Network.Cipher} interface.
|
|
||||||
*
|
|
||||||
* @param key Key to Decrypt Data with
|
|
||||||
* @param data Encrypted Data Array
|
|
||||||
* @return JSON Data
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public YAMLSection decrypt(String key, Value data) throws Exception {
|
|
||||||
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
|
|
||||||
decrypt(key, new ByteArrayInputStream(data.asBinaryValue().asByteArray()), bytes);
|
|
||||||
return new YAMLSection(MessagePack.newDefaultUnpacker(bytes.toByteArray()).unpackValue().asMapValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A tuple of encryption and authentication keys returned by {@link #keygen}
|
|
||||||
*/
|
|
||||||
private static class Keys {
|
|
||||||
public final SecretKey encryption, authentication;
|
|
||||||
public Keys(SecretKey encryption, SecretKey authentication) {
|
|
||||||
this.encryption = encryption;
|
|
||||||
this.authentication = authentication;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Thrown if an attempt is made to decrypt a stream with an incorrect password.
|
|
||||||
*/
|
|
||||||
public static class InvalidPasswordException extends Exception { }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Thrown if an attempt is made to encrypt a stream with an invalid AES key length.
|
|
||||||
*/
|
|
||||||
public static class InvalidKeyLengthException extends Exception {
|
|
||||||
InvalidKeyLengthException(int length) {
|
|
||||||
super("Invalid AES key length: " + length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Thrown if 192- or 256-bit AES encryption or decryption is attempted,
|
|
||||||
* but not available on the particular Java platform.
|
|
||||||
*/
|
|
||||||
public static class StrongEncryptionNotAvailableException extends Exception {
|
|
||||||
public StrongEncryptionNotAvailableException(int keySize) {
|
|
||||||
super(keySize + "-bit AES encryption is not available on this Java platform.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Thrown if an attempt is made to decrypt an invalid AES stream.
|
|
||||||
*/
|
|
||||||
public static class InvalidAESStreamException extends Exception {
|
|
||||||
public InvalidAESStreamException() { super(); };
|
|
||||||
public InvalidAESStreamException(Exception e) { super(e); }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
package net.ME1312.SubServers.Bungee.Network.Packet;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
|
import net.ME1312.SubData.Server.Protocol.PacketObjectIn;
|
||||||
|
import net.ME1312.SubData.Server.Protocol.PacketObjectOut;
|
||||||
|
import net.ME1312.SubData.Server.SubDataClient;
|
||||||
|
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Server Packet
|
||||||
|
*/
|
||||||
|
public class PacketAddServer implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
|
||||||
|
private SubProxy plugin;
|
||||||
|
private int response;
|
||||||
|
private int status;
|
||||||
|
private UUID tracker;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New PacketAddServer (In)
|
||||||
|
*
|
||||||
|
* @param plugin SubPlugin
|
||||||
|
*/
|
||||||
|
public PacketAddServer(SubProxy plugin) {
|
||||||
|
this.plugin = Util.nullpo(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New PacketEditServer (Out)
|
||||||
|
*
|
||||||
|
* @param response Response ID
|
||||||
|
* @param tracker Receiver ID
|
||||||
|
*/
|
||||||
|
public PacketAddServer(int response, UUID tracker) {
|
||||||
|
this.response = response;
|
||||||
|
this.tracker = tracker;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObjectMap<Integer> send(SubDataClient client) {
|
||||||
|
ObjectMap<Integer> json = new ObjectMap<Integer>();
|
||||||
|
if (tracker != null) json.set(0x0000, tracker);
|
||||||
|
json.set(0x0001, response);
|
||||||
|
json.set(0x0002, status);
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public void receive(SubDataClient client, ObjectMap<Integer> data) {
|
||||||
|
UUID tracker = (data.contains(0x0000)?data.getUUID(0x0000):null);
|
||||||
|
try {
|
||||||
|
String name = data.getString(0x0001);
|
||||||
|
boolean subserver = data.getBoolean(0x0002);
|
||||||
|
ObjectMap<String> opt = new ObjectMap<>((Map<String, ?>)data.getObject(0x0003));
|
||||||
|
UUID player = (data.contains(0x0004)?data.getUUID(0x0004):null);
|
||||||
|
|
||||||
|
if (plugin.api.getServers().containsKey(name.toLowerCase())) {
|
||||||
|
client.sendPacket(new PacketAddServer(3, tracker));
|
||||||
|
} else {
|
||||||
|
if (!subserver) {
|
||||||
|
if (plugin.api.addServer(player, name, InetAddress.getByName(opt.getString("address").split(":")[0]), Integer.parseInt(opt.getString("address").split(":")[1]),
|
||||||
|
ChatColor.translateAlternateColorCodes('&', Util.unescapeJavaString(opt.getString("motd"))), opt.getBoolean("hidden"), opt.getBoolean("restricted")) != null) {
|
||||||
|
client.sendPacket(new PacketAddServer(0, tracker));
|
||||||
|
} else {
|
||||||
|
client.sendPacket(new PacketAddServer(1, tracker));
|
||||||
|
}
|
||||||
|
} else if (!plugin.api.getHosts().containsKey(opt.getString("host").toLowerCase())) {
|
||||||
|
client.sendPacket(new PacketAddServer(4, tracker));
|
||||||
|
} else {
|
||||||
|
if (plugin.api.getHost(opt.getString("host")).addSubServer(player, name, opt.getBoolean("enabled"), opt.getInt("port"), ChatColor.translateAlternateColorCodes('&', Util.unescapeJavaString(opt.getString("motd"))),
|
||||||
|
opt.getBoolean("log"), opt.getString("dir"), opt.getString("exec"), opt.getString("stop-cmd"), opt.getBoolean("hidden"), opt.getBoolean("restricted")) != null) {
|
||||||
|
client.sendPacket(new PacketAddServer(0, tracker));
|
||||||
|
} else {
|
||||||
|
client.sendPacket(new PacketAddServer(1, tracker));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
client.sendPacket(new PacketAddServer(2, tracker));
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,68 +0,0 @@
|
||||||
package net.ME1312.SubServers.Bungee.Network.Packet;
|
|
||||||
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.Client;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.PacketIn;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.PacketOut;
|
|
||||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Authorization Packet
|
|
||||||
*/
|
|
||||||
public final class PacketAuthorization implements PacketIn, PacketOut {
|
|
||||||
private SubPlugin plugin;
|
|
||||||
private int response;
|
|
||||||
private String message;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* New PacketAuthorization (In)
|
|
||||||
*
|
|
||||||
* @param plugin SubPlugin
|
|
||||||
*/
|
|
||||||
public PacketAuthorization(SubPlugin plugin) {
|
|
||||||
if (Util.isNull(plugin)) throw new NullPointerException();
|
|
||||||
this.plugin = plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* New PacketAuthorization (Out)
|
|
||||||
*
|
|
||||||
* @param response Response ID
|
|
||||||
* @param message Message
|
|
||||||
*/
|
|
||||||
public PacketAuthorization(int response, String message) {
|
|
||||||
if (Util.isNull(response, message)) throw new NullPointerException();
|
|
||||||
this.response = response;
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public YAMLSection generate() {
|
|
||||||
YAMLSection data = new YAMLSection();
|
|
||||||
data.set("r", response);
|
|
||||||
data.set("m", message);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(Client client, YAMLSection data) {
|
|
||||||
try {
|
|
||||||
if (data.getRawString("password").equals(plugin.config.get().getSection("Settings").getSection("SubData").getRawString("Password"))) {
|
|
||||||
client.authorize();
|
|
||||||
client.sendPacket(new PacketAuthorization(0, "Successfully Logged in"));
|
|
||||||
} else {
|
|
||||||
client.sendPacket(new PacketAuthorization(2, "Invalid Password"));
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
client.sendPacket(new PacketAuthorization(1, e.getClass().getCanonicalName() + ": " + e.getMessage()));
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Version getVersion() {
|
|
||||||
return new Version("2.11.0a");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
package net.ME1312.SubServers.Bungee.Network.Packet;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
|
import net.ME1312.SubData.Server.Protocol.PacketObjectIn;
|
||||||
|
import net.ME1312.SubData.Server.Protocol.PacketObjectOut;
|
||||||
|
import net.ME1312.SubData.Server.SubDataClient;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check Permission Packet
|
||||||
|
*/
|
||||||
|
public class PacketCheckPermission implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
|
||||||
|
static HashMap<UUID, Consumer<Boolean>[]> callbacks = new HashMap<UUID, Consumer<Boolean>[]>();
|
||||||
|
private UUID player;
|
||||||
|
private String permission;
|
||||||
|
private UUID tracker;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New PacketCheckPermission (In)
|
||||||
|
*/
|
||||||
|
public PacketCheckPermission() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New PacketCheckPermission (Out)
|
||||||
|
*
|
||||||
|
* @param player Player to check on
|
||||||
|
* @param permission Permission to check
|
||||||
|
* @param callback Callbacks
|
||||||
|
*/
|
||||||
|
@SafeVarargs
|
||||||
|
public PacketCheckPermission(UUID player, String permission, Consumer<Boolean>... callback) {
|
||||||
|
this.player = player;
|
||||||
|
this.permission = permission;
|
||||||
|
this.tracker = Util.getNew(callbacks.keySet(), UUID::randomUUID);
|
||||||
|
callbacks.put(tracker, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObjectMap<Integer> send(SubDataClient client) throws Throwable {
|
||||||
|
ObjectMap<Integer> data = new ObjectMap<Integer>();
|
||||||
|
data.set(0x0000, tracker);
|
||||||
|
data.set(0x0001, player);
|
||||||
|
data.set(0x0002, permission);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void receive(SubDataClient client, ObjectMap<Integer> data) throws Throwable {
|
||||||
|
client.sendPacket(new PacketCheckPermissionResponse(data.getUUID(0x0001), data.getString(0x0002), (data.contains(0x0000))?data.getUUID(0x0000):null));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package net.ME1312.SubServers.Bungee.Network.Packet;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
|
import net.ME1312.Galaxi.Library.Try;
|
||||||
|
import net.ME1312.SubData.Server.Protocol.PacketObjectIn;
|
||||||
|
import net.ME1312.SubData.Server.Protocol.PacketObjectOut;
|
||||||
|
import net.ME1312.SubData.Server.SubDataClient;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import static net.ME1312.SubServers.Bungee.Network.Packet.PacketCheckPermission.callbacks;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check Permission Response Packet
|
||||||
|
*/
|
||||||
|
public class PacketCheckPermissionResponse implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
|
||||||
|
private boolean result;
|
||||||
|
private UUID tracker;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New PacketCheckPermissionResponse (In)
|
||||||
|
*/
|
||||||
|
public PacketCheckPermissionResponse() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New PacketCheckPermissionResponse (Out)
|
||||||
|
*
|
||||||
|
* @param player Player to check on
|
||||||
|
* @param permission Permission to check
|
||||||
|
* @param tracker Receiver ID
|
||||||
|
*/
|
||||||
|
public PacketCheckPermissionResponse(UUID player, String permission, UUID tracker) {
|
||||||
|
this.result = Try.all.get(() -> ProxyServer.getInstance().getPlayer(player).hasPermission(permission), false);
|
||||||
|
this.tracker = tracker;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObjectMap<Integer> send(SubDataClient client) throws Throwable {
|
||||||
|
ObjectMap<Integer> data = new ObjectMap<Integer>();
|
||||||
|
data.set(0x0000, tracker);
|
||||||
|
data.set(0x0001, result);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void receive(SubDataClient client, ObjectMap<Integer> data) throws Throwable {
|
||||||
|
for (Consumer<Boolean> callback : callbacks.remove(data.getUUID(0x0000))) callback.accept(data.getBoolean(0x0001));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,14 +1,13 @@
|
||||||
package net.ME1312.SubServers.Bungee.Network.Packet;
|
package net.ME1312.SubServers.Bungee.Network.Packet;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
|
import net.ME1312.SubData.Server.Protocol.PacketObjectIn;
|
||||||
|
import net.ME1312.SubData.Server.Protocol.PacketObjectOut;
|
||||||
|
import net.ME1312.SubData.Server.SubDataClient;
|
||||||
import net.ME1312.SubServers.Bungee.Host.Server;
|
import net.ME1312.SubServers.Bungee.Host.Server;
|
||||||
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.Client;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.PacketIn;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.PacketOut;
|
|
||||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
@ -16,86 +15,81 @@ import java.util.UUID;
|
||||||
/**
|
/**
|
||||||
* Server Command Packet
|
* Server Command Packet
|
||||||
*/
|
*/
|
||||||
public class PacketCommandServer implements PacketIn, PacketOut {
|
public class PacketCommandServer implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
|
||||||
private SubPlugin plugin;
|
private SubProxy plugin;
|
||||||
private int response;
|
private int response;
|
||||||
private String message;
|
private UUID tracker;
|
||||||
private String id;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* New PacketCommandServer (In)
|
* New PacketCommandServer (In)
|
||||||
*
|
*
|
||||||
* @param plugin SubPlugin
|
* @param plugin SubPlugin
|
||||||
*/
|
*/
|
||||||
public PacketCommandServer(SubPlugin plugin) {
|
public PacketCommandServer(SubProxy plugin) {
|
||||||
if (Util.isNull(plugin)) throw new NullPointerException();
|
this.plugin = Util.nullpo(plugin);
|
||||||
this.plugin = plugin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* New PacketCommandServer (Out)
|
* New PacketCommandServer (Out)
|
||||||
*
|
*
|
||||||
* @param response Response ID
|
* @param response Response ID
|
||||||
* @param message Message
|
* @param tracker Tracker ID
|
||||||
* @param id Receiver ID
|
|
||||||
*/
|
*/
|
||||||
public PacketCommandServer(int response, String message, String id) {
|
public PacketCommandServer(int response, UUID tracker) {
|
||||||
if (Util.isNull(response, message)) throw new NullPointerException();
|
|
||||||
this.response = response;
|
this.response = response;
|
||||||
this.message = message;
|
this.tracker = tracker;
|
||||||
this.id = id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public YAMLSection generate() {
|
public ObjectMap<Integer> send(SubDataClient client) {
|
||||||
YAMLSection data = new YAMLSection();
|
ObjectMap<Integer> data = new ObjectMap<Integer>();
|
||||||
if (id != null) data.set("id", id);
|
if (tracker != null) data.set(0x0000, tracker);
|
||||||
data.set("r", response);
|
data.set(0x0001, response);
|
||||||
data.set("m", message);
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(Client client, YAMLSection data) {
|
public void receive(SubDataClient client, ObjectMap<Integer> data) {
|
||||||
|
UUID tracker = (data.contains(0x0000)?data.getUUID(0x0000):null);
|
||||||
try {
|
try {
|
||||||
|
String server = data.getString(0x0001);
|
||||||
|
String command = data.getString(0x0002);
|
||||||
|
UUID player = (data.contains(0x0003)?data.getUUID(0x0003):null);
|
||||||
|
UUID target = (data.contains(0x0004)?data.getUUID(0x0004):null);
|
||||||
|
|
||||||
Map<String, Server> servers = plugin.api.getServers();
|
Map<String, Server> servers = plugin.api.getServers();
|
||||||
if (!data.getRawString("server").equals("*") && !servers.keySet().contains(data.getRawString("server").toLowerCase())) {
|
if (!server.equals("*") && !servers.containsKey(server.toLowerCase())) {
|
||||||
client.sendPacket(new PacketCommandServer(3, "There is no server with that name", (data.contains("id")) ? data.getRawString("id") : null));
|
client.sendPacket(new PacketCommandServer(3, tracker));
|
||||||
} else if (!data.getRawString("server").equals("*") && !(servers.get(data.getRawString("server").toLowerCase()) instanceof SubServer)) {
|
} else if (!server.equals("*") && !(target == null && servers.get(server.toLowerCase()) instanceof SubServer) && servers.get(server.toLowerCase()).getSubData()[0] == null) {
|
||||||
client.sendPacket(new PacketCommandServer(4, "That Server is not a SubServer", (data.contains("id")) ? data.getRawString("id") : null));
|
client.sendPacket(new PacketCommandServer(4, tracker));
|
||||||
} else if (!data.getRawString("server").equals("*") && !((SubServer) servers.get(data.getRawString("server").toLowerCase())).isRunning()) {
|
} else if (!server.equals("*") && servers.get(server.toLowerCase()) instanceof SubServer && !((SubServer) servers.get(server.toLowerCase())).isRunning()) {
|
||||||
client.sendPacket(new PacketCommandServer(5, "That SubServer is not running", (data.contains("id")) ? data.getRawString("id") : null));
|
client.sendPacket(new PacketCommandServer(5, tracker));
|
||||||
} else {
|
} else {
|
||||||
if (data.getRawString("server").equals("*")) {
|
if (server.equals("*")) {
|
||||||
boolean sent = false;
|
boolean sent = false;
|
||||||
for (Server server : servers.values()) {
|
for (Server next : servers.values()) {
|
||||||
if (server instanceof SubServer && ((SubServer) server).isRunning()) {
|
if (target == null) {
|
||||||
if (((SubServer) server).command((data.contains("player"))?data.getUUID("player"):null, data.getRawString("command"))) {
|
sent |= next.command(player, command);
|
||||||
sent = true;
|
} else {
|
||||||
}
|
sent |= next.command(player, target, command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sent) {
|
if (sent) {
|
||||||
client.sendPacket(new PacketCommandServer(0, "Sending Command", (data.contains("id")) ? data.getRawString("id") : null));
|
client.sendPacket(new PacketCommandServer(0, tracker));
|
||||||
} else {
|
} else {
|
||||||
client.sendPacket(new PacketCommandServer(1, "Couldn't send command", (data.contains("id")) ? data.getRawString("id") : null));
|
client.sendPacket(new PacketCommandServer(1, tracker));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (((SubServer) servers.get(data.getRawString("server").toLowerCase())).command((data.contains("player"))?data.getUUID("player"):null, data.getRawString("command"))) {
|
if (target == null) {
|
||||||
client.sendPacket(new PacketCommandServer(0, "Sending Command", (data.contains("id")) ? data.getRawString("id") : null));
|
client.sendPacket(new PacketCommandServer((servers.get(server.toLowerCase()).command(player, command))? 0 : 1, tracker));
|
||||||
} else {
|
} else {
|
||||||
client.sendPacket(new PacketCommandServer(1, "Couldn't send command", (data.contains("id")) ? data.getRawString("id") : null));
|
client.sendPacket(new PacketCommandServer((servers.get(server.toLowerCase()).command(player, target, command))? 0 : 1, tracker));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
client.sendPacket(new PacketCommandServer(2, e.getClass().getCanonicalName() + ": " + e.getMessage(), (data.contains("id")) ? data.getRawString("id") : null));
|
client.sendPacket(new PacketCommandServer(2, tracker));
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Version getVersion() {
|
|
||||||
return new Version("2.11.0a");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,31 +1,29 @@
|
||||||
package net.ME1312.SubServers.Bungee.Network.Packet;
|
package net.ME1312.SubServers.Bungee.Network.Packet;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
|
import net.ME1312.Galaxi.Library.Version.Version;
|
||||||
|
import net.ME1312.SubData.Server.Protocol.PacketObjectIn;
|
||||||
|
import net.ME1312.SubData.Server.Protocol.PacketObjectOut;
|
||||||
|
import net.ME1312.SubData.Server.SubDataClient;
|
||||||
import net.ME1312.SubServers.Bungee.Host.SubCreator;
|
import net.ME1312.SubServers.Bungee.Host.SubCreator;
|
||||||
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.Client;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.PacketIn;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.PacketOut;
|
|
||||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create Server Packet
|
* Create Server Packet
|
||||||
*/
|
*/
|
||||||
public class PacketCreateServer implements PacketIn, PacketOut {
|
public class PacketCreateServer implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
|
||||||
private SubPlugin plugin;
|
private SubProxy plugin;
|
||||||
private int response;
|
private int response;
|
||||||
private String message;
|
private UUID tracker;
|
||||||
private String id;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* New PacketCreateServer (In)
|
* New PacketCreateServer (In)
|
||||||
*
|
*
|
||||||
* @param plugin SubPlugin
|
* @param plugin SubPlugin
|
||||||
*/
|
*/
|
||||||
public PacketCreateServer(SubPlugin plugin) {
|
public PacketCreateServer(SubProxy plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,72 +31,64 @@ public class PacketCreateServer implements PacketIn, PacketOut {
|
||||||
* New PacketCreateServer (Out)
|
* New PacketCreateServer (Out)
|
||||||
*
|
*
|
||||||
* @param response Response ID
|
* @param response Response ID
|
||||||
* @param message Message
|
|
||||||
* @param id Receiver ID
|
* @param id Receiver ID
|
||||||
*/
|
*/
|
||||||
public PacketCreateServer(int response, String message, String id) {
|
public PacketCreateServer(int response, UUID id) {
|
||||||
this.response = response;
|
this.response = response;
|
||||||
this.message = message;
|
this.tracker = id;
|
||||||
this.id = id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public YAMLSection generate() {
|
public ObjectMap<Integer> send(SubDataClient client) {
|
||||||
YAMLSection data = new YAMLSection();
|
ObjectMap<Integer> data = new ObjectMap<Integer>();
|
||||||
if (id != null) data.set("id", id);
|
if (tracker != null) data.set(0x0000, tracker);
|
||||||
data.set("r", response);
|
data.set(0x0001, response);
|
||||||
data.set("m", message);
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(Client client, YAMLSection data) {
|
public void receive(SubDataClient client, ObjectMap<Integer> data) {
|
||||||
|
UUID tracker = (data.contains(0x0000)?data.getUUID(0x0000):null);
|
||||||
try {
|
try {
|
||||||
if (data.getSection("creator").getString("name").contains(" ")) {
|
String name = data.getString(0x0001);
|
||||||
client.sendPacket(new PacketCreateServer(3, "Server names cannot have spaces", (data.contains("id")) ? data.getRawString("id") : null));
|
String host = data.getString(0x0002);
|
||||||
} else if (plugin.api.getSubServers().keySet().contains(data.getSection("creator").getString("name").toLowerCase()) || SubCreator.isReserved(data.getSection("creator").getString("name"))) {
|
String template = data.getString(0x0003);
|
||||||
client.sendPacket(new PacketCreateServer(4, "There is already a subserver with that name", (data.contains("id")) ? data.getRawString("id") : null));
|
Version version = (data.contains(0x0004)?data.getVersion(0x0004):null);
|
||||||
} else if (!plugin.hosts.keySet().contains(data.getSection("creator").getString("host").toLowerCase())) {
|
Integer port = (data.contains(0x0005)?data.getInt(0x0005):null);
|
||||||
client.sendPacket(new PacketCreateServer(5, "There is no Host with that name", (data.contains("id")) ? data.getRawString("id") : null));
|
UUID player = (data.contains(0x0006)?data.getUUID(0x0006):null);
|
||||||
} else if (!plugin.hosts.get(data.getSection("creator").getString("host").toLowerCase()).isAvailable()) {
|
boolean waitfor = (data.contains(0x0007)?data.getBoolean(0x0007):false);
|
||||||
client.sendPacket(new PacketStartServer(6, "That SubServer's Host is not available", (data.contains("id"))?data.getRawString("id"):null));
|
|
||||||
} else if (!plugin.hosts.get(data.getSection("creator").getString("host").toLowerCase()).isEnabled()) {
|
if (name.contains(" ")) {
|
||||||
client.sendPacket(new PacketStartServer(7, "That SubServer's Host is not enabled", (data.contains("id"))?data.getRawString("id"):null));
|
client.sendPacket(new PacketCreateServer(3, tracker));
|
||||||
} else if (!plugin.hosts.get(data.getSection("creator").getString("host").toLowerCase()).getCreator().getTemplates().keySet().contains(data.getSection("creator").getString("template").toLowerCase())) {
|
} else if (plugin.api.getSubServers().containsKey(name.toLowerCase()) || SubCreator.isReserved(name)) {
|
||||||
client.sendPacket(new PacketCreateServer(8, "There is no template with that name", (data.contains("id")) ? data.getRawString("id") : null));
|
client.sendPacket(new PacketCreateServer(4, tracker));
|
||||||
} else if (!plugin.hosts.get(data.getSection("creator").getString("host").toLowerCase()).getCreator().getTemplate(data.getSection("creator").getString("template")).isEnabled()) {
|
} else if (!plugin.hosts.containsKey(host.toLowerCase())) {
|
||||||
client.sendPacket(new PacketCreateServer(8, "That Template is not enabled", (data.contains("id")) ? data.getRawString("id") : null));
|
client.sendPacket(new PacketCreateServer(5, tracker));
|
||||||
} else if (new Version("1.8").compareTo(data.getSection("creator").getVersion("version")) > 0) {
|
} else if (!plugin.hosts.get(host.toLowerCase()).isAvailable()) {
|
||||||
client.sendPacket(new PacketCreateServer(10, "SubCreator cannot create servers before Minecraft 1.8", (data.contains("id")) ? data.getRawString("id") : null));
|
client.sendPacket(new PacketCreateServer(6, tracker));
|
||||||
} else if (data.getSection("creator").contains("port") && (data.getSection("creator").getInt("port") <= 0 || data.getSection("creator").getInt("port") > 65535)) {
|
} else if (!plugin.hosts.get(host.toLowerCase()).isEnabled()) {
|
||||||
client.sendPacket(new PacketCreateServer(11, "Invalid Port Number", (data.contains("id")) ? data.getRawString("id") : null));
|
client.sendPacket(new PacketCreateServer(7, tracker));
|
||||||
|
} else if (!plugin.hosts.get(host.toLowerCase()).getCreator().getTemplates().containsKey(template.toLowerCase())) {
|
||||||
|
client.sendPacket(new PacketCreateServer(8, tracker));
|
||||||
|
} else if (!plugin.hosts.get(host.toLowerCase()).getCreator().getTemplate(template).isEnabled()) {
|
||||||
|
client.sendPacket(new PacketCreateServer(9, tracker));
|
||||||
|
} else if (version == null && plugin.hosts.get(host.toLowerCase()).getCreator().getTemplate(template).requiresVersion()) {
|
||||||
|
client.sendPacket(new PacketCreateServer(10, tracker));
|
||||||
|
} else if (port != null && (port <= 0 || port > 65535)) {
|
||||||
|
client.sendPacket(new PacketCreateServer(11, tracker));
|
||||||
} else {
|
} else {
|
||||||
if (plugin.hosts.get(data.getSection("creator").getString("host").toLowerCase()).getCreator().create((data.contains("player"))?data.getUUID("player"):null, data.getSection("creator").getString("name"), plugin.hosts.get(data.getSection("creator").getString("host").toLowerCase()).getCreator().getTemplate(data.getSection("creator").getString("template")), data.getSection("creator").getVersion("version"), (data.getSection("creator").contains("port"))?data.getSection("creator").getInt("port"):null)) {
|
if (plugin.hosts.get(host.toLowerCase()).getCreator().create(player, name, plugin.hosts.get(host.toLowerCase()).getCreator().getTemplate(template), version, port, server -> {
|
||||||
if (data.contains("wait") && data.getBoolean("wait")) {
|
if (waitfor) client.sendPacket(new PacketCreateServer((server == null)?12:0, tracker));
|
||||||
new Thread(() -> {
|
})) {
|
||||||
try {
|
if (!waitfor) client.sendPacket(new PacketCreateServer(0, tracker));
|
||||||
plugin.hosts.get(data.getSection("creator").getString("host").toLowerCase()).getCreator().waitFor();
|
|
||||||
client.sendPacket(new PacketCreateServer(0, "Created SubServer", (data.contains("id")) ? data.getRawString("id") : null));
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}, "SubServers.Bungee::SubData_SubCreator_Handler(" + client.getAddress().toString() + ')').start();
|
|
||||||
} else {
|
|
||||||
client.sendPacket(new PacketCreateServer(0, "Creating SubServer", (data.contains("id")) ? data.getRawString("id") : null));
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
client.sendPacket(new PacketCreateServer(1, "Couldn't create SubServer", (data.contains("id")) ? data.getRawString("id") : null));
|
client.sendPacket(new PacketCreateServer(1, tracker));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
client.sendPacket(new PacketCreateServer(2, e.getClass().getCanonicalName() + ": " + e.getMessage(), (data.contains("id")) ? data.getRawString("id") : null));
|
client.sendPacket(new PacketCreateServer(2, tracker));
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Version getVersion() {
|
|
||||||
return new Version("2.13b");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,101 @@
|
||||||
|
package net.ME1312.SubServers.Bungee.Network.Packet;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
|
import net.ME1312.SubData.Server.Protocol.PacketObjectIn;
|
||||||
|
import net.ME1312.SubData.Server.Protocol.PacketObjectOut;
|
||||||
|
import net.ME1312.SubData.Server.SubDataClient;
|
||||||
|
import net.ME1312.SubServers.Bungee.Host.Server;
|
||||||
|
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
||||||
|
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete Server Packet
|
||||||
|
*/
|
||||||
|
public class PacketDeleteServer implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
|
||||||
|
private SubProxy plugin;
|
||||||
|
private int response;
|
||||||
|
private UUID tracker;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New PacketDeleteServer (In)
|
||||||
|
*
|
||||||
|
* @param plugin SubPlugin
|
||||||
|
*/
|
||||||
|
public PacketDeleteServer(SubProxy plugin) {
|
||||||
|
this.plugin = Util.nullpo(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New PacketDeleteServer (Out)
|
||||||
|
*
|
||||||
|
* @param response Response ID
|
||||||
|
* @param tracker Receiver ID
|
||||||
|
*/
|
||||||
|
public PacketDeleteServer(int response, UUID tracker) {
|
||||||
|
this.response = response;
|
||||||
|
this.tracker = tracker;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObjectMap<Integer> send(SubDataClient client) {
|
||||||
|
ObjectMap<Integer> json = new ObjectMap<Integer>();
|
||||||
|
if (tracker != null) json.set(0x0000, tracker);
|
||||||
|
json.set(0x0001, response);
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void receive(SubDataClient client, ObjectMap<Integer> data) {
|
||||||
|
UUID tracker = (data.contains(0x0000)?data.getUUID(0x0000):null);
|
||||||
|
try {
|
||||||
|
String name = data.getString(0x0001);
|
||||||
|
boolean recycle = data.getBoolean(0x0002);
|
||||||
|
boolean force = data.getBoolean(0x0003);
|
||||||
|
UUID player = (data.contains(0x0004)?data.getUUID(0x0004):null);
|
||||||
|
|
||||||
|
Map<String, Server> servers = plugin.api.getServers();
|
||||||
|
if (!servers.containsKey(name.toLowerCase())) {
|
||||||
|
client.sendPacket(new PacketDeleteServer(3, tracker));
|
||||||
|
} else if (!(servers.get(name.toLowerCase()) instanceof SubServer)) {
|
||||||
|
client.sendPacket(new PacketDeleteServer(4, tracker));
|
||||||
|
} else {
|
||||||
|
if (recycle) {
|
||||||
|
if (force) {
|
||||||
|
if (((SubServer) servers.get(name.toLowerCase())).getHost().forceRecycleSubServer(player, name.toLowerCase())) {
|
||||||
|
client.sendPacket(new PacketDeleteServer(0, tracker));
|
||||||
|
} else {
|
||||||
|
client.sendPacket(new PacketDeleteServer(1, tracker));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (((SubServer) servers.get(name.toLowerCase())).getHost().recycleSubServer(player, name.toLowerCase())) {
|
||||||
|
client.sendPacket(new PacketDeleteServer(0, tracker));
|
||||||
|
} else {
|
||||||
|
client.sendPacket(new PacketDeleteServer(1, tracker));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (force) {
|
||||||
|
if (((SubServer) servers.get(name.toLowerCase())).getHost().forceDeleteSubServer(player, name.toLowerCase())) {
|
||||||
|
client.sendPacket(new PacketDeleteServer(0, tracker));
|
||||||
|
} else {
|
||||||
|
client.sendPacket(new PacketDeleteServer(1, tracker));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (((SubServer) servers.get(name.toLowerCase())).getHost().deleteSubServer(player, name.toLowerCase())) {
|
||||||
|
client.sendPacket(new PacketDeleteServer(0, tracker));
|
||||||
|
} else {
|
||||||
|
client.sendPacket(new PacketDeleteServer(1, tracker));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
client.sendPacket(new PacketDeleteServer(2, tracker));
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
package net.ME1312.SubServers.Bungee.Network.Packet;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Container.Container;
|
||||||
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
|
import net.ME1312.Galaxi.Library.Merger;
|
||||||
|
import net.ME1312.SubData.Server.Protocol.PacketObjectIn;
|
||||||
|
import net.ME1312.SubData.Server.Protocol.PacketObjectOut;
|
||||||
|
import net.ME1312.SubData.Server.SubDataClient;
|
||||||
|
import net.ME1312.SubServers.Bungee.Host.Proxy;
|
||||||
|
import net.ME1312.SubServers.Bungee.Host.RemotePlayer;
|
||||||
|
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.IntConsumer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnect Player Packet
|
||||||
|
*/
|
||||||
|
public class PacketDisconnectPlayer implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
|
||||||
|
private int response;
|
||||||
|
private UUID tracker;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New PacketDisconnectPlayer (In)
|
||||||
|
*/
|
||||||
|
public PacketDisconnectPlayer() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New PacketDisconnectPlayer (Out)
|
||||||
|
*
|
||||||
|
* @param response Response ID
|
||||||
|
* @param tracker Receiver ID
|
||||||
|
*/
|
||||||
|
public PacketDisconnectPlayer(int response, UUID tracker) {
|
||||||
|
this.response = response;
|
||||||
|
this.tracker = tracker;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObjectMap<Integer> send(SubDataClient client) {
|
||||||
|
ObjectMap<Integer> json = new ObjectMap<Integer>();
|
||||||
|
if (tracker != null) json.set(0x0000, tracker);
|
||||||
|
json.set(0x0001, response);
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void receive(SubDataClient client, ObjectMap<Integer> data) {
|
||||||
|
UUID tracker = (data.contains(0x0000)?data.getUUID(0x0000):null);
|
||||||
|
run(data.getUUIDList(0x0001), data.contains(0x0002)?data.getString(0x0002):null, i -> {
|
||||||
|
client.sendPacket(new PacketDisconnectPlayer(i, tracker));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public static void run(List<UUID> ids, String reason, IntConsumer callback) {
|
||||||
|
try {
|
||||||
|
Container<Integer> failures = new Container<>(0);
|
||||||
|
HashMap<Proxy, List<UUID>> requests = new HashMap<Proxy, List<UUID>>();
|
||||||
|
for (UUID id : ids) {
|
||||||
|
ProxiedPlayer local;
|
||||||
|
RemotePlayer remote;
|
||||||
|
if ((local = ProxyServer.getInstance().getPlayer(id)) != null) {
|
||||||
|
if (reason != null) {
|
||||||
|
local.disconnect(reason);
|
||||||
|
} else local.disconnect();
|
||||||
|
} else if ((remote = SubAPI.getInstance().getRemotePlayer(id)) != null && remote.getProxy().getSubData()[0] != null) {
|
||||||
|
Proxy proxy = remote.getProxy();
|
||||||
|
List<UUID> list = requests.getOrDefault(proxy, new ArrayList<>());
|
||||||
|
list.add(id);
|
||||||
|
requests.put(proxy, list);
|
||||||
|
} else {
|
||||||
|
++failures.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requests.size() == 0) {
|
||||||
|
callback.accept(failures.value);
|
||||||
|
} else {
|
||||||
|
Merger merge = new Merger(() -> {
|
||||||
|
callback.accept(failures.value);
|
||||||
|
});
|
||||||
|
for (Map.Entry<Proxy, List<UUID>> entry : requests.entrySet()) {
|
||||||
|
merge.reserve();
|
||||||
|
((SubDataClient) entry.getKey().getSubData()[0]).sendPacket(new PacketExDisconnectPlayer(entry.getValue(), reason, r -> {
|
||||||
|
failures.value += r.getInt(0x0001);
|
||||||
|
merge.release();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
callback.accept(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,80 +1,81 @@
|
||||||
package net.ME1312.SubServers.Bungee.Network.Packet;
|
package net.ME1312.SubServers.Bungee.Network.Packet;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
import net.ME1312.SubServers.Bungee.Host.Host;
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
import net.ME1312.SubServers.Bungee.Host.Proxy;
|
import net.ME1312.SubData.Server.Protocol.PacketObjectIn;
|
||||||
|
import net.ME1312.SubData.Server.Protocol.PacketObjectOut;
|
||||||
|
import net.ME1312.SubData.Server.SubDataClient;
|
||||||
import net.ME1312.SubServers.Bungee.Host.Server;
|
import net.ME1312.SubServers.Bungee.Host.Server;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.Client;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.PacketIn;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.PacketOut;
|
|
||||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Download Group Info Packet
|
* Download Group Info Packet
|
||||||
*/
|
*/
|
||||||
public class PacketDownloadGroupInfo implements PacketIn, PacketOut {
|
public class PacketDownloadGroupInfo implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
|
||||||
private SubPlugin plugin;
|
private SubProxy plugin;
|
||||||
private String host;
|
private String[] groups;
|
||||||
private String group;
|
private UUID tracker;
|
||||||
private String id;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* New PacketDownloadGroupInfo (In)
|
* New PacketDownloadGroupInfo (In)
|
||||||
*
|
*
|
||||||
* @param plugin SubPlugin
|
* @param plugin SubPlugin
|
||||||
*/
|
*/
|
||||||
public PacketDownloadGroupInfo(SubPlugin plugin) {
|
public PacketDownloadGroupInfo(SubProxy plugin) {
|
||||||
if (Util.isNull(plugin)) throw new NullPointerException();
|
this.plugin = Util.nullpo(plugin);
|
||||||
this.plugin = plugin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* New PacketDownloadGroupInfo (Out)
|
* New PacketDownloadGroupInfo (Out)
|
||||||
*
|
*
|
||||||
* @param plugin SubPlugin
|
* @param plugin SubPlugin
|
||||||
* @param group Group (or null for all)
|
* @param groups Groups (or null for all)
|
||||||
* @param id Receiver ID
|
* @param tracker Receiver ID
|
||||||
*/
|
*/
|
||||||
public PacketDownloadGroupInfo(SubPlugin plugin, String group, String id) {
|
public PacketDownloadGroupInfo(SubProxy plugin, List<String> groups, UUID tracker) {
|
||||||
if (Util.isNull(plugin)) throw new NullPointerException();
|
this.plugin = Util.nullpo(plugin);
|
||||||
this.plugin = plugin;
|
this.tracker = tracker;
|
||||||
this.host = host;
|
|
||||||
this.group = group;
|
if (groups != null) {
|
||||||
this.id = id;
|
this.groups = new String[groups.size()];
|
||||||
|
for (int i = 0; i < this.groups.length; ++i) this.groups[i] = groups.get(i).toLowerCase();
|
||||||
|
Arrays.sort(this.groups);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
@Override
|
||||||
public YAMLSection generate() {
|
public ObjectMap<Integer> send(SubDataClient client) {
|
||||||
YAMLSection data = new YAMLSection();
|
ObjectMap<Integer> data = new ObjectMap<Integer>();
|
||||||
if (id != null) data.set("id", id);
|
if (tracker != null) data.set(0x0000, tracker);
|
||||||
|
|
||||||
YAMLSection groups = new YAMLSection();
|
if (this.groups == null || this.groups.length > 0) {
|
||||||
for (String group : plugin.api.getGroups().keySet()) {
|
ObjectMap<String> groups = new ObjectMap<String>();
|
||||||
if (this.group == null || this.group.length() <= 0 || this.group.equalsIgnoreCase(group)) {
|
for (Map.Entry<String, List<Server>> group : plugin.api.getGroups().entrySet()) {
|
||||||
YAMLSection servers = new YAMLSection();
|
if (this.groups == null || Arrays.binarySearch(this.groups, group.getKey().toLowerCase()) >= 0) {
|
||||||
for (Server server : plugin.api.getGroup(group)) {
|
ObjectMap<String> servers = new ObjectMap<String>();
|
||||||
servers.set(server.getName(), new YAMLSection(new Gson().fromJson(server.toString(), Map.class)));
|
for (Server server : group.getValue()) {
|
||||||
|
servers.set(server.getName(), server.forSubData());
|
||||||
|
}
|
||||||
|
groups.set(group.getKey(), servers);
|
||||||
}
|
}
|
||||||
groups.set(group, servers);
|
|
||||||
}
|
}
|
||||||
|
data.set(0x0001, groups);
|
||||||
|
} else {
|
||||||
|
ObjectMap<String> ungrouped = new ObjectMap<String>();
|
||||||
|
for (Server server : plugin.api.getServers().values()) {
|
||||||
|
if (server.getGroups().size() <= 0) ungrouped.set(server.getName(), server.forSubData());
|
||||||
|
}
|
||||||
|
|
||||||
|
data.set(0x0001, Collections.emptyMap());
|
||||||
|
data.set(0x0002, ungrouped);
|
||||||
}
|
}
|
||||||
data.set("groups", groups);
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(Client client, YAMLSection data) {
|
public void receive(SubDataClient client, ObjectMap<Integer> data) {
|
||||||
client.sendPacket(new PacketDownloadGroupInfo(plugin, (data.contains("group"))?data.getRawString("group"):null, (data.contains("id"))?data.getRawString("id"):null));
|
client.sendPacket(new PacketDownloadGroupInfo(plugin, (data.contains(0x0001))?data.getStringList(0x0001):null, (data.contains(0x0000))?data.getUUID(0x0000):null));
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Version getVersion() {
|
|
||||||
return new Version("2.13b");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,72 +1,69 @@
|
||||||
package net.ME1312.SubServers.Bungee.Network.Packet;
|
package net.ME1312.SubServers.Bungee.Network.Packet;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
|
import net.ME1312.SubData.Server.Protocol.PacketObjectIn;
|
||||||
|
import net.ME1312.SubData.Server.Protocol.PacketObjectOut;
|
||||||
|
import net.ME1312.SubData.Server.SubDataClient;
|
||||||
import net.ME1312.SubServers.Bungee.Host.Host;
|
import net.ME1312.SubServers.Bungee.Host.Host;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.Client;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.PacketIn;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.PacketOut;
|
|
||||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Download Host Info Packet
|
* Download Host Info Packet
|
||||||
*/
|
*/
|
||||||
public class PacketDownloadHostInfo implements PacketIn, PacketOut {
|
public class PacketDownloadHostInfo implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
|
||||||
private SubPlugin plugin;
|
private SubProxy plugin;
|
||||||
private String host;
|
private String[] hosts;
|
||||||
private String id;
|
private UUID tracker;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* New PacketDownloadHostInfo (In)
|
* New PacketDownloadHostInfo (In)
|
||||||
*
|
*
|
||||||
* @param plugin SubPlugin
|
* @param plugin SubPlugin
|
||||||
*/
|
*/
|
||||||
public PacketDownloadHostInfo(SubPlugin plugin) {
|
public PacketDownloadHostInfo(SubProxy plugin) {
|
||||||
if (Util.isNull(plugin)) throw new NullPointerException();
|
this.plugin = Util.nullpo(plugin);
|
||||||
this.plugin = plugin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* New PacketDownloadHostInfo (Out)
|
* New PacketDownloadHostInfo (Out)
|
||||||
*
|
*
|
||||||
* @param plugin SubPlugin
|
* @param plugin SubPlugin
|
||||||
* @param host Host (or null for all)
|
* @param hosts Hosts (or null for all)
|
||||||
* @param id Receiver ID
|
* @param tracker Receiver ID
|
||||||
*/
|
*/
|
||||||
public PacketDownloadHostInfo(SubPlugin plugin, String host, String id) {
|
public PacketDownloadHostInfo(SubProxy plugin, List<String> hosts, UUID tracker) {
|
||||||
if (Util.isNull(plugin)) throw new NullPointerException();
|
this.plugin = Util.nullpo(plugin);
|
||||||
this.plugin = plugin;
|
this.tracker = tracker;
|
||||||
this.host = host;
|
|
||||||
this.id = id;
|
if (hosts != null) {
|
||||||
|
this.hosts = new String[hosts.size()];
|
||||||
|
for (int i = 0; i < this.hosts.length; ++i) this.hosts[i] = hosts.get(i).toLowerCase();
|
||||||
|
Arrays.sort(this.hosts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
@Override
|
||||||
public YAMLSection generate() {
|
public ObjectMap<Integer> send(SubDataClient client) {
|
||||||
YAMLSection data = new YAMLSection();
|
ObjectMap<Integer> data = new ObjectMap<Integer>();
|
||||||
if (id != null) data.set("id", id);
|
if (tracker != null) data.set(0x0000, tracker);
|
||||||
|
|
||||||
YAMLSection hosts = new YAMLSection();
|
ObjectMap<String> hosts = new ObjectMap<String>();
|
||||||
for (Host host : plugin.api.getHosts().values()) {
|
for (Host host : plugin.api.getHosts().values()) {
|
||||||
if (this.host == null || this.host.length() <= 0 || this.host.equalsIgnoreCase(host.getName())) {
|
if (this.hosts == null || this.hosts.length <= 0 || Arrays.binarySearch(this.hosts, host.getName().toLowerCase()) >= 0) {
|
||||||
hosts.set(host.getName(), new YAMLSection(new Gson().fromJson(host.toString(), Map.class)));
|
hosts.set(host.getName(), host.forSubData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data.set("hosts", hosts);
|
data.set(0x0001, hosts);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(Client client, YAMLSection data) {
|
public void receive(SubDataClient client, ObjectMap<Integer> data) {
|
||||||
client.sendPacket(new PacketDownloadHostInfo(plugin, (data.contains("host"))?data.getRawString("host"):null, (data.contains("id"))?data.getRawString("id"):null));
|
client.sendPacket(new PacketDownloadHostInfo(plugin, (data.contains(0x0001))?data.getStringList(0x0001):null, (data.contains(0x0000))?data.getUUID(0x0000):null));
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Version getVersion() {
|
|
||||||
return new Version("2.13b");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +1,28 @@
|
||||||
package net.ME1312.SubServers.Bungee.Network.Packet;
|
package net.ME1312.SubServers.Bungee.Network.Packet;
|
||||||
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
import net.ME1312.SubData.Server.Protocol.PacketObjectIn;
|
||||||
import net.ME1312.SubServers.Bungee.Network.Client;
|
import net.ME1312.SubData.Server.Protocol.PacketObjectOut;
|
||||||
import net.ME1312.SubServers.Bungee.Network.PacketIn;
|
import net.ME1312.SubData.Server.SubDataClient;
|
||||||
import net.ME1312.SubServers.Bungee.Network.PacketOut;
|
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Download Lang Packet
|
* Download Lang Packet
|
||||||
*/
|
*/
|
||||||
public class PacketDownloadLang implements PacketIn, PacketOut {
|
public class PacketDownloadLang implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
|
||||||
private SubPlugin plugin;
|
private SubProxy plugin;
|
||||||
private String id;
|
private UUID tracker;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* New PacketDownloadLang (In)
|
* New PacketDownloadLang (In)
|
||||||
*
|
*
|
||||||
* @param plugin SubPlugin
|
* @param plugin SubPlugin
|
||||||
*/
|
*/
|
||||||
public PacketDownloadLang(SubPlugin plugin) {
|
public PacketDownloadLang(SubProxy plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,31 +30,26 @@ public class PacketDownloadLang implements PacketIn, PacketOut {
|
||||||
* New PacketDownloadLang (Out)
|
* New PacketDownloadLang (Out)
|
||||||
*
|
*
|
||||||
* @param plugin SubPlugin
|
* @param plugin SubPlugin
|
||||||
* @param id Receiver ID
|
* @param tracker Receiver ID
|
||||||
*/
|
*/
|
||||||
public PacketDownloadLang(SubPlugin plugin, String id) {
|
public PacketDownloadLang(SubProxy plugin, UUID tracker) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.id = id;
|
this.tracker = tracker;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public YAMLSection generate() {
|
public ObjectMap<Integer> send(SubDataClient client) {
|
||||||
YAMLSection data = new YAMLSection();
|
ObjectMap<Integer> data = new ObjectMap<Integer>();
|
||||||
if (id != null) data.set("id", id);
|
if (tracker != null) data.set(0x0000, tracker);
|
||||||
LinkedHashMap<String, Map<String, String>> full = new LinkedHashMap<>();
|
LinkedHashMap<String, Map<String, String>> full = new LinkedHashMap<>();
|
||||||
for (String channel : plugin.api.getLangChannels())
|
for (String channel : plugin.api.getLangChannels())
|
||||||
full.put(channel, plugin.api.getLang(channel));
|
full.put(channel, plugin.api.getLang(channel));
|
||||||
data.set("Lang", full);
|
data.set(0x0001, full);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(Client client, YAMLSection data) {
|
public void receive(SubDataClient client, ObjectMap<Integer> data) {
|
||||||
client.sendPacket(new PacketDownloadLang(plugin, (data != null && data.contains("id"))?data.getRawString("id"):null));
|
client.sendPacket(new PacketDownloadLang(plugin, (data != null && data.contains(0x0000))?data.getUUID(0x0000):null));
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Version getVersion() {
|
|
||||||
return new Version("2.11.0a");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
package net.ME1312.SubServers.Bungee.Network.Packet;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.JsonParseException;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.Client;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.PacketIn;
|
|
||||||
import net.ME1312.SubServers.Bungee.Network.PacketOut;
|
|
||||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Download Network List Packet
|
|
||||||
*/
|
|
||||||
public class PacketDownloadNetworkList implements PacketIn, PacketOut {
|
|
||||||
private SubPlugin plugin;
|
|
||||||
private String id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* New PacketDownloadNetworkList (In)
|
|
||||||
*
|
|
||||||
* @param plugin SubPlugin
|
|
||||||
*/
|
|
||||||
public PacketDownloadNetworkList(SubPlugin plugin) {
|
|
||||||
if (Util.isNull(plugin)) throw new NullPointerException();
|
|
||||||
this.plugin = plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* New PacketDownloadNetworkList (Out)
|
|
||||||
*
|
|
||||||
* @param plugin SubPlugin
|
|
||||||
* @param id Receiver ID
|
|
||||||
*/
|
|
||||||
public PacketDownloadNetworkList(SubPlugin plugin, String id) {
|
|
||||||
if (Util.isNull(plugin)) throw new NullPointerException();
|
|
||||||
this.plugin = plugin;
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
|
||||||
public YAMLSection generate() {
|
|
||||||
YAMLSection json = new YAMLSection();
|
|
||||||
if (id != null) json.set("id", id);
|
|
||||||
YAMLSection clients = new YAMLSection();
|
|
||||||
for (Client client : plugin.subdata.getClients()) {
|
|
||||||
try {
|
|
||||||
clients.set(client.getAddress().toString(), new YAMLSection(new Gson().fromJson(client.getHandler().toString(), Map.class)));
|
|
||||||
} catch (JsonParseException | NullPointerException e) {
|
|
||||||
clients.set(client.getAddress().toString(), new YAMLSection());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
json.set("clients", clients);
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(Client client, YAMLSection data) {
|
|
||||||
client.sendPacket(new PacketDownloadNetworkList(plugin, (data.contains("id"))?data.getRawString("id"):null));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Version getVersion() {
|
|
||||||
return new Version("2.11.0a");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +1,30 @@
|
||||||
package net.ME1312.SubServers.Bungee.Network.Packet;
|
package net.ME1312.SubServers.Bungee.Network.Packet;
|
||||||
|
|
||||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
import net.ME1312.Galaxi.Library.Version.Version;
|
||||||
import net.ME1312.SubServers.Bungee.Network.Client;
|
import net.ME1312.SubData.Server.Protocol.PacketObjectIn;
|
||||||
import net.ME1312.SubServers.Bungee.Network.PacketIn;
|
import net.ME1312.SubData.Server.Protocol.PacketObjectOut;
|
||||||
import net.ME1312.SubServers.Bungee.Network.PacketOut;
|
import net.ME1312.SubData.Server.SubDataClient;
|
||||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||||
|
|
||||||
import net.md_5.bungee.api.config.ListenerInfo;
|
import net.md_5.bungee.api.config.ListenerInfo;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Download Proxy Info Packet
|
* Download Proxy Info Packet
|
||||||
*/
|
*/
|
||||||
public class PacketDownloadPlatformInfo implements PacketIn, PacketOut {
|
public class PacketDownloadPlatformInfo implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
|
||||||
private SubPlugin plugin;
|
private SubProxy plugin;
|
||||||
private String id;
|
private UUID tracker;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* New PacketDownloadPlatformInfo (In)
|
* New PacketDownloadPlatformInfo (In)
|
||||||
*
|
*
|
||||||
* @param plugin SubPlugin
|
* @param plugin SubPlugin
|
||||||
*/
|
*/
|
||||||
public PacketDownloadPlatformInfo(SubPlugin plugin) {
|
public PacketDownloadPlatformInfo(SubProxy plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,65 +32,73 @@ public class PacketDownloadPlatformInfo implements PacketIn, PacketOut {
|
||||||
* New PacketDownloadPlatformInfo (Out)
|
* New PacketDownloadPlatformInfo (Out)
|
||||||
*
|
*
|
||||||
* @param plugin SubPlugin
|
* @param plugin SubPlugin
|
||||||
* @param id Receiver ID
|
* @param tracker Receiver ID
|
||||||
*/
|
*/
|
||||||
public PacketDownloadPlatformInfo(SubPlugin plugin, String id) {
|
public PacketDownloadPlatformInfo(SubProxy plugin, UUID tracker) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.id = id;
|
this.tracker = tracker;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public YAMLSection generate() {
|
public ObjectMap<Integer> send(SubDataClient client) {
|
||||||
YAMLSection data = new YAMLSection();
|
ObjectMap<Integer> data = new ObjectMap<Integer>();
|
||||||
if (id != null) data.set("id", id);
|
if (tracker != null) data.set(0x0000, tracker);
|
||||||
YAMLSection subservers = new YAMLSection();
|
ObjectMap<String> info = new ObjectMap<String>();
|
||||||
|
|
||||||
|
|
||||||
|
ObjectMap<String> subservers = new ObjectMap<String>();
|
||||||
subservers.set("version", plugin.api.getWrapperVersion().toString());
|
subservers.set("version", plugin.api.getWrapperVersion().toString());
|
||||||
if (plugin.api.getWrapperBuild() != null) subservers.set("build", plugin.api.getWrapperBuild().toString());
|
if (plugin.api.getWrapperBuild() != null) subservers.set("build", plugin.api.getWrapperBuild().toString());
|
||||||
subservers.set("last-reload", plugin.resetDate);
|
subservers.set("last-reload", plugin.resetDate);
|
||||||
|
subservers.set("proxies", plugin.api.getProxies().size());
|
||||||
subservers.set("hosts", plugin.api.getHosts().size());
|
subservers.set("hosts", plugin.api.getHosts().size());
|
||||||
subservers.set("subservers", plugin.api.getSubServers().size());
|
subservers.set("subservers", plugin.api.getSubServers().size());
|
||||||
data.set("subservers", subservers);
|
info.set("subservers", subservers);
|
||||||
YAMLSection bungee = new YAMLSection();
|
|
||||||
|
|
||||||
|
ObjectMap<String> bungee = new ObjectMap<String>();
|
||||||
bungee.set("version", plugin.api.getProxyVersion().toString());
|
bungee.set("version", plugin.api.getProxyVersion().toString());
|
||||||
bungee.set("disabled-cmds", plugin.getConfig().getDisabledCommands());
|
bungee.set("disabled-cmds", plugin.getConfig().getDisabledCommands());
|
||||||
bungee.set("player-limit", plugin.getConfig().getPlayerLimit());
|
bungee.set("player-limit", plugin.getConfig().getPlayerLimit());
|
||||||
bungee.set("servers", plugin.api.getServers().size());
|
bungee.set("servers", plugin.api.getServers().size());
|
||||||
LinkedList<YAMLSection> listeners = new LinkedList<YAMLSection>();
|
LinkedList<ObjectMap<String>> listeners = new LinkedList<ObjectMap<String>>();
|
||||||
for (ListenerInfo info : plugin.getConfig().getListeners()) {
|
for (ListenerInfo next : plugin.getConfig().getListeners()) {
|
||||||
YAMLSection listener = new YAMLSection();
|
ObjectMap<String> listener = new ObjectMap<String>();
|
||||||
listener.set("forced-hosts", info.getForcedHosts());
|
listener.set("forced-hosts", next.getForcedHosts());
|
||||||
listener.set("motd", info.getMotd());
|
listener.set("motd", next.getMotd());
|
||||||
listener.set("priorities", info.getServerPriority());
|
listener.set("priorities", next.getServerPriority());
|
||||||
listener.set("player-limit", info.getMaxPlayers());
|
listener.set("player-limit", next.getMaxPlayers());
|
||||||
listeners.add(listener);
|
listeners.add(listener);
|
||||||
}
|
}
|
||||||
bungee.set("listeners", listeners);
|
bungee.set("listeners", listeners);
|
||||||
data.set("bungee", bungee);
|
info.set("bungee", bungee);
|
||||||
YAMLSection minecraft = new YAMLSection();
|
|
||||||
|
|
||||||
|
ObjectMap<String> minecraft = new ObjectMap<String>();
|
||||||
LinkedList<String> mcversions = new LinkedList<String>();
|
LinkedList<String> mcversions = new LinkedList<String>();
|
||||||
for (Version version : plugin.api.getGameVersion()) mcversions.add(version.toString());
|
for (Version version : plugin.api.getGameVersion()) mcversions.add(version.toString());
|
||||||
minecraft.set("version", mcversions);
|
minecraft.set("version", mcversions);
|
||||||
minecraft.set("players", plugin.api.getGlobalPlayers().size());
|
minecraft.set("players", plugin.api.getRemotePlayers().size());
|
||||||
data.set("minecraft", minecraft);
|
info.set("minecraft", minecraft);
|
||||||
YAMLSection system = new YAMLSection();
|
|
||||||
YAMLSection os = new YAMLSection();
|
|
||||||
|
ObjectMap<String> system = new ObjectMap<String>();
|
||||||
|
ObjectMap<String> os = new ObjectMap<String>();
|
||||||
os.set("name", System.getProperty("os.name"));
|
os.set("name", System.getProperty("os.name"));
|
||||||
os.set("version", System.getProperty("os.version"));
|
os.set("version", System.getProperty("os.version"));
|
||||||
system.set("os", os);
|
system.set("os", os);
|
||||||
YAMLSection java = new YAMLSection();
|
ObjectMap<String> java = new ObjectMap<String>();
|
||||||
java.set("version", System.getProperty("java.version"));
|
java.set("version", System.getProperty("java.version"));
|
||||||
system.set("java", java);
|
system.set("java", java);
|
||||||
data.set("system", system);
|
info.set("system", system);
|
||||||
|
|
||||||
|
|
||||||
|
data.set(0x0001, info);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(Client client, YAMLSection data) {
|
public void receive(SubDataClient client, ObjectMap<Integer> data) {
|
||||||
client.sendPacket(new PacketDownloadPlatformInfo(plugin, (data != null && data.contains("id"))?data.getRawString("id"):null));
|
client.sendPacket(new PacketDownloadPlatformInfo(plugin, (data != null && data.contains(0x0000))?data.getUUID(0x0000):null));
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Version getVersion() {
|
|
||||||
return new Version("2.11.0a");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
package net.ME1312.SubServers.Bungee.Network.Packet;
|
||||||
|
|
||||||
|
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||||
|
import net.ME1312.Galaxi.Library.Util;
|
||||||
|
import net.ME1312.SubData.Server.Protocol.PacketObjectIn;
|
||||||
|
import net.ME1312.SubData.Server.Protocol.PacketObjectOut;
|
||||||
|
import net.ME1312.SubData.Server.SubDataClient;
|
||||||
|
import net.ME1312.SubServers.Bungee.Host.RemotePlayer;
|
||||||
|
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Download Player Info Packet
|
||||||
|
*/
|
||||||
|
public class PacketDownloadPlayerInfo implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
|
||||||
|
private SubProxy plugin;
|
||||||
|
private String[] names;
|
||||||
|
private UUID[] ids;
|
||||||
|
private UUID tracker;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New PacketDownloadPlayerInfo (In)
|
||||||
|
*
|
||||||
|
* @param plugin SubPlugin
|
||||||
|
*/
|
||||||
|
public PacketDownloadPlayerInfo(SubProxy plugin) {
|
||||||
|
this.plugin = Util.nullpo(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New PacketDownloadPlayerInfo (Out)
|
||||||
|
*
|
||||||
|
* @param plugin SubPlugin
|
||||||
|
* @param names Player names (or null for all)
|
||||||
|
* @param ids Player IDs (or null for all)
|
||||||
|
* @param tracker Receiver ID
|
||||||
|
*/
|
||||||
|
public PacketDownloadPlayerInfo(SubProxy plugin, List<String> names, List<UUID> ids, UUID tracker) {
|
||||||
|
this.plugin = Util.nullpo(plugin);
|
||||||
|
this.tracker = tracker;
|
||||||
|
|
||||||
|
if (ids != null) {
|
||||||
|
this.ids = new UUID[ids.size()];
|
||||||
|
for (int i = 0; i < this.ids.length; ++i) this.ids[i] = ids.get(i);
|
||||||
|
}
|
||||||
|
if (names != null) {
|
||||||
|
this.names = new String[names.size()];
|
||||||
|
for (int i = 0; i < this.names.length; ++i) this.names[i] = names.get(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObjectMap<Integer> send(SubDataClient client) {
|
||||||
|
ObjectMap<Integer> data = new ObjectMap<Integer>();
|
||||||
|
if (tracker != null) data.set(0x0000, tracker);
|
||||||
|
|
||||||
|
ObjectMap<String> players = new ObjectMap<String>();
|
||||||
|
if (ids == null && names == null) {
|
||||||
|
for (RemotePlayer player : plugin.api.getRemotePlayers().values()) {
|
||||||
|
players.set(player.getUniqueId().toString(), player.forSubData());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (ids != null) for (UUID id : ids) {
|
||||||
|
RemotePlayer player = plugin.api.getRemotePlayer(id);
|
||||||
|
if (player != null) players.set(player.getUniqueId().toString(), player.forSubData());
|
||||||
|
}
|
||||||
|
if (names != null) for (String name : names) {
|
||||||
|
RemotePlayer player = plugin.api.getRemotePlayer(name);
|
||||||
|
if (player != null) players.set(player.getUniqueId().toString(), player.forSubData());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.set(0x0001, players);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void receive(SubDataClient client, ObjectMap<Integer> data) {
|
||||||
|
client.sendPacket(new PacketDownloadPlayerInfo(plugin, (data.contains(0x0001))?data.getStringList(0x0001):null, (data.contains(0x0002))?data.getUUIDList(0x0002):null, (data.contains(0x0000))?data.getUUID(0x0000):null));
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue