diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/artifacts/PotSG_jar.xml b/.idea/artifacts/PotSG_jar.xml
new file mode 100644
index 0000000..7c09216
--- /dev/null
+++ b/.idea/artifacts/PotSG_jar.xml
@@ -0,0 +1,13 @@
+
+
+ $PROJECT_DIR$/out/artifacts/PotSG_jar
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..373ec26
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/discord.xml b/.idea/discord.xml
new file mode 100644
index 0000000..cd711a0
--- /dev/null
+++ b/.idea/discord.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
new file mode 100644
index 0000000..2534176
--- /dev/null
+++ b/.idea/jarRepositories.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Ziggurat_1_0_SNAPSHOT.xml b/.idea/libraries/Ziggurat_1_0_SNAPSHOT.xml
new file mode 100644
index 0000000..7dff495
--- /dev/null
+++ b/.idea/libraries/Ziggurat_1_0_SNAPSHOT.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/craftbukkit_1_7_10.xml b/.idea/libraries/craftbukkit_1_7_10.xml
new file mode 100644
index 0000000..6eb1977
--- /dev/null
+++ b/.idea/libraries/craftbukkit_1_7_10.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..bf9e798
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..d3ffa0a
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..e96534f
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/PotSG-Scenarios.iml b/PotSG-Scenarios.iml
new file mode 100644
index 0000000..4ec1b0e
--- /dev/null
+++ b/PotSG-Scenarios.iml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+ BUKKIT
+
+
+
+
+
\ No newline at end of file
diff --git a/PotSG.iml b/PotSG.iml
new file mode 100644
index 0000000..78b2cc5
--- /dev/null
+++ b/PotSG.iml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/libs/ProtocolLib-3.4.0.jar b/libs/ProtocolLib-3.4.0.jar
new file mode 100644
index 0000000..dd97508
Binary files /dev/null and b/libs/ProtocolLib-3.4.0.jar differ
diff --git a/libs/Ziggurat-1.0-SNAPSHOT.jar b/libs/Ziggurat-1.0-SNAPSHOT.jar
new file mode 100644
index 0000000..1ee42c8
Binary files /dev/null and b/libs/Ziggurat-1.0-SNAPSHOT.jar differ
diff --git a/libs/craftbukkit-1.7.10.jar b/libs/craftbukkit-1.7.10.jar
new file mode 100644
index 0000000..9756885
Binary files /dev/null and b/libs/craftbukkit-1.7.10.jar differ
diff --git a/libs/lombok.jar b/libs/lombok.jar
new file mode 100644
index 0000000..ee34cde
Binary files /dev/null and b/libs/lombok.jar differ
diff --git a/libs/mvn/com/qrakn/honcho/1.0-SNAPSHOT/_remote.repositories b/libs/mvn/com/qrakn/honcho/1.0-SNAPSHOT/_remote.repositories
new file mode 100644
index 0000000..650b242
--- /dev/null
+++ b/libs/mvn/com/qrakn/honcho/1.0-SNAPSHOT/_remote.repositories
@@ -0,0 +1,4 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Wed Dec 05 15:42:22 EST 2018
+honcho-1.0-SNAPSHOT.pom>=
+honcho-1.0-SNAPSHOT.jar>=
diff --git a/libs/mvn/com/qrakn/honcho/1.0-SNAPSHOT/honcho-1.0-SNAPSHOT.jar b/libs/mvn/com/qrakn/honcho/1.0-SNAPSHOT/honcho-1.0-SNAPSHOT.jar
new file mode 100644
index 0000000..8f34a11
Binary files /dev/null and b/libs/mvn/com/qrakn/honcho/1.0-SNAPSHOT/honcho-1.0-SNAPSHOT.jar differ
diff --git a/libs/mvn/com/qrakn/honcho/1.0-SNAPSHOT/honcho-1.0-SNAPSHOT.jar.lastUpdated b/libs/mvn/com/qrakn/honcho/1.0-SNAPSHOT/honcho-1.0-SNAPSHOT.jar.lastUpdated
new file mode 100644
index 0000000..5ab48d9
--- /dev/null
+++ b/libs/mvn/com/qrakn/honcho/1.0-SNAPSHOT/honcho-1.0-SNAPSHOT.jar.lastUpdated
@@ -0,0 +1,4 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Thu Dec 06 19:17:54 CET 2018
+https\://hub.spigotmc.org/nexus/content/repositories/snapshots/.error=
+https\://hub.spigotmc.org/nexus/content/repositories/snapshots/.lastUpdated=1544120274155
diff --git a/libs/mvn/com/qrakn/honcho/1.0-SNAPSHOT/honcho-1.0-SNAPSHOT.pom b/libs/mvn/com/qrakn/honcho/1.0-SNAPSHOT/honcho-1.0-SNAPSHOT.pom
new file mode 100644
index 0000000..cdc5b6f
--- /dev/null
+++ b/libs/mvn/com/qrakn/honcho/1.0-SNAPSHOT/honcho-1.0-SNAPSHOT.pom
@@ -0,0 +1,55 @@
+
+
+ 4.0.0
+
+ com.qrakn
+ honcho
+ 1.0-SNAPSHOT
+
+
+
+ dmulloy2-repo
+ http://repo.dmulloy2.net/nexus/repository/public/
+
+
+
+
+
+ org.spigotmc
+ spigot-api
+ 1.8.8-R0.1-SNAPSHOT
+ provided
+
+
+ org.projectlombok
+ lombok
+ LATEST
+ provided
+
+
+ com.comphenix.protocol
+ ProtocolLib-v1_7_R4
+ 3.7.0-BETA
+ provided
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.6.1
+
+
+
+ 1.8
+ -parameters
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libs/mvn/com/qrakn/honcho/1.0-SNAPSHOT/honcho-1.0-SNAPSHOT.pom.lastUpdated b/libs/mvn/com/qrakn/honcho/1.0-SNAPSHOT/honcho-1.0-SNAPSHOT.pom.lastUpdated
new file mode 100644
index 0000000..101a581
--- /dev/null
+++ b/libs/mvn/com/qrakn/honcho/1.0-SNAPSHOT/honcho-1.0-SNAPSHOT.pom.lastUpdated
@@ -0,0 +1,4 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Thu Dec 06 19:17:53 CET 2018
+https\://hub.spigotmc.org/nexus/content/repositories/snapshots/.error=
+https\://hub.spigotmc.org/nexus/content/repositories/snapshots/.lastUpdated=1544120273880
diff --git a/libs/mvn/com/qrakn/honcho/1.0-SNAPSHOT/maven-metadata-local.xml b/libs/mvn/com/qrakn/honcho/1.0-SNAPSHOT/maven-metadata-local.xml
new file mode 100644
index 0000000..c76306c
--- /dev/null
+++ b/libs/mvn/com/qrakn/honcho/1.0-SNAPSHOT/maven-metadata-local.xml
@@ -0,0 +1,24 @@
+
+
+ com.qrakn
+ honcho
+ 1.0-SNAPSHOT
+
+
+ true
+
+ 20181205204222
+
+
+ jar
+ 1.0-SNAPSHOT
+ 20181205204222
+
+
+ pom
+ 1.0-SNAPSHOT
+ 20181205204222
+
+
+
+
diff --git a/libs/mvn/com/qrakn/honcho/1.0-SNAPSHOT/resolver-status.properties b/libs/mvn/com/qrakn/honcho/1.0-SNAPSHOT/resolver-status.properties
new file mode 100644
index 0000000..6059f6e
--- /dev/null
+++ b/libs/mvn/com/qrakn/honcho/1.0-SNAPSHOT/resolver-status.properties
@@ -0,0 +1,18 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Wed Aug 28 16:25:24 CEST 2019
+maven-metadata-spigot-repo.xml.lastUpdated=1561206761216
+maven-metadata-sk89q-snapshots.xml.lastUpdated=1555091181644
+maven-metadata-vault-repo.xml.error=
+maven-metadata-spigot.xml.error=
+maven-metadata-fawe-repo.xml.error=
+maven-metadata-vault-repo.xml.lastUpdated=1567002324908
+maven-metadata-placeholderapi.xml.error=
+maven-metadata-aikar.xml.error=
+maven-metadata-aikar.xml.lastUpdated=1566830524738
+maven-metadata-md5-repo.xml.lastUpdated=1543628811135
+maven-metadata-fawe-repo.xml.lastUpdated=1554928060497
+maven-metadata-md5-repo.xml.error=
+maven-metadata-placeholderapi.xml.lastUpdated=1561206761220
+maven-metadata-sk89q-snapshots.xml.error=
+maven-metadata-spigot-repo.xml.error=
+maven-metadata-spigot.xml.lastUpdated=1567002324892
diff --git a/libs/mvn/com/qrakn/honcho/maven-metadata-local.xml b/libs/mvn/com/qrakn/honcho/maven-metadata-local.xml
new file mode 100644
index 0000000..8ac7bad
--- /dev/null
+++ b/libs/mvn/com/qrakn/honcho/maven-metadata-local.xml
@@ -0,0 +1,11 @@
+
+
+ com.qrakn
+ honcho
+
+
+ 1.0-SNAPSHOT
+
+ 20181205204222
+
+
diff --git a/libs/mvn/com/qrakn/honcho/unknown/honcho-unknown.jar.lastUpdated b/libs/mvn/com/qrakn/honcho/unknown/honcho-unknown.jar.lastUpdated
new file mode 100644
index 0000000..a66c12b
--- /dev/null
+++ b/libs/mvn/com/qrakn/honcho/unknown/honcho-unknown.jar.lastUpdated
@@ -0,0 +1,6 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Tue Oct 30 17:14:34 EDT 2018
+https\://hub.spigotmc.org/nexus/content/repositories/snapshots/.error=
+https\://hub.spigotmc.org/nexus/content/repositories/snapshots/.lastUpdated=1540934074026
+https\://repo.maven.apache.org/maven2/.lastUpdated=1540934074159
+https\://repo.maven.apache.org/maven2/.error=
diff --git a/libs/mvn/com/qrakn/honcho/unknown/honcho-unknown.pom.lastUpdated b/libs/mvn/com/qrakn/honcho/unknown/honcho-unknown.pom.lastUpdated
new file mode 100644
index 0000000..e66cd61
--- /dev/null
+++ b/libs/mvn/com/qrakn/honcho/unknown/honcho-unknown.pom.lastUpdated
@@ -0,0 +1,6 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Tue Oct 30 17:14:33 EDT 2018
+https\://hub.spigotmc.org/nexus/content/repositories/snapshots/.error=
+https\://hub.spigotmc.org/nexus/content/repositories/snapshots/.lastUpdated=1540934073643
+https\://repo.maven.apache.org/maven2/.lastUpdated=1540934073883
+https\://repo.maven.apache.org/maven2/.error=
diff --git a/libs/mvn/com/qrakn/phoenix-lang/1.0-SNAPSHOT/_remote.repositories b/libs/mvn/com/qrakn/phoenix-lang/1.0-SNAPSHOT/_remote.repositories
new file mode 100644
index 0000000..45537bc
--- /dev/null
+++ b/libs/mvn/com/qrakn/phoenix-lang/1.0-SNAPSHOT/_remote.repositories
@@ -0,0 +1,4 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Thu Sep 20 04:27:40 PDT 2018
+phoenix-lang-1.0-SNAPSHOT.jar>=
+phoenix-lang-1.0-SNAPSHOT.pom>=
diff --git a/libs/mvn/com/qrakn/phoenix-lang/1.0-SNAPSHOT/maven-metadata-local.xml b/libs/mvn/com/qrakn/phoenix-lang/1.0-SNAPSHOT/maven-metadata-local.xml
new file mode 100644
index 0000000..6ab952d
--- /dev/null
+++ b/libs/mvn/com/qrakn/phoenix-lang/1.0-SNAPSHOT/maven-metadata-local.xml
@@ -0,0 +1,24 @@
+
+
+ com.qrakn
+ phoenix-lang
+ 1.0-SNAPSHOT
+
+
+ true
+
+ 20180920112740
+
+
+ jar
+ 1.0-SNAPSHOT
+ 20180920112740
+
+
+ pom
+ 1.0-SNAPSHOT
+ 20180920112740
+
+
+
+
diff --git a/libs/mvn/com/qrakn/phoenix-lang/1.0-SNAPSHOT/phoenix-lang-1.0-SNAPSHOT.jar b/libs/mvn/com/qrakn/phoenix-lang/1.0-SNAPSHOT/phoenix-lang-1.0-SNAPSHOT.jar
new file mode 100644
index 0000000..3fa3fee
Binary files /dev/null and b/libs/mvn/com/qrakn/phoenix-lang/1.0-SNAPSHOT/phoenix-lang-1.0-SNAPSHOT.jar differ
diff --git a/libs/mvn/com/qrakn/phoenix-lang/1.0-SNAPSHOT/phoenix-lang-1.0-SNAPSHOT.jar.lastUpdated b/libs/mvn/com/qrakn/phoenix-lang/1.0-SNAPSHOT/phoenix-lang-1.0-SNAPSHOT.jar.lastUpdated
new file mode 100644
index 0000000..f2c1a9e
--- /dev/null
+++ b/libs/mvn/com/qrakn/phoenix-lang/1.0-SNAPSHOT/phoenix-lang-1.0-SNAPSHOT.jar.lastUpdated
@@ -0,0 +1,4 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Thu Dec 06 19:17:47 CET 2018
+https\://hub.spigotmc.org/nexus/content/repositories/snapshots/.error=
+https\://hub.spigotmc.org/nexus/content/repositories/snapshots/.lastUpdated=1544120267050
diff --git a/libs/mvn/com/qrakn/phoenix-lang/1.0-SNAPSHOT/phoenix-lang-1.0-SNAPSHOT.pom b/libs/mvn/com/qrakn/phoenix-lang/1.0-SNAPSHOT/phoenix-lang-1.0-SNAPSHOT.pom
new file mode 100644
index 0000000..eb87e00
--- /dev/null
+++ b/libs/mvn/com/qrakn/phoenix-lang/1.0-SNAPSHOT/phoenix-lang-1.0-SNAPSHOT.pom
@@ -0,0 +1,30 @@
+
+
+
+ phoenix
+ com.qrakn
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ phoenix-lang
+
+
+
+ md5-repo
+ http://repo.md-5.net/content/groups/public/
+
+
+
+
+
+ org.spigotmc
+ spigot-api
+ 1.7.10-R0.1-SNAPSHOT
+ provided
+
+
+
+
diff --git a/libs/mvn/com/qrakn/phoenix-lang/1.0-SNAPSHOT/phoenix-lang-1.0-SNAPSHOT.pom.lastUpdated b/libs/mvn/com/qrakn/phoenix-lang/1.0-SNAPSHOT/phoenix-lang-1.0-SNAPSHOT.pom.lastUpdated
new file mode 100644
index 0000000..6302ac8
--- /dev/null
+++ b/libs/mvn/com/qrakn/phoenix-lang/1.0-SNAPSHOT/phoenix-lang-1.0-SNAPSHOT.pom.lastUpdated
@@ -0,0 +1,4 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Thu Dec 06 19:17:46 CET 2018
+https\://hub.spigotmc.org/nexus/content/repositories/snapshots/.error=
+https\://hub.spigotmc.org/nexus/content/repositories/snapshots/.lastUpdated=1544120266767
diff --git a/libs/mvn/com/qrakn/phoenix-lang/1.0-SNAPSHOT/resolver-status.properties b/libs/mvn/com/qrakn/phoenix-lang/1.0-SNAPSHOT/resolver-status.properties
new file mode 100644
index 0000000..7602060
--- /dev/null
+++ b/libs/mvn/com/qrakn/phoenix-lang/1.0-SNAPSHOT/resolver-status.properties
@@ -0,0 +1,20 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Wed Aug 28 16:25:25 CEST 2019
+maven-metadata-fawe-repo.xml.lastUpdated=1554928060699
+maven-metadata-placeholderapi.xml.error=
+maven-metadata-vault-repo.xml.lastUpdated=1567002325153
+maven-metadata-md5-repo.xml.error=
+maven-metadata-md5-repo.xml.lastUpdated=1543628810804
+maven-metadata-dmulloy2-repo.xml.lastUpdated=1558733574445
+maven-metadata-spigot-repo.xml.lastUpdated=1561206761474
+maven-metadata-spigot.xml.lastUpdated=1567002325130
+maven-metadata-sk89q-snapshots.xml.lastUpdated=1555091182166
+maven-metadata-placeholderapi.xml.lastUpdated=1561206761435
+maven-metadata-dmulloy2-repo.xml.error=
+maven-metadata-spigot-repo.xml.error=
+maven-metadata-spigot.xml.error=
+maven-metadata-fawe-repo.xml.error=
+maven-metadata-aikar.xml.lastUpdated=1566830526101
+maven-metadata-sk89q-snapshots.xml.error=
+maven-metadata-vault-repo.xml.error=
+maven-metadata-aikar.xml.error=
diff --git a/libs/mvn/com/qrakn/phoenix-lang/maven-metadata-local.xml b/libs/mvn/com/qrakn/phoenix-lang/maven-metadata-local.xml
new file mode 100644
index 0000000..7959ce2
--- /dev/null
+++ b/libs/mvn/com/qrakn/phoenix-lang/maven-metadata-local.xml
@@ -0,0 +1,11 @@
+
+
+ com.qrakn
+ phoenix-lang
+
+
+ 1.0-SNAPSHOT
+
+ 20180920112740
+
+
diff --git a/libs/mvn/com/qrakn/phoenix-lang/unknown/phoenix-lang-unknown.jar.lastUpdated b/libs/mvn/com/qrakn/phoenix-lang/unknown/phoenix-lang-unknown.jar.lastUpdated
new file mode 100644
index 0000000..171fca3
--- /dev/null
+++ b/libs/mvn/com/qrakn/phoenix-lang/unknown/phoenix-lang-unknown.jar.lastUpdated
@@ -0,0 +1,6 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Tue Sep 04 13:09:43 PDT 2018
+http\://repo.md-5.net/content/groups/public/.error=
+http\://repo.md-5.net/content/groups/public/.lastUpdated=1536091783147
+https\://repo.maven.apache.org/maven2/.lastUpdated=1536091783477
+https\://repo.maven.apache.org/maven2/.error=
diff --git a/libs/mvn/com/qrakn/phoenix-lang/unknown/phoenix-lang-unknown.pom.lastUpdated b/libs/mvn/com/qrakn/phoenix-lang/unknown/phoenix-lang-unknown.pom.lastUpdated
new file mode 100644
index 0000000..e1978af
--- /dev/null
+++ b/libs/mvn/com/qrakn/phoenix-lang/unknown/phoenix-lang-unknown.pom.lastUpdated
@@ -0,0 +1,6 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Tue Sep 04 13:09:32 PDT 2018
+http\://repo.md-5.net/content/groups/public/.error=
+http\://repo.md-5.net/content/groups/public/.lastUpdated=1536091772234
+https\://repo.maven.apache.org/maven2/.lastUpdated=1536091772466
+https\://repo.maven.apache.org/maven2/.error=
diff --git a/libs/mvn/com/qrakn/phoenix/.DS_Store b/libs/mvn/com/qrakn/phoenix/.DS_Store
new file mode 100644
index 0000000..a152eaf
Binary files /dev/null and b/libs/mvn/com/qrakn/phoenix/.DS_Store differ
diff --git a/libs/mvn/com/qrakn/phoenix/1.0-SNAPSHOT/_remote.repositories b/libs/mvn/com/qrakn/phoenix/1.0-SNAPSHOT/_remote.repositories
new file mode 100644
index 0000000..0a342e5
--- /dev/null
+++ b/libs/mvn/com/qrakn/phoenix/1.0-SNAPSHOT/_remote.repositories
@@ -0,0 +1,3 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Thu Sep 20 04:27:38 PDT 2018
+phoenix-1.0-SNAPSHOT.pom>=
diff --git a/libs/mvn/com/qrakn/phoenix/1.0-SNAPSHOT/maven-metadata-local.xml b/libs/mvn/com/qrakn/phoenix/1.0-SNAPSHOT/maven-metadata-local.xml
new file mode 100644
index 0000000..c6959d2
--- /dev/null
+++ b/libs/mvn/com/qrakn/phoenix/1.0-SNAPSHOT/maven-metadata-local.xml
@@ -0,0 +1,19 @@
+
+
+ com.qrakn
+ phoenix
+ 1.0-SNAPSHOT
+
+
+ true
+
+ 20180920112738
+
+
+ pom
+ 1.0-SNAPSHOT
+ 20180920112738
+
+
+
+
diff --git a/libs/mvn/com/qrakn/phoenix/1.0-SNAPSHOT/phoenix-1.0-SNAPSHOT.pom b/libs/mvn/com/qrakn/phoenix/1.0-SNAPSHOT/phoenix-1.0-SNAPSHOT.pom
new file mode 100644
index 0000000..652eb15
--- /dev/null
+++ b/libs/mvn/com/qrakn/phoenix/1.0-SNAPSHOT/phoenix-1.0-SNAPSHOT.pom
@@ -0,0 +1,57 @@
+
+
+ 4.0.0
+
+ com.qrakn
+ phoenix
+ pom
+ 1.0-SNAPSHOT
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ 1.8
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 2.1
+
+
+ package
+
+ shade
+
+
+
+
+
+ false
+
+
+
+
+
+
+ phoenix-lang
+ phoenix-command
+ phoenix-utils
+
+
+
+
+ org.projectlombok
+ lombok
+ 1.14.8
+ provided
+
+
+
+
diff --git a/libs/mvn/com/qrakn/phoenix/1.0-SNAPSHOT/phoenix-1.0-SNAPSHOT.pom.lastUpdated b/libs/mvn/com/qrakn/phoenix/1.0-SNAPSHOT/phoenix-1.0-SNAPSHOT.pom.lastUpdated
new file mode 100644
index 0000000..35b457e
--- /dev/null
+++ b/libs/mvn/com/qrakn/phoenix/1.0-SNAPSHOT/phoenix-1.0-SNAPSHOT.pom.lastUpdated
@@ -0,0 +1,4 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Tue Sep 04 13:02:56 PDT 2018
+http\://repo.md-5.net/content/groups/public/.error=
+http\://repo.md-5.net/content/groups/public/.lastUpdated=1536091376967
diff --git a/libs/mvn/com/qrakn/phoenix/1.0-SNAPSHOT/resolver-status.properties b/libs/mvn/com/qrakn/phoenix/1.0-SNAPSHOT/resolver-status.properties
new file mode 100644
index 0000000..1369ab2
--- /dev/null
+++ b/libs/mvn/com/qrakn/phoenix/1.0-SNAPSHOT/resolver-status.properties
@@ -0,0 +1,20 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Wed Aug 28 16:25:25 CEST 2019
+maven-metadata-fawe-repo.xml.lastUpdated=1554928060905
+maven-metadata-placeholderapi.xml.error=
+maven-metadata-vault-repo.xml.lastUpdated=1567002325385
+maven-metadata-md5-repo.xml.error=
+maven-metadata-md5-repo.xml.lastUpdated=1567002325478
+maven-metadata-dmulloy2-repo.xml.lastUpdated=1558733574689
+maven-metadata-spigot-repo.xml.lastUpdated=1561206761712
+maven-metadata-spigot.xml.lastUpdated=1567002325378
+maven-metadata-sk89q-snapshots.xml.lastUpdated=1555091182604
+maven-metadata-placeholderapi.xml.lastUpdated=1561206761695
+maven-metadata-dmulloy2-repo.xml.error=
+maven-metadata-spigot-repo.xml.error=
+maven-metadata-spigot.xml.error=
+maven-metadata-fawe-repo.xml.error=
+maven-metadata-aikar.xml.lastUpdated=1566830527942
+maven-metadata-sk89q-snapshots.xml.error=
+maven-metadata-vault-repo.xml.error=
+maven-metadata-aikar.xml.error=
diff --git a/libs/mvn/com/qrakn/phoenix/maven-metadata-local.xml b/libs/mvn/com/qrakn/phoenix/maven-metadata-local.xml
new file mode 100644
index 0000000..161f5e5
--- /dev/null
+++ b/libs/mvn/com/qrakn/phoenix/maven-metadata-local.xml
@@ -0,0 +1,11 @@
+
+
+ com.qrakn
+ phoenix
+
+
+ 1.0-SNAPSHOT
+
+ 20180920112738
+
+
diff --git a/libs/mvn/com/qrakn/phoenix/phoenix-lang/.DS_Store b/libs/mvn/com/qrakn/phoenix/phoenix-lang/.DS_Store
new file mode 100644
index 0000000..ac4ab3c
Binary files /dev/null and b/libs/mvn/com/qrakn/phoenix/phoenix-lang/.DS_Store differ
diff --git a/libs/mvn/com/qrakn/phoenix/phoenix-lang/1.0-SNAPSHOT/phoenix-lang-1.0-SNAPSHOT.jar.lastUpdated b/libs/mvn/com/qrakn/phoenix/phoenix-lang/1.0-SNAPSHOT/phoenix-lang-1.0-SNAPSHOT.jar.lastUpdated
new file mode 100644
index 0000000..f45fe78
--- /dev/null
+++ b/libs/mvn/com/qrakn/phoenix/phoenix-lang/1.0-SNAPSHOT/phoenix-lang-1.0-SNAPSHOT.jar.lastUpdated
@@ -0,0 +1,6 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Tue Oct 30 17:13:29 EDT 2018
+http\://repo.md-5.net/content/groups/public/.error=
+https\://hub.spigotmc.org/nexus/content/repositories/snapshots/.lastUpdated=1540934009226
+https\://hub.spigotmc.org/nexus/content/repositories/snapshots/.error=
+http\://repo.md-5.net/content/groups/public/.lastUpdated=1536091590022
diff --git a/libs/mvn/com/qrakn/phoenix/phoenix-lang/1.0-SNAPSHOT/phoenix-lang-1.0-SNAPSHOT.pom.lastUpdated b/libs/mvn/com/qrakn/phoenix/phoenix-lang/1.0-SNAPSHOT/phoenix-lang-1.0-SNAPSHOT.pom.lastUpdated
new file mode 100644
index 0000000..9c4720a
--- /dev/null
+++ b/libs/mvn/com/qrakn/phoenix/phoenix-lang/1.0-SNAPSHOT/phoenix-lang-1.0-SNAPSHOT.pom.lastUpdated
@@ -0,0 +1,6 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Tue Oct 30 17:13:29 EDT 2018
+http\://repo.md-5.net/content/groups/public/.error=
+https\://hub.spigotmc.org/nexus/content/repositories/snapshots/.lastUpdated=1540934009086
+https\://hub.spigotmc.org/nexus/content/repositories/snapshots/.error=
+http\://repo.md-5.net/content/groups/public/.lastUpdated=1536091589755
diff --git a/libs/mvn/com/qrakn/phoenix/phoenix-lang/1.0-SNAPSHOT/resolver-status.properties b/libs/mvn/com/qrakn/phoenix/phoenix-lang/1.0-SNAPSHOT/resolver-status.properties
new file mode 100644
index 0000000..c2055a3
--- /dev/null
+++ b/libs/mvn/com/qrakn/phoenix/phoenix-lang/1.0-SNAPSHOT/resolver-status.properties
@@ -0,0 +1,6 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Tue Oct 30 17:13:28 EDT 2018
+maven-metadata-md5-repo.xml.error=
+maven-metadata-spigot-repo.xml.lastUpdated=1540934008957
+maven-metadata-md5-repo.xml.lastUpdated=1536091588462
+maven-metadata-spigot-repo.xml.error=
diff --git a/libs/mvn/com/qrakn/phoenix/phoenix-lang/unknown/phoenix-lang-unknown.jar.lastUpdated b/libs/mvn/com/qrakn/phoenix/phoenix-lang/unknown/phoenix-lang-unknown.jar.lastUpdated
new file mode 100644
index 0000000..1675e00
--- /dev/null
+++ b/libs/mvn/com/qrakn/phoenix/phoenix-lang/unknown/phoenix-lang-unknown.jar.lastUpdated
@@ -0,0 +1,6 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Tue Sep 04 13:07:58 PDT 2018
+http\://repo.md-5.net/content/groups/public/.error=
+http\://repo.md-5.net/content/groups/public/.lastUpdated=1536091677549
+https\://repo.maven.apache.org/maven2/.lastUpdated=1536091678759
+https\://repo.maven.apache.org/maven2/.error=
diff --git a/libs/mvn/com/qrakn/phoenix/phoenix-lang/unknown/phoenix-lang-unknown.pom.lastUpdated b/libs/mvn/com/qrakn/phoenix/phoenix-lang/unknown/phoenix-lang-unknown.pom.lastUpdated
new file mode 100644
index 0000000..a3f923d
--- /dev/null
+++ b/libs/mvn/com/qrakn/phoenix/phoenix-lang/unknown/phoenix-lang-unknown.pom.lastUpdated
@@ -0,0 +1,6 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Tue Sep 04 13:07:57 PDT 2018
+http\://repo.md-5.net/content/groups/public/.error=
+http\://repo.md-5.net/content/groups/public/.lastUpdated=1536091674647
+https\://repo.maven.apache.org/maven2/.lastUpdated=1536091677204
+https\://repo.maven.apache.org/maven2/.error=
diff --git a/libs/mvn/com/qrakn/qrakn.rar b/libs/mvn/com/qrakn/qrakn.rar
new file mode 100644
index 0000000..9115bd0
Binary files /dev/null and b/libs/mvn/com/qrakn/qrakn.rar differ
diff --git a/libs/mvn/me/allen/hubcore/1.0-SNAPSHOT/_remote.repositories b/libs/mvn/me/allen/hubcore/1.0-SNAPSHOT/_remote.repositories
new file mode 100644
index 0000000..b97a68c
--- /dev/null
+++ b/libs/mvn/me/allen/hubcore/1.0-SNAPSHOT/_remote.repositories
@@ -0,0 +1,4 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Sat Jun 01 14:29:43 CEST 2019
+hubcore-1.0-SNAPSHOT.jar>=
+hubcore-1.0-SNAPSHOT.pom>=
diff --git a/libs/mvn/me/allen/hubcore/1.0-SNAPSHOT/hubcore-1.0-SNAPSHOT.jar b/libs/mvn/me/allen/hubcore/1.0-SNAPSHOT/hubcore-1.0-SNAPSHOT.jar
new file mode 100644
index 0000000..2774655
Binary files /dev/null and b/libs/mvn/me/allen/hubcore/1.0-SNAPSHOT/hubcore-1.0-SNAPSHOT.jar differ
diff --git a/libs/mvn/me/allen/hubcore/1.0-SNAPSHOT/hubcore-1.0-SNAPSHOT.pom b/libs/mvn/me/allen/hubcore/1.0-SNAPSHOT/hubcore-1.0-SNAPSHOT.pom
new file mode 100644
index 0000000..97c7aa9
--- /dev/null
+++ b/libs/mvn/me/allen/hubcore/1.0-SNAPSHOT/hubcore-1.0-SNAPSHOT.pom
@@ -0,0 +1,147 @@
+
+
+ 4.0.0
+
+ me.allen
+ hubcore
+ 1.0-SNAPSHOT
+
+ HubCore
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ 8
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.2.0
+
+
+ package
+
+ shade
+
+
+
+
+ io.netty.*
+
+
+ false
+
+
+
+
+
+
+
+
+
+ vault-repo
+ http://nexus.hc.to/content/repositories/pub_releases
+
+
+
+ placeholderapi
+ http://repo.extendedclip.com/content/repositories/placeholderapi/
+
+
+
+ mvdw-software
+ MVdW Public Repositories
+ http://repo.mvdw-software.be/content/groups/public/
+
+
+
+
+
+ org.spigotmc
+ spigot
+ 1.8.8-R0.1-SNAPSHOT
+ system
+ ${project.basedir}/lib/server.jar
+
+
+
+ me.allen
+ Ziggurat
+ 1.0-SNAPSHOT
+ compile
+
+
+
+ me.joeleoli
+ portal
+ 1.0.0
+ system
+ ${project.basedir}/lib/Portal.jar
+
+
+
+ land.potion
+ core
+ 0.0.4-DEV
+ system
+ ${project.basedir}/lib/Core.jar
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.0
+ provided
+
+
+
+ net.milkbowl.vault
+ VaultAPI
+ 1.7
+ provided
+
+
+
+ ru.tehkode
+ PermissionsEx
+ 1.22
+ system
+ ${project.basedir}/lib/PermissionsEx.jar
+
+
+
+ me.lucko.luckperms
+ luckperms-api
+ 4.3
+ provided
+
+
+
+ me.clip
+ placeholderapi
+ 2.9.2
+ provided
+
+
+
+ be.maximvdw
+ MVdWPlaceholderAPI
+ LATEST
+ provided
+
+
+
+ com.google.guava
+ guava
+ 19.0
+ provided
+
+
+
\ No newline at end of file
diff --git a/libs/mvn/me/allen/hubcore/1.0-SNAPSHOT/maven-metadata-local.xml b/libs/mvn/me/allen/hubcore/1.0-SNAPSHOT/maven-metadata-local.xml
new file mode 100644
index 0000000..d019f6c
--- /dev/null
+++ b/libs/mvn/me/allen/hubcore/1.0-SNAPSHOT/maven-metadata-local.xml
@@ -0,0 +1,24 @@
+
+
+ me.allen
+ hubcore
+ 1.0-SNAPSHOT
+
+
+ true
+
+ 20190601122943
+
+
+ jar
+ 1.0-SNAPSHOT
+ 20190601122943
+
+
+ pom
+ 1.0-SNAPSHOT
+ 20190601122943
+
+
+
+
diff --git a/libs/mvn/me/allen/hubcore/maven-metadata-local.xml b/libs/mvn/me/allen/hubcore/maven-metadata-local.xml
new file mode 100644
index 0000000..10bee19
--- /dev/null
+++ b/libs/mvn/me/allen/hubcore/maven-metadata-local.xml
@@ -0,0 +1,11 @@
+
+
+ me.allen
+ hubcore
+
+
+ 1.0-SNAPSHOT
+
+ 20190601122943
+
+
diff --git a/libs/mvn/me/allen/npclib/1.0.0/npclib-1.0.0.jar.lastUpdated b/libs/mvn/me/allen/npclib/1.0.0/npclib-1.0.0.jar.lastUpdated
new file mode 100644
index 0000000..215ccd8
--- /dev/null
+++ b/libs/mvn/me/allen/npclib/1.0.0/npclib-1.0.0.jar.lastUpdated
@@ -0,0 +1,10 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Thu May 30 16:19:04 CEST 2019
+http\://repo.mvdw-software.be/content/groups/public/.lastUpdated=1559225944188
+http\://nexus.hc.to/content/repositories/pub_releases/.lastUpdated=1559225943075
+http\://repo.mvdw-software.be/content/groups/public/.error=
+https\://repo.maven.apache.org/maven2/.lastUpdated=1559225944485
+http\://repo.extendedclip.com/content/repositories/placeholderapi/.lastUpdated=1559225943502
+http\://repo.extendedclip.com/content/repositories/placeholderapi/.error=
+https\://repo.maven.apache.org/maven2/.error=
+http\://nexus.hc.to/content/repositories/pub_releases/.error=
diff --git a/libs/mvn/me/allen/npclib/1.0.0/npclib-1.0.0.pom.lastUpdated b/libs/mvn/me/allen/npclib/1.0.0/npclib-1.0.0.pom.lastUpdated
new file mode 100644
index 0000000..037b72d
--- /dev/null
+++ b/libs/mvn/me/allen/npclib/1.0.0/npclib-1.0.0.pom.lastUpdated
@@ -0,0 +1,10 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Thu May 30 16:18:58 CEST 2019
+http\://repo.mvdw-software.be/content/groups/public/.lastUpdated=1559225938178
+http\://nexus.hc.to/content/repositories/pub_releases/.lastUpdated=1559225937909
+http\://repo.mvdw-software.be/content/groups/public/.error=
+https\://repo.maven.apache.org/maven2/.lastUpdated=1559225938229
+http\://repo.extendedclip.com/content/repositories/placeholderapi/.lastUpdated=1559225938117
+http\://repo.extendedclip.com/content/repositories/placeholderapi/.error=
+https\://repo.maven.apache.org/maven2/.error=
+http\://nexus.hc.to/content/repositories/pub_releases/.error=
diff --git a/libs/mvn/me/allen/ziggurat.rar b/libs/mvn/me/allen/ziggurat.rar
new file mode 100644
index 0000000..41a6334
Binary files /dev/null and b/libs/mvn/me/allen/ziggurat.rar differ
diff --git a/libs/mvn/me/allen/ziggurat/1.0-SNAPSHOT/_remote.repositories b/libs/mvn/me/allen/ziggurat/1.0-SNAPSHOT/_remote.repositories
new file mode 100644
index 0000000..6bd1631
--- /dev/null
+++ b/libs/mvn/me/allen/ziggurat/1.0-SNAPSHOT/_remote.repositories
@@ -0,0 +1,4 @@
+#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
+#Wed Dec 12 19:08:01 CET 2018
+ziggurat-1.0-SNAPSHOT.pom>=
+ziggurat-1.0-SNAPSHOT.jar>=
diff --git a/libs/mvn/me/allen/ziggurat/1.0-SNAPSHOT/maven-metadata-local.xml b/libs/mvn/me/allen/ziggurat/1.0-SNAPSHOT/maven-metadata-local.xml
new file mode 100644
index 0000000..9601afb
--- /dev/null
+++ b/libs/mvn/me/allen/ziggurat/1.0-SNAPSHOT/maven-metadata-local.xml
@@ -0,0 +1,24 @@
+
+
+ me.allen
+ ziggurat
+ 1.0-SNAPSHOT
+
+
+ true
+
+ 20181212180801
+
+
+ jar
+ 1.0-SNAPSHOT
+ 20181212180801
+
+
+ pom
+ 1.0-SNAPSHOT
+ 20181212180801
+
+
+
+
diff --git a/libs/mvn/me/allen/ziggurat/1.0-SNAPSHOT/resolver-status.properties b/libs/mvn/me/allen/ziggurat/1.0-SNAPSHOT/resolver-status.properties
new file mode 100644
index 0000000..c9ef885
--- /dev/null
+++ b/libs/mvn/me/allen/ziggurat/1.0-SNAPSHOT/resolver-status.properties
@@ -0,0 +1,22 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Wed Aug 28 16:25:24 CEST 2019
+maven-metadata-fawe-repo.xml.lastUpdated=1554928059235
+maven-metadata-placeholderapi.xml.error=
+maven-metadata-vault-repo.xml.lastUpdated=1567002324668
+maven-metadata-sk89q-repo.xml.error=
+maven-metadata-sk89q-repo.xml.lastUpdated=1548021212883
+maven-metadata-spigot-repo.xml.lastUpdated=1555091178317
+maven-metadata-spigot.xml.lastUpdated=1567002324601
+maven-metadata-sk89q-snapshots.xml.lastUpdated=1555091178396
+maven-metadata-placeholderapi.xml.lastUpdated=1559392167913
+maven-metadata-spigot-repo.xml.error=
+maven-metadata-spigot.xml.error=
+maven-metadata-fawe-repo.xml.error=
+maven-metadata-aikar.xml.lastUpdated=1566830522373
+maven-metadata-sk89q-snapshots.xml.error=
+maven-metadata-qrakn-repo.xml.error=
+maven-metadata-qrakn-repo.xml.lastUpdated=1548515991361
+maven-metadata-mvdw-software.xml.error=
+maven-metadata-vault-repo.xml.error=
+maven-metadata-aikar.xml.error=
+maven-metadata-mvdw-software.xml.lastUpdated=1559392167782
diff --git a/libs/mvn/me/allen/ziggurat/1.0-SNAPSHOT/ziggurat-1.0-SNAPSHOT.jar b/libs/mvn/me/allen/ziggurat/1.0-SNAPSHOT/ziggurat-1.0-SNAPSHOT.jar
new file mode 100644
index 0000000..1ee42c8
Binary files /dev/null and b/libs/mvn/me/allen/ziggurat/1.0-SNAPSHOT/ziggurat-1.0-SNAPSHOT.jar differ
diff --git a/libs/mvn/me/allen/ziggurat/1.0-SNAPSHOT/ziggurat-1.0-SNAPSHOT.pom b/libs/mvn/me/allen/ziggurat/1.0-SNAPSHOT/ziggurat-1.0-SNAPSHOT.pom
new file mode 100644
index 0000000..e3a29bd
--- /dev/null
+++ b/libs/mvn/me/allen/ziggurat/1.0-SNAPSHOT/ziggurat-1.0-SNAPSHOT.pom
@@ -0,0 +1,9 @@
+
+
+ 4.0.0
+ me.allen
+ ziggurat
+ 1.0-SNAPSHOT
+ POM was created from install:install-file
+
diff --git a/libs/mvn/me/allen/ziggurat/1.0.2/ziggurat-1.0.2.jar.lastUpdated b/libs/mvn/me/allen/ziggurat/1.0.2/ziggurat-1.0.2.jar.lastUpdated
new file mode 100644
index 0000000..375c916
--- /dev/null
+++ b/libs/mvn/me/allen/ziggurat/1.0.2/ziggurat-1.0.2.jar.lastUpdated
@@ -0,0 +1,10 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Thu May 30 16:19:04 CEST 2019
+http\://repo.mvdw-software.be/content/groups/public/.lastUpdated=1559225944182
+http\://nexus.hc.to/content/repositories/pub_releases/.lastUpdated=1559225943071
+http\://repo.mvdw-software.be/content/groups/public/.error=
+https\://repo.maven.apache.org/maven2/.lastUpdated=1559225944482
+http\://repo.extendedclip.com/content/repositories/placeholderapi/.lastUpdated=1559225943497
+http\://repo.extendedclip.com/content/repositories/placeholderapi/.error=
+https\://repo.maven.apache.org/maven2/.error=
+http\://nexus.hc.to/content/repositories/pub_releases/.error=
diff --git a/libs/mvn/me/allen/ziggurat/1.0.2/ziggurat-1.0.2.pom.lastUpdated b/libs/mvn/me/allen/ziggurat/1.0.2/ziggurat-1.0.2.pom.lastUpdated
new file mode 100644
index 0000000..dc665d6
--- /dev/null
+++ b/libs/mvn/me/allen/ziggurat/1.0.2/ziggurat-1.0.2.pom.lastUpdated
@@ -0,0 +1,10 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Thu May 30 16:18:57 CEST 2019
+http\://repo.mvdw-software.be/content/groups/public/.lastUpdated=1559225937530
+http\://nexus.hc.to/content/repositories/pub_releases/.lastUpdated=1559225936769
+http\://repo.mvdw-software.be/content/groups/public/.error=
+https\://repo.maven.apache.org/maven2/.lastUpdated=1559225937678
+http\://repo.extendedclip.com/content/repositories/placeholderapi/.lastUpdated=1559225936973
+http\://repo.extendedclip.com/content/repositories/placeholderapi/.error=
+https\://repo.maven.apache.org/maven2/.error=
+http\://nexus.hc.to/content/repositories/pub_releases/.error=
diff --git a/libs/mvn/me/allen/ziggurat/maven-metadata-local.xml b/libs/mvn/me/allen/ziggurat/maven-metadata-local.xml
new file mode 100644
index 0000000..03c6ce3
--- /dev/null
+++ b/libs/mvn/me/allen/ziggurat/maven-metadata-local.xml
@@ -0,0 +1,11 @@
+
+
+ me.allen
+ ziggurat
+
+
+ 1.0-SNAPSHOT
+
+ 20181212180801
+
+
diff --git a/libs/mvn/me/allen/ziggurat/resolver-status.properties b/libs/mvn/me/allen/ziggurat/resolver-status.properties
new file mode 100644
index 0000000..bc5a71c
--- /dev/null
+++ b/libs/mvn/me/allen/ziggurat/resolver-status.properties
@@ -0,0 +1,12 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Thu May 30 16:23:13 CEST 2019
+maven-metadata-spigot-repo.xml.lastUpdated=1559226193242
+maven-metadata-mvdw-software.xml.error=
+maven-metadata-mvdw-software.xml.lastUpdated=1559226151665
+maven-metadata-vault-repo.xml.error=
+maven-metadata-vault-repo.xml.lastUpdated=1559226151724
+maven-metadata-placeholderapi.xml.error=
+maven-metadata-placeholderapi.xml.lastUpdated=1559226151703
+maven-metadata-spigot-repo.xml.error=
+maven-metadata-central.xml.lastUpdated=1559226151624
+maven-metadata-central.xml.error=
diff --git a/libs/mvn/me/allen/ziggurat/ziggurat/1.0.0/ziggurat-1.0.0.jar.lastUpdated b/libs/mvn/me/allen/ziggurat/ziggurat/1.0.0/ziggurat-1.0.0.jar.lastUpdated
new file mode 100644
index 0000000..04f7325
--- /dev/null
+++ b/libs/mvn/me/allen/ziggurat/ziggurat/1.0.0/ziggurat-1.0.0.jar.lastUpdated
@@ -0,0 +1,8 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Wed Dec 12 19:08:30 CET 2018
+http\://maven.sk89q.com/repo/.error=
+http\://maven.sk89q.com/repo/.lastUpdated=1544638109971
+http\://ci.athion.net/job/FastAsyncWorldEdit/ws/mvn/.error=
+http\://ci.athion.net/job/FastAsyncWorldEdit/ws/mvn/.lastUpdated=1544638110502
+https\://repo.maven.apache.org/maven2/.lastUpdated=1544638110662
+https\://repo.maven.apache.org/maven2/.error=
diff --git a/libs/mvn/me/allen/ziggurat/ziggurat/1.0.0/ziggurat-1.0.0.pom.lastUpdated b/libs/mvn/me/allen/ziggurat/ziggurat/1.0.0/ziggurat-1.0.0.pom.lastUpdated
new file mode 100644
index 0000000..f1134b7
--- /dev/null
+++ b/libs/mvn/me/allen/ziggurat/ziggurat/1.0.0/ziggurat-1.0.0.pom.lastUpdated
@@ -0,0 +1,8 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Wed Dec 12 19:08:29 CET 2018
+http\://maven.sk89q.com/repo/.error=
+http\://maven.sk89q.com/repo/.lastUpdated=1544638108852
+http\://ci.athion.net/job/FastAsyncWorldEdit/ws/mvn/.error=
+http\://ci.athion.net/job/FastAsyncWorldEdit/ws/mvn/.lastUpdated=1544638109426
+https\://repo.maven.apache.org/maven2/.lastUpdated=1544638109658
+https\://repo.maven.apache.org/maven2/.error=
diff --git a/libs/paperspigot-api.jar b/libs/paperspigot-api.jar
new file mode 100644
index 0000000..00ae906
Binary files /dev/null and b/libs/paperspigot-api.jar differ
diff --git a/out/artifacts/PotSG_jar/PotSG.jar b/out/artifacts/PotSG_jar/PotSG.jar
new file mode 100644
index 0000000..c448e4b
Binary files /dev/null and b/out/artifacts/PotSG_jar/PotSG.jar differ
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..d1383ce
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,161 @@
+
+
+ 4.0.0
+
+ me.m69.scenarios
+ PotSG-Scenarios
+ 1.0-SNAPSHOT
+
+
+
+ vault-repo
+ http://nexus.hc.to/content/repositories/pub_releases
+
+
+ aikar
+ https://repo.aikar.co/content/groups/aikar/
+
+
+ spigot
+ https://hub.spigotmc.org/nexus/content/groups/public/
+
+
+ dmulloy2-repo
+ http://repo.dmulloy2.net/nexus/repository/public/
+
+
+ apache-commons-lang
+ https://mvnrepository.com/artifact/org.apache.commons/commons-lang3
+
+
+ apache-commons-text
+ https://mvnrepository.com/artifact/org.apache.commons/commons-text
+
+
+ google-gson
+ https://mvnrepository.com/artifact/com.google.code.gson/gson
+
+
+
+
+
+ co.aikar
+ taskchain-bukkit
+ LATEST
+
+
+ org.projectlombok
+ lombok
+ 1.16.16
+ provided
+
+
+ net.hylist
+ spigot-api
+ 1.7.10-R0.1-SNAPSHOT
+ provided
+
+
+ net.hylist
+ spigot-server
+ 1.7.10-R0.1-SNAPSHOT
+ provided
+
+
+
+
+ org.mongodb
+ mongo-java-driver
+ 3.9.1
+
+
+
+ net.milkbowl.vault
+ VaultAPI
+ 1.7
+ provided
+
+
+
+ com.comphenix.protocol
+ ProtocolLib
+ 3.4.0
+ system
+ ${project.basedir}/libs/ProtocolLib-3.4.0.jar
+
+
+
+ com.comphenix.protocol
+ ProtocolLib
+ 4.4.0
+ provided
+
+
+
+ org.apache.commons
+ commons-lang3
+ 3.1
+ compile
+
+
+
+ org.apache.commons
+ commons-text
+ 1.8
+ compile
+
+
+
+ com.google.code.gson
+ gson
+ 2.8.5
+ compile
+
+
+
+
+ clean install
+
+
+
+ src/main/resources
+ true
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.6.1
+
+
+
+ 1.8
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.0.0
+
+ false
+ false
+
+
+
+ package
+
+ shade
+
+
+ ${project.artifactId}
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/me/missionary/board/BoardManager.java b/src/main/java/me/missionary/board/BoardManager.java
new file mode 100644
index 0000000..b92f843
--- /dev/null
+++ b/src/main/java/me/missionary/board/BoardManager.java
@@ -0,0 +1,90 @@
+package me.missionary.board;
+
+import me.missionary.board.board.Board;
+import me.missionary.board.board.tasks.BoardUpdateTask;
+import me.missionary.board.settings.BoardSettings;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerJoinEvent;
+import org.bukkit.event.player.PlayerQuitEvent;
+import org.bukkit.plugin.java.JavaPlugin;
+import org.bukkit.scheduler.BukkitTask;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @author Missionary (missionarymc@gmail.com)
+ * @since 3/23/2018
+ */
+public class BoardManager implements Listener {
+
+ private final JavaPlugin plugin;
+ private BoardSettings boardSettings;
+ private Map scoreboards;
+ private BukkitTask updateTask;
+
+ public BoardManager(JavaPlugin plugin, BoardSettings boardSettings) {
+ this.plugin = plugin;
+ this.boardSettings = boardSettings;
+ this.scoreboards = new ConcurrentHashMap<>();
+ this.updateTask = new BoardUpdateTask(this).runTaskTimer(plugin, 10L, 10L);
+ plugin.getServer().getPluginManager().registerEvents(this, plugin);
+ plugin.getServer().getOnlinePlayers().forEach(this::setup);
+ }
+
+ public void setBoardSettings(BoardSettings boardSettings) {
+ this.boardSettings = boardSettings;
+ scoreboards.values().forEach(board -> board.setBoardSettings(boardSettings));
+ }
+
+ public boolean hasBoard(Player player) {
+ return scoreboards.containsKey(player.getUniqueId());
+ }
+
+ public Optional getBoard(Player player) {
+ return Optional.ofNullable(scoreboards.get(player.getUniqueId()));
+ }
+
+ private void setup(Player player) {
+ Optional.ofNullable(scoreboards.remove(player.getUniqueId())).ifPresent(Board::resetScoreboard);
+ if (player.getScoreboard() == Bukkit.getScoreboardManager().getMainScoreboard()) {
+ player.setScoreboard(Bukkit.getScoreboardManager().getNewScoreboard());
+ }
+ scoreboards.put(player.getUniqueId(), new Board(player, boardSettings));
+ }
+
+ private void remove(Player player) {
+ Optional.ofNullable(scoreboards.remove(player.getUniqueId())).ifPresent(Board::remove);
+ }
+
+ public Map getScoreboards() {
+ return Collections.unmodifiableMap(scoreboards);
+ }
+
+ @EventHandler
+ public void onJoin(final PlayerJoinEvent e) {
+ plugin.getServer().getScheduler().runTaskLater(plugin, () -> {
+ if (e.getPlayer().isOnline()) { // Set this up 2 ticks later.
+ setup(e.getPlayer());
+ }
+ }, 2L);
+ }
+
+ @EventHandler
+ public void onQuit(final PlayerQuitEvent e) {
+ this.remove(e.getPlayer());
+ }
+
+ public void onDisable() {
+ updateTask.cancel();
+ plugin.getServer().getOnlinePlayers().forEach(this::remove);
+ scoreboards.clear();
+ }
+}
diff --git a/src/main/java/me/missionary/board/board/Board.java b/src/main/java/me/missionary/board/board/Board.java
new file mode 100644
index 0000000..30572b9
--- /dev/null
+++ b/src/main/java/me/missionary/board/board/Board.java
@@ -0,0 +1,131 @@
+package me.missionary.board.board;
+
+import lombok.NonNull;
+import lombok.Setter;
+import me.missionary.board.settings.BoardSettings;
+import me.missionary.board.settings.ScoreDirection;
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.entity.Player;
+import org.bukkit.scoreboard.DisplaySlot;
+import org.bukkit.scoreboard.Objective;
+import org.bukkit.scoreboard.Scoreboard;
+import org.bukkit.scoreboard.Team;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+/**
+ * @author Missionary (missionarymc@gmail.com)
+ * @since 3/23/2018
+ */
+public class Board {
+
+ private static final String[] CACHED_ENTRIES = new String[ChatColor.values().length];
+
+ private static final Function APPLY_COLOR_TRANSLATION = s -> ChatColor.translateAlternateColorCodes('&', s);
+
+ static {
+ IntStream.range(0, 15).forEach(i -> CACHED_ENTRIES[i] = ChatColor.values()[i].toString() + ChatColor.RESET);
+ }
+
+ private final Player player;
+ private final Objective objective;
+ private final Team team;
+ @Setter private BoardSettings boardSettings;
+ private boolean ready;
+
+ public Board(@NonNull final Player player, final BoardSettings boardSettings) {
+ this.player = player;
+ this.boardSettings = boardSettings;
+ this.objective = this.getScoreboard().getObjective("board") == null ? this.getScoreboard().registerNewObjective("board", "dummy") : this.getScoreboard().getObjective("board");
+ this.objective.setDisplaySlot(DisplaySlot.SIDEBAR);
+ this.team = this.getScoreboard().getTeam("board") == null ? this.getScoreboard().registerNewTeam("board") : this.getScoreboard().getTeam("board");
+ this.team.setAllowFriendlyFire(true);
+ this.team.setCanSeeFriendlyInvisibles(false);
+ this.team.setPrefix("");
+ this.team.setSuffix("");
+ this.ready = true;
+ }
+
+ public Scoreboard getScoreboard() {
+ return (player != null) ? player.getScoreboard() : null;
+ }
+
+ public void remove() {
+ this.resetScoreboard();
+ }
+
+ public void update() {
+ // Checking if we are ready to start updating the Scoreboard.
+ if (!ready) {
+ return;
+ }
+
+ // Making sure the player is connected.
+ if (!player.isOnline()) {
+ remove();
+ return;
+ }
+
+ // Making sure the Scoreboard Provider is set.
+ if (boardSettings == null) {
+ return;
+ }
+
+ // Getting their Scoreboard display from the Scoreboard Provider.
+ final List entries = boardSettings.getBoardProvider().getLines(player).stream().map(APPLY_COLOR_TRANSLATION).collect(Collectors.toList());
+
+ if (boardSettings.getScoreDirection() == ScoreDirection.UP) {
+ Collections.reverse(entries);
+ }
+
+ // Setting the Scoreboard title
+ String title = boardSettings.getBoardProvider().getTitle(player);
+ if (title.length() > 32) {
+ Bukkit.getLogger().warning("The title " + title + " is over 32 characters in length, substringing to prevent errors.");
+ title = title.substring(0, 32);
+ }
+ objective.setDisplayName(ChatColor.translateAlternateColorCodes('&', title));
+
+ // Clearing previous Scoreboard values if entry sizes don't match.
+ if (this.getScoreboard().getEntries().size() != entries.size())
+ this.getScoreboard().getEntries().forEach(this::removeEntry);
+
+ // Setting Scoreboard lines.
+ for (int i = 0; i < entries.size(); i++) {
+ String str = entries.get(i);
+ BoardEntry entry = BoardEntry.translateToEntry(str);
+ Team team = getScoreboard().getTeam(CACHED_ENTRIES[i]);
+
+ if (team == null) {
+ team = this.getScoreboard().registerNewTeam(CACHED_ENTRIES[i]);
+ team.addEntry(team.getName());
+ }
+
+ team.setPrefix(entry.getPrefix());
+ team.setSuffix(entry.getSuffix());
+
+ switch (boardSettings.getScoreDirection()) {
+ case UP:
+ objective.getScore(team.getName()).setScore(1 + i);
+ break;
+ case DOWN:
+ objective.getScore(team.getName()).setScore(15 - i);
+ break;
+ }
+ }
+ }
+
+ public void removeEntry(String id) {
+ this.getScoreboard().resetScores(id);
+ }
+
+ public void resetScoreboard() {
+ ready = false;
+ player.setScoreboard(Bukkit.getScoreboardManager().getMainScoreboard());
+ }
+}
diff --git a/src/main/java/me/missionary/board/board/BoardEntry.java b/src/main/java/me/missionary/board/board/BoardEntry.java
new file mode 100644
index 0000000..13cf06a
--- /dev/null
+++ b/src/main/java/me/missionary/board/board/BoardEntry.java
@@ -0,0 +1,40 @@
+package me.missionary.board.board;
+
+import lombok.Getter;
+import org.apache.commons.lang.StringUtils;
+import org.bukkit.ChatColor;
+
+/**
+ * @author Missionary (missionarymc@gmail.com)
+ * @since 3/29/2018
+ */
+public class BoardEntry {
+
+ @Getter
+ private final String prefix, suffix;
+
+ private BoardEntry(final String prefix, final String suffix) {
+ this.prefix = prefix;
+ this.suffix = suffix;
+ }
+
+ public static BoardEntry translateToEntry(String input) {
+ if (input.isEmpty()) {
+ return new BoardEntry("", "");
+ }
+ if (input.length() <= 16) {
+ return new BoardEntry(input, "");
+ } else {
+ String prefix = input.substring(0, 16);
+ String suffix = "";
+
+ if (prefix.endsWith("\u00a7")) {
+ prefix = prefix.substring(0, prefix.length() - 1);
+ suffix = "\u00a7" + suffix;
+ }
+
+ suffix = StringUtils.left(ChatColor.getLastColors(prefix) + suffix + input.substring(16), 16);
+ return new BoardEntry(prefix, suffix);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/me/missionary/board/board/tasks/BoardUpdateTask.java b/src/main/java/me/missionary/board/board/tasks/BoardUpdateTask.java
new file mode 100644
index 0000000..71dd5ed
--- /dev/null
+++ b/src/main/java/me/missionary/board/board/tasks/BoardUpdateTask.java
@@ -0,0 +1,26 @@
+package me.missionary.board.board.tasks;
+
+import lombok.RequiredArgsConstructor;
+import me.missionary.board.BoardManager;
+import org.bukkit.Bukkit;
+import org.bukkit.scheduler.BukkitRunnable;
+
+import java.util.UUID;
+import java.util.function.Predicate;
+
+/**
+ * @author Missionary (missionarymc@gmail.com)
+ * @since 5/31/2018
+ */
+@RequiredArgsConstructor
+public class BoardUpdateTask extends BukkitRunnable {
+
+ private static final Predicate PLAYER_IS_ONLINE = uuid -> Bukkit.getPlayer(uuid) != null;
+
+ private final BoardManager boardManager;
+
+ @Override
+ public void run() {
+ boardManager.getScoreboards().entrySet().stream().filter(entrySet -> PLAYER_IS_ONLINE.test(entrySet.getKey())).forEach(entrySet -> entrySet.getValue().update());
+ }
+}
diff --git a/src/main/java/me/missionary/board/provider/BoardProvider.java b/src/main/java/me/missionary/board/provider/BoardProvider.java
new file mode 100644
index 0000000..10b3534
--- /dev/null
+++ b/src/main/java/me/missionary/board/provider/BoardProvider.java
@@ -0,0 +1,26 @@
+package me.missionary.board.provider;
+
+import me.missionary.board.board.Board;
+import org.bukkit.entity.Player;
+import org.bukkit.scoreboard.Objective;
+
+import java.util.List;
+
+public interface BoardProvider {
+
+ /**
+ * Gets the title for {@link Objective#getDisplayName()}
+ *
+ * @param player The {@link Player} to supply
+ * @return The title for the objective
+ */
+ String getTitle(Player player);
+
+ /**
+ * Gets the contents to be displayed on the {@link Board}
+ *
+ * @param player The {@link Player} to supply
+ * @return The {@link List} of contents
+ */
+ List getLines(Player player);
+}
diff --git a/src/main/java/me/missionary/board/settings/BoardSettings.java b/src/main/java/me/missionary/board/settings/BoardSettings.java
new file mode 100644
index 0000000..6ccbbf5
--- /dev/null
+++ b/src/main/java/me/missionary/board/settings/BoardSettings.java
@@ -0,0 +1,19 @@
+package me.missionary.board.settings;
+
+import lombok.Builder;
+import lombok.Getter;
+import me.missionary.board.provider.BoardProvider;
+
+/**
+ * @author Missionary (missionarymc@gmail.com)
+ * @since 5/31/2018
+ */
+@Getter
+@Builder
+public class BoardSettings {
+
+ private BoardProvider boardProvider;
+
+ private ScoreDirection scoreDirection;
+
+}
diff --git a/src/main/java/me/missionary/board/settings/ScoreDirection.java b/src/main/java/me/missionary/board/settings/ScoreDirection.java
new file mode 100644
index 0000000..79e378b
--- /dev/null
+++ b/src/main/java/me/missionary/board/settings/ScoreDirection.java
@@ -0,0 +1,10 @@
+package me.missionary.board.settings;
+
+/**
+ * @author Missionary (missionarymc@gmail.com)
+ * @since 5/31/2018
+ */
+public enum ScoreDirection {
+ UP,
+ DOWN
+}
diff --git a/src/main/java/me/weebo/GameState.java b/src/main/java/me/weebo/GameState.java
new file mode 100644
index 0000000..82e35fd
--- /dev/null
+++ b/src/main/java/me/weebo/GameState.java
@@ -0,0 +1,10 @@
+package me.weebo;
+
+/*
+ * There are 3 game states.
+ */
+public enum GameState {
+
+ IDLE, WAITING, STARTED
+
+}
diff --git a/src/main/java/me/weebo/PotionSG.java b/src/main/java/me/weebo/PotionSG.java
new file mode 100644
index 0000000..556f72c
--- /dev/null
+++ b/src/main/java/me/weebo/PotionSG.java
@@ -0,0 +1,518 @@
+package me.weebo;
+
+import lombok.Getter;
+import lombok.Setter;
+import me.missionary.board.BoardManager;
+import me.missionary.board.settings.BoardSettings;
+import me.missionary.board.settings.ScoreDirection;
+import me.weebo.commands.staff.*;
+import org.bukkit.*;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.entity.Player;
+import org.bukkit.event.Listener;
+import org.bukkit.inventory.Recipe;
+import org.bukkit.plugin.java.JavaPlugin;
+import org.bukkit.potion.PotionEffect;
+import org.bukkit.potion.PotionEffectType;
+import org.bukkit.scheduler.BukkitRunnable;
+import me.weebo.barrier.ProtocolLibHook;
+import me.weebo.barrier.VisualiseHandler;
+import me.weebo.border.Border;
+import me.weebo.commands.GameInfoCommand;
+import me.weebo.commands.host.CancelCmd;
+import me.weebo.commands.host.HostCommand;
+import me.weebo.commands.host.StartCmd;
+import me.weebo.listeners.InventoryListener;
+import me.weebo.listeners.PlayerListeners;
+import me.weebo.listeners.WallBorderListener;
+import me.weebo.listeners.WorldListeners;
+import me.weebo.managers.Managers;
+import me.weebo.managers.scenarios.InventoryManager;
+import me.weebo.managers.scenarios.ScenarioManager;
+import me.weebo.managers.types.SidebarManager;
+import me.weebo.managers.types.TasksManager;
+import me.weebo.managers.types.UpdatedInventoryManager;
+import me.weebo.menu.MenuListener;
+import me.weebo.menu.Page;
+import me.weebo.utilities.C;
+import me.weebo.utilities.LocationUtils;
+import me.weebo.utilities.PlayerUtils;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+/*
+ * The main class of the plugin.
+ */
+public class PotionSG extends JavaPlugin {
+
+ public static final String PERM_ACCESS = "potionsg.access";
+ public static final String PERM_MOD = "potionsg.mod";
+ public static final String PERM_HOST = "potionsg.host";
+ public static final String PERM_BUILD = "potionsg.build";
+ public static final String PERM_ADMIN = "potionsg.admin";
+ public int port = Bukkit.getPort();
+ static PotionSG potsgscen;
+
+ @Getter
+ private static PotionSG inst;
+
+ @Getter
+ private GameState state;
+
+ @Getter
+ @Setter
+ private String host;
+
+ @Getter
+ private int startTimer, pvpTimer, feastTimer, rad, borderTimer, feastRad, cooldownTimer, targetRad, gameTimer;
+
+ @Getter
+ private boolean pvp;
+
+ @Getter
+ private VisualiseHandler visualiseHandler;
+ private BoardManager manager;
+
+ @Getter
+ String arena;
+
+ @Getter
+ TasksManager tasksManager;
+
+ @Getter
+ ScenarioManager scenarioManager;
+
+ @Getter
+ InventoryManager inventoryManager;
+
+ @Getter
+ Map playerMenu;
+
+ public static PotionSG getInstance() {
+ return potsgscen;
+ }
+
+ @Override
+ public void onEnable() {
+ //ProtocolLib
+ if(this.getServer().getPluginManager().getPlugin("ProtocolLib") == null) {
+ Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.RED + "ProtocolLib depend not found!");
+ Bukkit.shutdown();
+ //Registred ProtocolLib
+ } else {
+ Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.GREEN + "ProtocolLib found!");
+ }
+ //Multiverse-Core
+ if(this.getServer().getPluginManager().getPlugin("Multiverse-Core") == null) {
+ Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.RED + "Multiverse-Core depend not found!");
+ Bukkit.shutdown();
+ //Registered Multiverse
+ } else {
+ Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.GREEN + "Multiverse-Core found!");
+ }
+
+ //GameTask gametask;
+ //if(PotionSG.getInstance().isStarted()) {
+ //gametask = new GameTask();
+ //gametask.runTaskTimer(this, 0, 1 * 20);
+ //}
+ potsgscen = this;
+ inst = this;
+ state = GameState.IDLE;
+ arena = "";
+ scenarioManager = new ScenarioManager();
+ regEvents();
+ regCmds();
+ registerManagers();
+ getConfig().options().copyDefaults(true);
+ saveConfig();
+ manager = new BoardManager(this, BoardSettings.builder().boardProvider(new SidebarManager()).scoreDirection(ScoreDirection.UP).build());
+ visualiseHandler = new VisualiseHandler();
+ playerMenu = new ConcurrentHashMap();
+ new UpdatedInventoryManager();
+ Iterator it = Bukkit.getServer().recipeIterator();
+ while (it.hasNext()) {
+ Recipe rec = it.next();
+ if (rec.getResult().getType() == Material.CHEST || rec.getResult().getType() == Material.ENDER_CHEST || rec.getResult().getType() == Material.TRAPPED_CHEST)
+ it.remove();
+ }
+ for (Player p : Bukkit.getOnlinePlayers()) {
+ Managers.getProfileManager().createProfile(p);
+ PlayerUtils.lobbyItems(p);
+ }
+ ProtocolLibHook.hook();
+ Managers.getMapManager().loadArenas();
+ for (World w : Bukkit.getWorlds()) w.setDifficulty(Difficulty.NORMAL);
+ Bukkit.broadcastMessage(C.c("&a&l\u24D8 &aPotionSG has been enabled."));
+ //hostGame(Bukkit.getConsoleSender().getName());
+ }
+
+ @Override
+ public void onDisable() {
+ manager.onDisable();
+ for (Player p : Bukkit.getOnlinePlayers()) p.kickPlayer("PotionSG is reloading / restarting");
+ }
+
+ public void registerConfigs() {
+ saveDefaultConfig();
+
+ }
+ private void regEvents() {
+ List l = new ArrayList<>();
+ l.add(new PlayerListeners());
+ l.add(new WorldListeners());
+ l.add(new WallBorderListener());
+ l.add(new MenuListener());
+ l.add(new InventoryListener());
+ l.forEach(li -> Bukkit.getPluginManager().registerEvents(li, this));
+ }
+
+ private void regCmds() {
+ Map m = new HashMap<>();
+ m.put("build", new BuildCmd());
+ m.put("setlobbyspawn", new SetLobbySpawnCmd());
+ m.put("arena", new ArenaCmd());
+ m.put("cancel", new CancelCmd());
+ m.put("start", new StartCmd());
+ m.put("freeze", new FreezeCmd());
+ m.put("host", new HostCommand());
+ m.put("gameinfo", new GameInfoCommand());
+ m.put("setslots", new SetSlotsCommand());
+ m.forEach((s, c) -> getCommand(s).setExecutor(c));
+ }
+ private void registerManagers() {
+ scenarioManager = new ScenarioManager();
+ inventoryManager = new InventoryManager();
+ tasksManager = new TasksManager();
+ }
+
+
+ public List getPlayersInGame() {
+ List l = new ArrayList<>();
+ for (Player p : Bukkit.getOnlinePlayers())
+ if (Managers.getProfileManager().getProfile(p.getUniqueId()).isInGame()) l.add(p);
+ return l;
+ }
+
+
+ public List getPlayersWaiting() {
+ List l = new ArrayList<>();
+ for (Player p : Bukkit.getOnlinePlayers())
+ if (Managers.getProfileManager().getProfile(p.getUniqueId()).isWaiting()) l.add(p);
+ return l;
+ }
+
+
+ public List getSpectators() {
+ List l = new ArrayList<>();
+ for (Player p : Bukkit.getOnlinePlayers())
+ if (Managers.getProfileManager().getProfile(p.getUniqueId()).isSpectating()) l.add(p);
+ return l;
+ }
+
+
+ public void msgAll(String m) {
+ for (Player p : Bukkit.getOnlinePlayers()) C.c(p, m);
+ }
+
+ public void msg(String m) {
+ if (isStarted()) {
+ for (Player p : getPlayersInGame()) C.c(p, m);
+ for (Player p : getSpectators()) C.c(p, m);
+ } else if (isWaiting()) for (Player p : getPlayersWaiting()) C.c(p, m);
+ }
+
+ public void sound(Sound s, int v, int pi) {
+ if (isStarted()) {
+ for (Player p : getPlayersInGame()) p.playSound(p.getLocation(), s, v, pi);
+ for (Player p : getSpectators()) p.playSound(p.getLocation(), s, v, pi);
+ } else if (isWaiting()) for (Player p : getPlayersWaiting()) p.playSound(p.getLocation(), s, v, pi);
+ }
+
+ public void hide(Player player) {
+ if (isStarted()) for (Player p : getPlayersInGame()) p.hidePlayer(player);
+ else if (isWaiting()) for (Player p : getPlayersWaiting()) p.hidePlayer(player);
+ }
+
+
+ public void show(Player player) {
+ for (Player p : Bukkit.getOnlinePlayers()) p.showPlayer(player);
+ }
+
+ public void setWaiting() {
+ state = GameState.WAITING;
+ }
+
+ public void setStarted() {
+ state = GameState.STARTED;
+ }
+
+ public void setIdle() {
+ state = GameState.IDLE;
+ }
+
+ public boolean isStarted() {
+ return state == GameState.STARTED;
+ }
+
+ public boolean isIdle() {
+ return state == GameState.IDLE;
+ }
+
+ public boolean isWaiting() {
+ return state == GameState.WAITING;
+ }
+
+ public boolean isInCooldown() {
+ return state == GameState.IDLE && cooldownTimer > 0;
+ }
+
+
+ public void cancel(Player p) {
+ for (Player pl : getPlayersWaiting()) leaveGame(pl);
+ setIdle();
+ Bukkit.broadcastMessage(C.c("&7&m--------------------------------------------------"));
+ Bukkit.broadcastMessage(C.c("&c&l\u26A0 Game Cancelled"));
+ Bukkit.broadcastMessage("");
+ Bukkit.broadcastMessage(C.c("&7The game has been cancelled by " + p.getName() + "."));
+ Bukkit.broadcastMessage(C.c("&7&m--------------------------------------------------"));
+ for (Player pl : Bukkit.getOnlinePlayers()) pl.playSound(pl.getLocation(), Sound.ZOMBIE_UNFECT, 5, 2);
+ setHost(null);
+ arena = "";
+ }
+
+ public void start() {
+ setStarted();
+ rad = 500;
+ startTimer = 30;
+ pvpTimer = 0;
+ gameTimer = 0;
+ feastTimer = 0;
+ borderTimer = 0;
+ targetRad = 30;
+ pvp = false;
+ new Border();
+ for (Player p : getPlayersInGame()) PlayerUtils.reset(p);
+ msg("");
+ msg("&e\u26A0 &cFrom now on, you will not be able to join the game again if you leave.");
+ msg("");
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ if (isStarted() && startTimer >= 0) {
+ if (startTimer % 5 == 0 || startTimer <= 5) {
+ msg(startTimer > 0 ? C.CHAT_SECONDARY + "The game starts in " + C.MAIN + startTimer + C.CHAT_SECONDARY + "..." : "&aThe game has started.");
+ sound(startTimer > 0 ? Sound.CLICK : Sound.ZOMBIE_REMEDY, 5, 1);
+ }
+ if (startTimer == 0)
+ for (Player p : getPlayersInGame()) {
+ PlayerUtils.reset(p);
+ Location loc1 = LocationUtils.readGameSpawn().clone();
+ loc1.setPitch(p.getLocation().getPitch());
+ loc1.setYaw(p.getLocation().getYaw());
+ p.teleport(loc1);
+ p.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 600, 1));
+ }
+ startTimer--;
+ } else {
+ cancel();
+ if (isStarted()) startPvP();
+ if (isStarted()) startGameTimer();
+ }
+ }
+ }.runTaskTimer(PotionSG.getInst(), 0L, 20L);
+ }
+ public void startPvP() {
+ pvpTimer = 180;
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ if (isStarted() && pvpTimer >= 0) {
+ if (pvpTimer != 0 && pvpTimer % 60 == 0)
+ msg(C.CHAT_SECONDARY + "PvP will be enabled in " + C.MAIN + pvpTimer / 60 + (pvpTimer / 60 > 1 ? " minutes" : " minute") + C.CHAT_SECONDARY + "...");
+ else if (pvpTimer == 10 || pvpTimer <= 5)
+ msg(pvpTimer > 0 ? C.CHAT_SECONDARY + "PvP will be enabled in " + C.MAIN + pvpTimer + C.CHAT_SECONDARY + "..." : C.CHAT_SECONDARY + "PvP protection has expired!");
+ if (pvpTimer == 0) {
+ sound(Sound.FIREWORK_BLAST, 5, 1);
+ pvp = true;
+ }
+ pvpTimer--;
+ } else {
+ cancel();
+ if (isStarted()) startFeast();
+ }
+ }
+ }.runTaskTimer(PotionSG.getInst(), 0L, 20L);
+ }
+
+ public void startFeast() {
+ feastTimer = 420;
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ if (isStarted() && feastTimer >= 0) {
+ if (feastTimer != 0 && feastTimer % 60 == 0)
+ msg(C.CHAT_SECONDARY + "The feast will spawn at [0, 0] in " + C.MAIN + feastTimer / 60 + (feastTimer / 60 > 1 ? " minutes" : " minute") + C.CHAT_SECONDARY + "...");
+ else if (feastTimer == 10 || feastTimer <= 5)
+ msg(feastTimer > 0 ? C.CHAT_SECONDARY + "The feast will spawn at [0, 0] in " + C.MAIN + feastTimer + C.CHAT_SECONDARY + "..." : C.CHAT_SECONDARY + "The feast has spawned at [0, 0]!");
+ if (feastTimer == 0) {
+ feast();
+ sound(Sound.FIREWORK_BLAST, 5, 1);
+ }
+ feastTimer--;
+ } else {
+ cancel();
+ if (isStarted()) startBorder();
+ }
+ }
+ }.runTaskTimer(PotionSG.getInst(), 0L, 20L);
+ }
+
+ private void feast() {
+ feastRad = 10;
+ Location lo = LocationUtils.readGameSpawn();
+ int x1 = lo.getBlockX() + feastRad;
+ int z1 = lo.getBlockZ() + feastRad;
+ int x2 = lo.getBlockX() - feastRad;
+ int z2 = lo.getBlockZ() - feastRad;
+ int y = lo.getBlockY();
+ World w = lo.getWorld();
+ Location[] loc = new Location[]{
+ new Location(w, x1 - 2, y, z1),
+ new Location(w, x1, y, z1 - 2),
+ new Location(w, x2 + 2, y, z1),
+ new Location(w, x2, y, z1 - 2),
+ new Location(w, x1 - 2, y, z2),
+ new Location(w, x1, y, z2 + 2),
+ new Location(w, x2 + 2, y, z2),
+ new Location(w, x2, y, z2 + 2)};
+ Location[] loc2 = new Location[]{
+ new Location(w, lo.getX() - 2, y, lo.getZ()),
+ new Location(w, lo.getX(), y, lo.getZ() - 2),
+ new Location(w, lo.getX(), y, lo.getZ() + 2),
+ new Location(w, lo.getX() + 2, y, lo.getZ())};
+ w.getBlockAt(lo).setType(Material.ENCHANTMENT_TABLE);
+ for (Location l : loc) w.getBlockAt(l).setType(Material.ENDER_CHEST);
+ for (Location l : loc2) w.getBlockAt(l).setType(Material.BOOKSHELF);
+ }
+ public void startGameTimer() {
+ gameTimer = 0;
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ gameTimer++;
+ }
+ }.runTaskTimer(this, 0L, 20L);
+ }
+
+
+ public void startBorder() {
+ msg(C.CHAT_SECONDARY + "The border will be shrinking by " + C.MAIN + "50 blocks" + C.CHAT_SECONDARY + " every minute.");
+ sound(Sound.WITHER_IDLE, 5, 1);
+ borderTimer = 60;
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ if (isStarted() && rad > targetRad) {
+ if (borderTimer == 0) {
+ rad -= (rad == 50 ? 20 : 50);
+ borderTimer = 60;
+ }
+ borderTimer--;
+ } else cancel();
+ }
+ }.runTaskTimer(PotionSG.getInst(), 0L, 20L);
+ }
+
+ public void check() {
+ if (getPlayersInGame().size() == 1) {
+ for (Player p : getSpectators()) stopSpectating(p, false);
+ Bukkit.broadcastMessage(C.c("&7&m--------------------------------------------------"));
+ Bukkit.broadcastMessage(C.c(C.MAIN + "&l\u26A0 Game Ended"));
+ Bukkit.broadcastMessage("");
+ Bukkit.broadcastMessage(C.c("&6" + getPlayersInGame().get(0).getName() + " has won the game!"));
+ Bukkit.broadcastMessage(C.c("&7&m--------------------------------------------------"));
+ for (Player p : getPlayersInGame()) {
+ Managers.getPearlManager().removePearlCooldown(p, false);
+ leaveGame(p);
+ Managers.getLeaderboardManager().addWin(p.getUniqueId());
+ }
+ for (Player pl : Bukkit.getOnlinePlayers()) pl.playSound(pl.getLocation(), Sound.LEVEL_UP, 5, 1);
+ Bukkit.broadcastMessage(C.c("&eThe world is going to be reset so... expect lag."));
+ Managers.getMapManager().resetMap(LocationUtils.readGameSpawn());
+ arena = "";
+ setIdle();
+ startCooldown();
+ }
+ }
+
+ public void leaveGame(Player p) {
+ Managers.getProfileManager().getProfile(p.getUniqueId()).setInLobby();
+ p.teleport(LocationUtils.readLobbySpawn());
+ PlayerUtils.lobbyItems(p);
+ }
+
+ public void spectate(Player p, boolean b) {
+ hide(p);
+ p.teleport(LocationUtils.readGameSpawn());
+ PlayerUtils.spectateItems(p);
+ p.setGameMode(GameMode.CREATIVE);
+ Managers.getProfileManager().getProfile(p.getUniqueId()).setSpectating();
+ if (b) msg(C.MAIN + p.getName() + C.CHAT_SECONDARY + " is now spectating.");
+ }
+
+ public void stopSpectating(Player p, boolean b) {
+ if (b) msg(C.MAIN + p.getName() + C.CHAT_SECONDARY + " is no longer spectating.");
+ p.setGameMode(GameMode.SURVIVAL);
+ Managers.getProfileManager().getProfile(p.getUniqueId()).setInLobby();
+ p.teleport(LocationUtils.readLobbySpawn());
+ show(p);
+ PlayerUtils.lobbyItems(p);
+ }
+
+ public void startCooldown() {
+ cooldownTimer = 60;
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ if (cooldownTimer == 0) {
+ hostGame(Bukkit.getConsoleSender().getName());
+ cancel();
+ }
+ cooldownTimer--;
+ }
+ }.runTaskTimer(this, 0L, 20L);
+ }
+
+
+ public void hostGame(String host) {
+ Bukkit.broadcastMessage(C.c("&7&m--------------------------------------------------"));
+ Bukkit.broadcastMessage(C.c(C.MAIN + "&l\u24D8 New PotionSG Game"));
+ Bukkit.broadcastMessage("");
+ Bukkit.broadcastMessage(C.c("&7A new game has been hosted by " + host + "."));
+ Bukkit.broadcastMessage(C.c("&7&m--------------------------------------------------"));
+ for (Player pl : Bukkit.getOnlinePlayers()) pl.playSound(pl.getLocation(), Sound.ZOMBIE_METAL, 5, 1);
+ setHost(host);
+ arena = Managers.getMapManager().getArenas().get(new Random().nextInt(Managers.getMapManager().getArenas().size()));
+ setWaiting();
+ }
+
+ public Location getBorderLocation2() {
+ return new Location(LocationUtils.readGameSpawn().getWorld(), LocationUtils.readGameSpawn().getX() + rad, 0, LocationUtils.readGameSpawn().getZ() + rad);
+ }
+
+ public Location getBorderLocation1() {
+ return new Location(LocationUtils.readGameSpawn().getWorld(), LocationUtils.readGameSpawn().getX() - rad, 0, LocationUtils.readGameSpawn().getZ() - rad);
+ }
+
+ public void join(Player p) {
+ Managers.getProfileManager().getProfile(p.getUniqueId()).setInGame();
+ PlayerUtils.waitingItems(p);
+ p.teleport(LocationUtils.readGameSpawn());
+ p.playSound(p.getLocation(), Sound.NOTE_PLING, 5, 1);
+ PotionSG.getInst().msgAll(C.MAIN + p.getName() + C.CHAT_SECONDARY + " joined the game.");
+ p.setGameMode(GameMode.CREATIVE);
+ Managers.getHostManager().check();
+ }
+}
diff --git a/src/main/java/me/weebo/barrier/BlockFiller.java b/src/main/java/me/weebo/barrier/BlockFiller.java
new file mode 100644
index 0000000..2d74d0f
--- /dev/null
+++ b/src/main/java/me/weebo/barrier/BlockFiller.java
@@ -0,0 +1,25 @@
+package me.weebo.barrier;
+
+import com.google.common.collect.Iterables;
+import org.bukkit.Location;
+import org.bukkit.World;
+import org.bukkit.entity.Player;
+
+import java.util.ArrayList;
+
+abstract class BlockFiller {
+ @Deprecated
+ VisualBlockData generate(Player player, World world, int x, int y, int z) {
+ return generate(player, new Location(world, x, y, z));
+ }
+
+ abstract VisualBlockData generate(Player paramPlayer, Location paramLocation);
+
+ ArrayList bulkGenerate(Player player, Iterable locations) {
+ ArrayList data = new ArrayList<>(Iterables.size(locations));
+ for (Location location : locations) {
+ data.add(generate(player, location));
+ }
+ return data;
+ }
+}
diff --git a/src/main/java/me/weebo/barrier/ProtocolLibHook.java b/src/main/java/me/weebo/barrier/ProtocolLibHook.java
new file mode 100644
index 0000000..6612841
--- /dev/null
+++ b/src/main/java/me/weebo/barrier/ProtocolLibHook.java
@@ -0,0 +1,130 @@
+package me.weebo.barrier;
+
+import me.weebo.PotionSG;
+import org.bukkit.GameMode;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.scheduler.BukkitRunnable;
+
+import com.comphenix.protocol.PacketType;
+import com.comphenix.protocol.PacketType.Play.Client;
+import com.comphenix.protocol.ProtocolLibrary;
+import com.comphenix.protocol.ProtocolManager;
+import com.comphenix.protocol.events.ListenerPriority;
+import com.comphenix.protocol.events.PacketAdapter;
+import com.comphenix.protocol.events.PacketContainer;
+import com.comphenix.protocol.events.PacketEvent;
+import com.comphenix.protocol.reflect.FieldAccessException;
+import com.comphenix.protocol.reflect.StructureModifier;
+
+import net.minecraft.server.v1_7_R4.EntityPlayer;
+
+public class ProtocolLibHook {
+ public static void hook() {
+ ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
+ protocolManager.addPacketListener(new PacketAdapter(PotionSG.getInst(), ListenerPriority.NORMAL, new PacketType[]{Client.BLOCK_PLACE}) {
+ @SuppressWarnings("deprecation")
+ public void onPacketReceiving(PacketEvent event) {
+ PacketContainer packet = event.getPacket();
+ StructureModifier modifier = packet.getIntegers();
+ final Player player = event.getPlayer();
+ try {
+ if ((modifier.size() < 4) || (((Integer) modifier.read(3)).intValue() == 255)) {
+ return;
+ }
+ int face2 = 0;
+ final Location location = new Location(player.getWorld(), ((Integer) modifier.read(0)).intValue(), ((Integer) modifier.read(1)).intValue(), ((Integer) modifier.read(2)).intValue());
+ VisualBlock visualBlock = PotionSG.getInst().getVisualiseHandler().getVisualBlockAt(player, location);
+ if (visualBlock == null) {
+ return;
+ }
+ switch (face2) {
+ case 0:
+ location.add(0.0D, -1.0D, 0.0D);
+ break;
+ case 1:
+ location.add(0.0D, 1.0D, 0.0D);
+ break;
+ case 2:
+ location.add(0.0D, 0.0D, -1.0D);
+ break;
+ case 3:
+ location.add(0.0D, 0.0D, 1.0D);
+ break;
+ case 4:
+ location.add(-1.0D, 0.0D, 0.0D);
+ break;
+ case 5:
+ location.add(1.0D, 0.0D, 0.0D);
+ break;
+ default:
+ return;
+ }
+ event.setCancelled(true);
+ ItemStack stack = (ItemStack) packet.getItemModifier().read(0);
+ if ((stack != null) && ((stack.getType().isBlock()) || (ProtocolLibHook.isLiquidSource(stack.getType())))) {
+ player.setItemInHand(player.getItemInHand());
+ }
+ visualBlock = PotionSG.getInst().getVisualiseHandler().getVisualBlockAt(player, location);
+ if (visualBlock != null) {
+ VisualBlockData visualBlockData = visualBlock.getBlockData();
+ player.sendBlockChange(location, visualBlockData.getBlockType(), visualBlockData.getData());
+ } else {
+ new BukkitRunnable() {
+ public void run() {
+ org.bukkit.block.Block block = location.getBlock();
+ player.sendBlockChange(location, block.getType(), block.getData());
+ }
+ }.runTask(PotionSG.getInst());
+ }
+ } catch (FieldAccessException localFieldAccessException) {
+ }
+ }
+ });
+ protocolManager.addPacketListener(new PacketAdapter(PotionSG.getInst(), ListenerPriority.NORMAL, new PacketType[]{Client.BLOCK_DIG}) {
+ @SuppressWarnings("deprecation")
+ public void onPacketReceiving(PacketEvent event) {
+ PacketContainer packet = event.getPacket();
+ StructureModifier modifier = packet.getIntegers();
+ Player player = event.getPlayer();
+ try {
+ int status = ((Integer) modifier.read(4)).intValue();
+ if ((status == 0) || (status == 2)) {
+ int x = ((Integer) modifier.read(0)).intValue();
+ int y = ((Integer) modifier.read(1)).intValue();
+ int z = ((Integer) modifier.read(2)).intValue();
+ Location location = new Location(player.getWorld(), x, y, z);
+ VisualBlock visualBlock = PotionSG.getInst().getVisualiseHandler().getVisualBlockAt(player, location);
+ if (visualBlock == null) {
+ return;
+ }
+ event.setCancelled(true);
+ VisualBlockData data = visualBlock.getBlockData();
+ if (status == 2) {
+ player.sendBlockChange(location, data.getBlockType(), data.getData());
+ } else if (status == 0) {
+ EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
+ if ((player.getGameMode() == GameMode.CREATIVE) || (net.minecraft.server.v1_7_R4.Block.getById(data.getItemTypeId()).getDamage(entityPlayer, entityPlayer.world, x, y, z) > 1.0F)) {
+ player.sendBlockChange(location, data.getBlockType(), data.getData());
+ }
+ }
+ }
+ } catch (FieldAccessException localFieldAccessException) {
+ }
+ }
+ });
+ }
+
+ @SuppressWarnings("incomplete-switch")
+ private static boolean isLiquidSource(Material material) {
+ switch (material) {
+ case RED_ROSE:
+ case WORKBENCH:
+ return true;
+ }
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/me/weebo/barrier/VisualBlock.java b/src/main/java/me/weebo/barrier/VisualBlock.java
new file mode 100644
index 0000000..06a6f01
--- /dev/null
+++ b/src/main/java/me/weebo/barrier/VisualBlock.java
@@ -0,0 +1,27 @@
+package me.weebo.barrier;
+
+import org.bukkit.Location;
+
+public class VisualBlock {
+ private VisualType visualType;
+ private VisualBlockData blockData;
+ private Location location;
+
+ public VisualBlock(VisualType visualType, VisualBlockData blockData, Location location) {
+ this.visualType = visualType;
+ this.blockData = blockData;
+ this.location = location;
+ }
+
+ public VisualType getVisualType() {
+ return this.visualType;
+ }
+
+ public VisualBlockData getBlockData() {
+ return this.blockData;
+ }
+
+ public Location getLocation() {
+ return this.location;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/me/weebo/barrier/VisualBlockData.java b/src/main/java/me/weebo/barrier/VisualBlockData.java
new file mode 100644
index 0000000..edb9f6d
--- /dev/null
+++ b/src/main/java/me/weebo/barrier/VisualBlockData.java
@@ -0,0 +1,36 @@
+package me.weebo.barrier;
+
+import org.bukkit.Material;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.material.MaterialData;
+
+public class VisualBlockData
+ extends MaterialData {
+ public VisualBlockData(Material type) {
+ super(type);
+ }
+
+ @SuppressWarnings("deprecation")
+ public VisualBlockData(Material type, byte data) {
+ super(type, data);
+ }
+
+ public Material getBlockType() {
+ return getItemType();
+ }
+
+ @Deprecated
+ public Material getItemType() {
+ return super.getItemType();
+ }
+
+ @Deprecated
+ public ItemStack toItemStack() {
+ throw new UnsupportedOperationException("This is a VisualBlock data");
+ }
+
+ @Deprecated
+ public ItemStack toItemStack(int amount) {
+ throw new UnsupportedOperationException("This is a VisualBlock data");
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/me/weebo/barrier/VisualType.java b/src/main/java/me/weebo/barrier/VisualType.java
new file mode 100644
index 0000000..4e0644d
--- /dev/null
+++ b/src/main/java/me/weebo/barrier/VisualType.java
@@ -0,0 +1,25 @@
+package me.weebo.barrier;
+
+import org.bukkit.DyeColor;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+
+public enum VisualType {
+
+ WORLD_BORDER() {
+ private final BlockFiller blockFiller = new BlockFiller() {
+ @SuppressWarnings("deprecation")
+ @Override
+ VisualBlockData generate(Player player, Location location) {
+ return new VisualBlockData(Material.STAINED_GLASS, DyeColor.PINK.getData());
+ }
+ };
+ @Override
+ BlockFiller blockFiller() {
+ return blockFiller;
+ }
+ };
+
+ abstract BlockFiller blockFiller();
+}
\ No newline at end of file
diff --git a/src/main/java/me/weebo/barrier/VisualiseHandler.java b/src/main/java/me/weebo/barrier/VisualiseHandler.java
new file mode 100644
index 0000000..562e473
--- /dev/null
+++ b/src/main/java/me/weebo/barrier/VisualiseHandler.java
@@ -0,0 +1,253 @@
+package me.weebo.barrier;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.collect.HashBasedTable;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Table;
+import me.weebo.cuboid.Cuboid;
+import org.bukkit.Chunk;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.World;
+import org.bukkit.block.Block;
+import org.bukkit.craftbukkit.v1_7_R4.CraftChunk;
+import org.bukkit.craftbukkit.v1_7_R4.util.CraftMagicNumbers;
+import org.bukkit.entity.Player;
+
+import javax.annotation.Nullable;
+import java.util.*;
+
+public class VisualiseHandler {
+
+ private final Table storedVisualises = HashBasedTable.create();
+
+ public Table getStoredVisualises() {
+ return storedVisualises;
+ }
+
+ @Deprecated
+ public VisualBlock getVisualBlockAt(Player player, int x, int y, int z) throws NullPointerException {
+ return this.getVisualBlockAt(player, new Location(player.getWorld(), x, y, z));
+ }
+
+ /**
+ * Gets a {@link VisualBlock} for a {@link Player}.
+ *
+ * @param player the {@link Player} to get for
+ * @param location the {@link Location} to get at
+ * @return the {@link VisualBlock} or none
+ * @throws NullPointerException if player or location is null
+ */
+ public VisualBlock getVisualBlockAt(Player player, Location location) throws NullPointerException {
+ Preconditions.checkNotNull(player, "Player cannot be null");
+ Preconditions.checkNotNull(location, "Location cannot be null");
+ synchronized (storedVisualises) {
+ return storedVisualises.get(player.getUniqueId(), location);
+ }
+ }
+
+ /**
+ * Gets the current {@link VisualBlock}s to their {@link Location}s that are shown to a {@link Player} of a specific {@link VisualType}.
+ *
+ * @param player the {@link Player} to get for
+ * @return copied map of {@link VisualBlock}s shown to a {@link Player}.
+ */
+ public Map getVisualBlocks(Player player) {
+ synchronized (storedVisualises) {
+ return new HashMap<>(storedVisualises.row(player.getUniqueId()));
+ }
+ }
+
+ /**
+ * Gets the current {@link VisualBlock}s to their {@link Location}s that are shown to a {@link Player} of a specific {@link VisualType}.
+ *
+ * @param player the {@link Player} to get for
+ * @param visualType the {@link VisualType} to get for
+ * @return copied map of {@link VisualBlock}s shown to a {@link Player}.
+ */
+ public Map getVisualBlocks(Player player, VisualType visualType) {
+ return Maps.filterValues(this.getVisualBlocks(player), new Predicate() {
+ @Override
+ public boolean apply(VisualBlock visualBlock) {
+ return visualType == visualBlock.getVisualType();
+ }
+ });
+ }
+
+ public LinkedHashMap generate(Player player, Cuboid cuboid, VisualType visualType, boolean canOverwrite) {
+ Collection locations = new HashSet<>(cuboid.getSizeX() * cuboid.getSizeY() * cuboid.getSizeZ());
+ Iterator iterator = cuboid.locationIterator();
+ while (iterator.hasNext()) {
+ locations.add(iterator.next());
+ }
+
+ return this.generate(player, locations, visualType, canOverwrite);
+ }
+
+ public LinkedHashMap generateAsync(Player player, Cuboid cuboid, VisualType visualType, boolean canOverwrite) {
+ Collection locations = new HashSet<>(cuboid.getSizeX() * cuboid.getSizeY() * cuboid.getSizeZ());
+ Iterator iterator = cuboid.locationIterator();
+ while (iterator.hasNext()) {
+ locations.add(iterator.next());
+ }
+
+ return this.generateAsync(player, locations, visualType, canOverwrite);
+ }
+
+ @SuppressWarnings("deprecation")
+ public LinkedHashMap generate(Player player, Iterable locations, VisualType visualType, boolean canOverwrite) {
+ synchronized (storedVisualises) {
+ LinkedHashMap results = new LinkedHashMap<>();
+
+ ArrayList filled = visualType.blockFiller().bulkGenerate(player, locations);
+ if (filled != null) {
+ int count = 0;
+ for (Location location : locations) {
+ if (!canOverwrite && storedVisualises.contains(player.getUniqueId(), location)) {
+ continue;
+ }
+
+ Material previousType = location.getBlock().getType();
+ if (previousType.isSolid() || previousType != Material.AIR) {
+ continue;
+ }
+
+ VisualBlockData visualBlockData = filled.get(count++);
+ results.put(location, visualBlockData);
+ player.sendBlockChange(location, visualBlockData.getBlockType(), visualBlockData.getData());
+ storedVisualises.put(player.getUniqueId(), location, new VisualBlock(visualType, visualBlockData, location));
+ }
+ }
+
+ return results;
+ }
+ }
+
+ public LinkedHashMap generateAsync(Player player, Iterable locations, VisualType visualType, boolean canOverwrite) {
+ synchronized (storedVisualises) {
+ LinkedHashMap results = new LinkedHashMap<>();
+
+ ArrayList filled = visualType.blockFiller().bulkGenerate(player, locations);
+ if (filled != null) {
+ for (Location location : locations) {
+ if (!canOverwrite && storedVisualises.contains(player.getUniqueId(), location)) {
+ continue;
+ }
+
+ location.getWorld().getChunkAtAsync(location, new World.ChunkLoadCallback() {
+ int count = 0;
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public void onLoad(Chunk chunk) {
+ Material previousType = CraftMagicNumbers.getMaterial(((CraftChunk) chunk).getHandle().getType(location.getBlockX(), location.getBlockY(), location.getBlockZ()));
+ if (previousType.isSolid() || previousType != Material.AIR) {
+ return;
+ }
+
+ VisualBlockData visualBlockData = filled.get(count++);
+ results.put(location, visualBlockData);
+ player.sendBlockChange(location, visualBlockData.getBlockType(), visualBlockData.getData());
+ storedVisualises.put(player.getUniqueId(), location, new VisualBlock(visualType, visualBlockData, location));
+ }
+ });
+ }
+ }
+
+ return results;
+ }
+ }
+
+ /**
+ * Clears a visual block at a given location for a player.
+ *
+ * @param player the player to clear for
+ * @param location the location to clear at
+ * @return if the visual block was shown in the first place
+ */
+ public boolean clearVisualBlock(Player player, Location location) {
+ return this.clearVisualBlock(player, location, true);
+ }
+
+ /**
+ * Clears a visual block at a given location for a player.
+ *
+ * @param player the player to clear for
+ * @param location the location to clear at
+ * @param sendRemovalPacket if a packet to send a block change should be sent (this is used to prevent unnecessary packets sent when disconnecting or changing worlds, for example)
+ * @return if the visual block was shown in the first place
+ */
+ @SuppressWarnings("deprecation")
+ public boolean clearVisualBlock(Player player, Location location, boolean sendRemovalPacket) {
+ synchronized (storedVisualises) {
+ VisualBlock visualBlock = this.storedVisualises.remove(player.getUniqueId(), location);
+ if (sendRemovalPacket && visualBlock != null) {
+ // Have to send a packet to the original block type, don't send if the fake block has the same data properties though.
+ Block block = location.getBlock();
+ VisualBlockData visualBlockData = visualBlock.getBlockData();
+ if (visualBlockData.getBlockType() != block.getType() || visualBlockData.getData() != block.getData()) {
+ player.sendBlockChange(location, block.getType(), block.getData());
+ }
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Clears all visual blocks that are shown to a player.
+ *
+ * @param player the player to clear for
+ * @return mapping of the removed visualises
+ */
+ public Map clearVisualBlocks(Player player) {
+ return this.clearVisualBlocks(player, null, null);
+ }
+
+ /**
+ * Clears all visual blocks that are shown to a player of a given VisualType.
+ *
+ * @param player the player to clear for
+ * @param visualType the visual type
+ * @param predicate the predicate to filter to
+ * @return mapping of the removed visualises
+ */
+ public Map clearVisualBlocks(Player player, @Nullable VisualType visualType, @Nullable Predicate predicate) {
+ return this.clearVisualBlocks(player, visualType, predicate, true);
+ }
+
+ /**
+ * Clears all visual blocks that are shown to a player of a given VisualType.
+ *
+ * @param player the player to clear for
+ * @param visualType the visual type
+ * @param predicate the predicate to filter to
+ * @param sendRemovalPackets if a packet to send a block change should be sent (this is used to prevent unnecessary packets sent when disconnecting or changing worlds, for example)
+ * @return mapping of the removed visualises
+ */
+ @Deprecated
+ public Map clearVisualBlocks(Player player, @Nullable VisualType visualType, @Nullable Predicate predicate, boolean sendRemovalPackets) {
+
+ synchronized (storedVisualises) {
+ if (!this.storedVisualises.containsRow(player.getUniqueId()))
+ return Collections.emptyMap();
+ Map results = new HashMap<>(this.storedVisualises.row(player.getUniqueId())); // copy to prevent commodification
+ Map removed = new HashMap<>();
+ for (Map.Entry entry : results.entrySet()) {
+ VisualBlock visualBlock = entry.getValue();
+
+ if ((predicate == null || predicate.apply(visualBlock)) && (visualType == null || visualBlock.getVisualType() == visualType)) {
+ Location location = entry.getKey();
+ if (removed.put(location, visualBlock) == null) { // not really necessary, but might as well
+ this.clearVisualBlock(player, location, sendRemovalPackets); // this will call remove on storedVisualises.
+ }
+ }
+ }
+
+ return removed;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/me/weebo/border/Border.java b/src/main/java/me/weebo/border/Border.java
new file mode 100644
index 0000000..41e1582
--- /dev/null
+++ b/src/main/java/me/weebo/border/Border.java
@@ -0,0 +1,51 @@
+package me.weebo.border;
+
+import java.util.List;
+
+import me.weebo.PotionSG;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.scheduler.BukkitRunnable;
+
+import me.weebo.utilities.C;
+import me.weebo.utilities.LocationUtils;
+
+public class Border extends BukkitRunnable {
+
+ public Border() {
+ runTaskTimer(PotionSG.getInst(), 0L, 5L);
+ }
+
+ @Override
+ public void run() {
+ if (PotionSG.getInst().isStarted()) {
+ List list = PotionSG.getInst().getPlayersInGame();
+ list.addAll(PotionSG.getInst().getSpectators());
+ for (Player p : list) {
+ if (PotionSG.getInst().getArena() != null) {
+ if (p.getWorld().equals(LocationUtils.readGameSpawn().getWorld())) {
+ Location loc = p.getLocation().clone();
+ if (p.getLocation().getX() < PotionSG.getInst().getBorderLocation1().getX()) loc.setX(PotionSG.getInst().getBorderLocation1().getX() + 2);
+ if (p.getLocation().getX() > PotionSG.getInst().getBorderLocation2().getX()) loc.setX(PotionSG.getInst().getBorderLocation2().getX() - 2);
+ if (p.getLocation().getZ() < PotionSG.getInst().getBorderLocation1().getZ()) loc.setZ(PotionSG.getInst().getBorderLocation1().getZ() + 2);
+ if (p.getLocation().getZ() > PotionSG.getInst().getBorderLocation2().getZ()) loc.setZ(PotionSG.getInst().getBorderLocation2().getZ() - 2);
+ if (!p.getLocation().equals(loc)) {
+ loc.setY(getHighestBlockYAt(loc));
+ p.teleport(loc);
+ C.c(p, "&e\u26A0 &cYou have reached the edge of the world.");
+ }
+ }
+ }
+ }
+ } else cancel();
+ }
+
+ public int getHighestBlockYAt(Location loc) {
+ for (int y = 0; y < 256; y++) {
+ Material m = loc.getWorld().getBlockAt(loc.getBlockX(), y, loc.getBlockZ()).getType();
+ if (m == Material.AIR || m == Material.LONG_GRASS) return y;
+ }
+ return 0;
+ }
+}
diff --git a/src/main/java/me/weebo/commands/GameInfoCommand.java b/src/main/java/me/weebo/commands/GameInfoCommand.java
new file mode 100644
index 0000000..5159663
--- /dev/null
+++ b/src/main/java/me/weebo/commands/GameInfoCommand.java
@@ -0,0 +1,20 @@
+package me.weebo.commands;
+
+import me.weebo.PotionSG;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public class GameInfoCommand implements CommandExecutor {
+
+ @Override
+ public boolean onCommand(CommandSender s, Command cmd, String label, String[] arg) {
+ if (s instanceof Player) {
+ Player p = (Player) s;
+ PotionSG.getInst().getInventoryManager().createScen(p, 2);
+ }
+ return true;
+ }
+
+}
diff --git a/src/main/java/me/weebo/commands/host/CancelCmd.java b/src/main/java/me/weebo/commands/host/CancelCmd.java
new file mode 100644
index 0000000..d5b8732
--- /dev/null
+++ b/src/main/java/me/weebo/commands/host/CancelCmd.java
@@ -0,0 +1,28 @@
+package me.weebo.commands.host;
+
+import me.weebo.PotionSG;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import me.weebo.utilities.C;
+
+public class CancelCmd implements CommandExecutor {
+
+ @Override
+ public boolean onCommand(CommandSender s, Command cmd, String label, String[] arg) {
+ if (s instanceof Player) {
+ Player p = (Player) s;
+ if (p.hasPermission(PotionSG.PERM_HOST) || p.hasPermission(PotionSG.PERM_MOD) || p.hasPermission(PotionSG.PERM_ACCESS)) {
+ if (p.getName().equalsIgnoreCase(PotionSG.getInst().getHost())) {
+ if (PotionSG.getInst().isWaiting()) PotionSG.getInst().cancel(p);
+ else if (PotionSG.getInst().isStarted()) C.c(p, "&cThe game has already started!");
+ else C.c(p, "&cThere is no game available.");
+ } else C.c(p, "&cYou cannot cancel the game as you are not the host.");
+ } else C.c(p, "&cYou do not have permissions to cancel events.");
+ }
+ return true;
+ }
+
+}
diff --git a/src/main/java/me/weebo/commands/host/HostCommand.java b/src/main/java/me/weebo/commands/host/HostCommand.java
new file mode 100644
index 0000000..6e6ae50
--- /dev/null
+++ b/src/main/java/me/weebo/commands/host/HostCommand.java
@@ -0,0 +1,24 @@
+package me.weebo.commands.host;
+
+import me.weebo.PotionSG;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public class HostCommand implements CommandExecutor {
+
+ @Override
+ public boolean onCommand(CommandSender s, Command cmd, String label, String[] arg) {
+ if (s instanceof Player) {
+ Player p = (Player) s;
+ if (p.hasPermission(PotionSG.PERM_MOD) || p.hasPermission(PotionSG.PERM_ACCESS)) {
+ PotionSG.getInst().getInventoryManager().createScen(p, 1);
+ } else {
+ p.sendMessage("No Permissions!");
+ }
+ }
+ return true;
+ }
+
+}
diff --git a/src/main/java/me/weebo/commands/host/StartCmd.java b/src/main/java/me/weebo/commands/host/StartCmd.java
new file mode 100644
index 0000000..84ec954
--- /dev/null
+++ b/src/main/java/me/weebo/commands/host/StartCmd.java
@@ -0,0 +1,30 @@
+package me.weebo.commands.host;
+
+import me.weebo.PotionSG;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import me.weebo.utilities.C;
+
+public class StartCmd implements CommandExecutor {
+
+ @Override
+ public boolean onCommand(CommandSender s, Command cmd, String label, String[] arg) {
+ if (s instanceof Player) {
+ Player p = (Player) s;
+ if (p.hasPermission(PotionSG.PERM_HOST) || p.hasPermission(PotionSG.PERM_MOD) || p.hasPermission(PotionSG.PERM_ACCESS)) {
+ if (p.getName().equalsIgnoreCase(PotionSG.getInst().getHost())) {
+ if (PotionSG.getInst().isWaiting()) {
+ if (PotionSG.getInst().getPlayersWaiting().size() > 1) PotionSG.getInst().start();
+ else C.c(p, "&cThere must be at least 2 players joined to start the game.");
+ } else if (PotionSG.getInst().isStarted()) C.c(p, "&e\u26A0 &cThe game has already started!");
+ else C.c(p, "&cThere is no game available.");
+ } else C.c(p, "&cYou cannot start the game as you are not the host.");
+ } else C.c(p, "&cYou do not have permissions to start events.");
+ }
+ return true;
+ }
+
+}
diff --git a/src/main/java/me/weebo/commands/staff/ArenaCmd.java b/src/main/java/me/weebo/commands/staff/ArenaCmd.java
new file mode 100644
index 0000000..797de90
--- /dev/null
+++ b/src/main/java/me/weebo/commands/staff/ArenaCmd.java
@@ -0,0 +1,47 @@
+package me.weebo.commands.staff;
+
+import me.weebo.PotionSG;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import me.weebo.managers.Managers;
+import me.weebo.utilities.C;
+
+public class ArenaCmd implements CommandExecutor {
+
+ @Override
+ public boolean onCommand(CommandSender s, Command cmd, String label, String[] arg) {
+ if (s instanceof Player) {
+ Player p = (Player) s;
+ if (p.hasPermission(PotionSG.PERM_ACCESS)) {
+ if (arg.length == 1) {
+ if (arg[0].equalsIgnoreCase("list")) list(p);
+ else help(p);
+ } else if (arg.length == 2) {
+ if (arg[0].equalsIgnoreCase("create")) Managers.getMapManager().addArena(arg[1], p);
+ else if (arg[0].equalsIgnoreCase("delete")) Managers.getMapManager().removeArena(arg[1], p);
+ else help(p);
+ } else help(p);
+ } else C.c(p, "&cYou do not have permissions to manage arenas.");
+ }
+ return true;
+ }
+
+ private void list(Player p) {
+ C.c(p, "&7&m--------------------------------------------------", C.MAIN + "&lArenas:");
+ for (String a : Managers.getMapManager().getArenas()) C.c(p, C.CHAT_SECONDARY + "* " + C.MAIN + a);
+ C.c(p, "&7&m--------------------------------------------------");
+ }
+
+ private void help(Player p) {
+ C.c(p,
+ "&7&m--------------------------------------------------",
+ C.MAIN + "&lSub-commands of \"" + C.CHAT_SECONDARY + "/arenas" + C.MAIN + "&l\":",
+ C.MAIN + "/arena create &7- Create an arena",
+ C.MAIN + "/arena delete &7- Delete an arena",
+ C.MAIN + "/arena list &7- List all arenas",
+ "&7&m--------------------------------------------------");
+ }
+}
diff --git a/src/main/java/me/weebo/commands/staff/BuildCmd.java b/src/main/java/me/weebo/commands/staff/BuildCmd.java
new file mode 100644
index 0000000..84b6e1c
--- /dev/null
+++ b/src/main/java/me/weebo/commands/staff/BuildCmd.java
@@ -0,0 +1,36 @@
+package me.weebo.commands.staff;
+
+import me.weebo.PotionSG;
+import org.bukkit.GameMode;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import me.weebo.managers.Managers;
+import me.weebo.players.Profile;
+import me.weebo.utilities.C;
+import me.weebo.utilities.PlayerUtils;
+
+public class BuildCmd implements CommandExecutor {
+
+ @Override
+ public boolean onCommand(CommandSender s, Command cmd, String label, String[] arg) {
+ if (s instanceof Player) {
+ Player p = (Player) s;
+ if (p.hasPermission(PotionSG.PERM_BUILD)) {
+ Profile pr = Managers.getProfileManager().getProfile(p.getUniqueId());
+ if (pr.isInLobby()) {
+ p.setGameMode(pr.isBuild() ? GameMode.SURVIVAL : GameMode.CREATIVE);
+ if (!pr.isBuild()) {
+ p.getInventory().clear();
+ p.updateInventory();
+ } else PlayerUtils.lobbyItems(p);
+ C.c(p, "&aBuild mode has been " + (pr.isBuild() ? "disabled" : "enabled") + ".");
+ pr.setBuild(!pr.isBuild());
+ } else C.c(p, "&cYou must be in lobby to toggle build mode.");
+ } else C.c(p, "&cYou do not have permissions to toggle build mode.");
+ }
+ return true;
+ }
+}
diff --git a/src/main/java/me/weebo/commands/staff/FreezeCmd.java b/src/main/java/me/weebo/commands/staff/FreezeCmd.java
new file mode 100644
index 0000000..dcceb24
--- /dev/null
+++ b/src/main/java/me/weebo/commands/staff/FreezeCmd.java
@@ -0,0 +1,68 @@
+package me.weebo.commands.staff;
+
+import me.weebo.PotionSG;
+import me.weebo.managers.Managers;
+import org.bukkit.Bukkit;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.bukkit.potion.PotionEffect;
+import org.bukkit.potion.PotionEffectType;
+
+import me.weebo.utilities.C;
+
+public class FreezeCmd implements CommandExecutor {
+
+ @Override
+ public boolean onCommand(CommandSender s, Command cmd, String label, String[] arg) {
+ if (s instanceof Player) {
+ Player p = (Player) s;
+ if (p.hasPermission(PotionSG.PERM_MOD) || p.hasPermission(PotionSG.PERM_ACCESS)) {
+ if (arg.length == 0 || arg.length > 1) C.c(p, "&e\u26A0 &cUsage: /freeze ");
+ else {
+ if (Bukkit.getPlayer(arg[0]) != null) {
+ Player t = Bukkit.getPlayer(arg[0]);
+ if (Managers.getProfileManager().getProfile(t.getUniqueId()).isFrozen()) {
+ allowMovement(t);
+ C.c(p, "&aYou unfroze " + t.getName() + ".");
+ C.c(t, "&aYou have been unfrozen.");
+ } else {
+ denyMovement(t);
+ C.c(p, "&aYou froze " + t.getName() + ".");
+ C.c(t, "",
+ "&f\u2588\u2588\u2588\u2588&c\u2588&f\u2588\u2588\u2588\u2588",
+ "&f\u2588\u2588\u2588&c\u2588&6\u2588&c\u2588&f\u2588\u2588\u2588",
+ "&f\u2588\u2588&c\u2588&6\u2588&0\u2588&6\u2588&c\u2588&f\u2588\u2588 &c&lYou have been frozen!",
+ "&f\u2588\u2588&c\u2588&6\u2588&0\u2588&6\u2588&c\u2588&f\u2588\u2588",
+ "&f\u2588&c\u2588&6\u2588\u2588&0\u2588&6\u2588\u2588&c\u2588&f\u2588 &7Please join " + C.MAIN + "discord.nekros.club",
+ "&f\u2588&c\u2588&6\u2588\u2588\u2588\u2588\u2588&c\u2588&f\u2588 &7in 3 minutes or you will be banned",
+ "&c\u2588&6\u2588\u2588\u2588&0\u2588&6\u2588\u2588\u2588&c\u2588",
+ "&c\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
+ "");
+ }
+ Managers.getProfileManager().getProfile(t.getUniqueId()).toggleFreeze();
+ }
+
+ }
+ }
+ }
+ return true;
+ }
+
+ private void denyMovement(Player player) {
+ player.setWalkSpeed(0.0F);
+ player.setFlySpeed(0.0F);
+ player.setFoodLevel(0);
+ player.setSprinting(false);
+ player.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, Integer.MAX_VALUE, 200));
+ }
+
+ private void allowMovement(Player player) {
+ player.setWalkSpeed(0.2F);
+ player.setFlySpeed(0.0001F);
+ player.setFoodLevel(20);
+ player.setSprinting(true);
+ player.removePotionEffect(PotionEffectType.JUMP);
+ }
+}
diff --git a/src/main/java/me/weebo/commands/staff/SetLobbySpawnCmd.java b/src/main/java/me/weebo/commands/staff/SetLobbySpawnCmd.java
new file mode 100644
index 0000000..6da1dde
--- /dev/null
+++ b/src/main/java/me/weebo/commands/staff/SetLobbySpawnCmd.java
@@ -0,0 +1,22 @@
+package me.weebo.commands.staff;
+
+import me.weebo.PotionSG;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import me.weebo.utilities.LocationUtils;
+
+public class SetLobbySpawnCmd implements CommandExecutor {
+
+ @Override
+ public boolean onCommand(CommandSender s, Command cmd, String label, String[] arg) {
+ if (s instanceof Player) {
+ Player p = (Player) s;
+ if (p.hasPermission(PotionSG.PERM_ACCESS)) LocationUtils.saveLobbySpawn(p);
+ }
+ return true;
+ }
+
+}
diff --git a/src/main/java/me/weebo/commands/staff/SetSlotsCommand.java b/src/main/java/me/weebo/commands/staff/SetSlotsCommand.java
new file mode 100644
index 0000000..3d4f057
--- /dev/null
+++ b/src/main/java/me/weebo/commands/staff/SetSlotsCommand.java
@@ -0,0 +1,35 @@
+package me.weebo.commands.staff;
+
+import me.weebo.PotionSG;
+import me.weebo.utilities.BukkitReflection;
+import org.bukkit.Bukkit;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+
+public class SetSlotsCommand implements CommandExecutor {
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String s, String[] args) {
+ if (!sender.hasPermission(PotionSG.PERM_ADMIN)) {
+ sender.sendMessage("§cInsufficient permissions");
+ return true;
+ } else if (args.length != 1) {
+ sender.sendMessage("§c/setslots ");
+ return true;
+ } else {
+ Integer slots;
+ try {
+ slots = Integer.parseInt(args[0]);
+ } catch (Exception var6) {
+ sender.sendMessage("§cNot a valid number.");
+ return true;
+ }
+ BukkitReflection.setMaxPlayers(Bukkit.getServer(), slots);
+ sender.sendMessage(String.format("§aSuccessfully set the slots to §2%s§a.", slots));
+ return true;
+ }
+ }
+}
+
+
diff --git a/src/main/java/me/weebo/cuboid/Cuboid.java b/src/main/java/me/weebo/cuboid/Cuboid.java
new file mode 100644
index 0000000..e1f82bf
--- /dev/null
+++ b/src/main/java/me/weebo/cuboid/Cuboid.java
@@ -0,0 +1,482 @@
+package me.weebo.cuboid;
+
+import com.google.common.base.Preconditions;
+import org.bukkit.*;
+import org.bukkit.block.Block;
+import org.bukkit.configuration.serialization.ConfigurationSerializable;
+import org.bukkit.entity.Player;
+import org.bukkit.util.Vector;
+
+import java.util.*;
+
+public class Cuboid
+ implements Iterable, Cloneable, ConfigurationSerializable {
+ protected String worldName;
+ protected int x1;
+ protected int y1;
+ protected int z1;
+ protected int x2;
+ protected int y2;
+ protected int z2;
+
+ public Cuboid(Map map) {
+ this.worldName = ((String) map.get("worldName"));
+ this.x1 = ((Integer) map.get("x1")).intValue();
+ this.y1 = ((Integer) map.get("y1")).intValue();
+ this.z1 = ((Integer) map.get("z1")).intValue();
+ this.x2 = ((Integer) map.get("x2")).intValue();
+ this.y2 = ((Integer) map.get("y2")).intValue();
+ this.z2 = ((Integer) map.get("z2")).intValue();
+ }
+
+ public Cuboid(World world, int x1, int y1, int z1, int x2, int y2, int z2) {
+ this(((World) Preconditions.checkNotNull(world)).getName(), x1, y1, z1, x2, y2, z2);
+ }
+
+ private Cuboid(String worldName, int x1, int y1, int z1, int x2, int y2, int z2) {
+ Preconditions.checkNotNull(worldName, "World name cannot be null");
+ this.worldName = worldName;
+ this.x1 = Math.min(x1, x2);
+ this.y1 = Math.min(y1, y2);
+ this.z1 = Math.min(z1, z2);
+ this.x2 = Math.max(x1, x2);
+ this.y2 = Math.max(y1, y2);
+ this.z2 = Math.max(z1, z2);
+ }
+
+ public Cuboid(Location first, Location second) {
+ Preconditions.checkNotNull(first, "Location 1 cannot be null");
+ Preconditions.checkNotNull(second, "Location 2 cannot be null");
+ Preconditions.checkArgument(first.getWorld().equals(second.getWorld()), "Locations must be on the same world");
+ this.worldName = first.getWorld().getName();
+ this.x1 = Math.min(first.getBlockX(), second.getBlockX());
+ this.y1 = Math.min(first.getBlockY(), second.getBlockY());
+ this.z1 = Math.min(first.getBlockZ(), second.getBlockZ());
+ this.x2 = Math.max(first.getBlockX(), second.getBlockX());
+ this.y2 = Math.max(first.getBlockY(), second.getBlockY());
+ this.z2 = Math.max(first.getBlockZ(), second.getBlockZ());
+ }
+
+ public Cuboid(Location location) {
+ this(location, location);
+ }
+
+ public Cuboid(Cuboid other) {
+ this(other.getWorld().getName(), other.x1, other.y1, other.z1, other.x2, other.y2, other.z2);
+ }
+
+ public Map serialize() {
+ Map map = new LinkedHashMap<>();
+ map.put("worldName", this.worldName);
+ map.put("x1", Integer.valueOf(this.x1));
+ map.put("y1", Integer.valueOf(this.y1));
+ map.put("z1", Integer.valueOf(this.z1));
+ map.put("x2", Integer.valueOf(this.x2));
+ map.put("y2", Integer.valueOf(this.y2));
+ map.put("z2", Integer.valueOf(this.z2));
+ return map;
+ }
+
+ public boolean hasBothPositionsSet() {
+ return (getMinimumPoint() != null) && (getMaximumPoint() != null);
+ }
+
+ public int getMinimumX() {
+ return Math.min(this.x1, this.x2);
+ }
+
+ public int getMinimumZ() {
+ return Math.min(this.z1, this.z2);
+ }
+
+ public int getMaximumX() {
+ return Math.max(this.x1, this.x2);
+ }
+
+ public int getMaximumZ() {
+ return Math.max(this.z1, this.z2);
+ }
+
+ public List edges() {
+ return edges(-1, -1, -1, -1);
+ }
+
+ public List edges(int fixedMinX, int fixedMaxX, int fixedMinZ, int fixedMaxZ) {
+ Vector v1 = getMinimumPoint().toVector();
+ Vector v2 = getMaximumPoint().toVector();
+ int minX = v1.getBlockX();
+ int maxX = v2.getBlockX();
+ int minZ = v1.getBlockZ();
+ int maxZ = v2.getBlockZ();
+ int capacity = (maxX - minX) * 4 + (maxZ - minZ) * 4;
+ capacity += 4;
+ List result = new ArrayList<>(capacity);
+ if (capacity <= 0) {
+ return result;
+ }
+ int minY = v1.getBlockY();
+ int maxY = v1.getBlockY();
+ for (int x = minX; x <= maxX; x++) {
+ result.add(new Vector(x, minY, minZ));
+ result.add(new Vector(x, minY, maxZ));
+ result.add(new Vector(x, maxY, minZ));
+ result.add(new Vector(x, maxY, maxZ));
+ }
+ for (int z = minZ; z <= maxZ; z++) {
+ result.add(new Vector(minX, minY, z));
+ result.add(new Vector(minX, maxY, z));
+ result.add(new Vector(maxX, minY, z));
+ result.add(new Vector(maxX, maxY, z));
+ }
+ return result;
+ }
+
+ @SuppressWarnings("deprecation")
+ public Set getPlayers() {
+ Set players = new HashSet();
+ for (Player player : Bukkit.getServer().getOnlinePlayers()) {
+ if (contains(player)) {
+ players.add(player);
+ }
+ }
+ return players;
+ }
+
+ public Location getLowerNE() {
+ return new Location(getWorld(), this.x1, this.y1, this.z1);
+ }
+
+ public Location getUpperSW() {
+ return new Location(getWorld(), this.x2, this.y2, this.z2);
+ }
+
+ public Location getCenter() {
+ int x1 = this.x2 + 1;
+ int y1 = this.y2 + 1;
+ int z1 = this.z2 + 1;
+ return new Location(getWorld(), this.x1 + (x1 - this.x1) / 2.0D, this.y1 + (y1 - this.y1) / 2.0D, this.z1 + (z1 - this.z1) / 2.0D);
+ }
+
+ public String getWorldName() {
+ return this.worldName;
+ }
+
+ public World getWorld() {
+ return Bukkit.getWorld(this.worldName);
+ }
+
+ public int getSizeX() {
+ return this.x2 - this.x1 + 1;
+ }
+
+ public int getSizeY() {
+ return this.y2 - this.y1 + 1;
+ }
+
+ public int getSizeZ() {
+ return this.z2 - this.z1 + 1;
+ }
+
+ public int getX1() {
+ return this.x1;
+ }
+
+ public void setX1(int x1) {
+ this.x1 = x1;
+ }
+
+ public int getY1() {
+ return this.y1;
+ }
+
+ public void setY1(int y1) {
+ this.y1 = y1;
+ }
+
+ public int getZ1() {
+ return this.z1;
+ }
+
+ public void setZ1(int z1) {
+ this.z1 = z1;
+ }
+
+ public int getX2() {
+ return this.x2;
+ }
+
+ public int getY2() {
+ return this.y2;
+ }
+
+ public void setY2(int y2) {
+ this.y2 = y2;
+ }
+
+ public int getZ2() {
+ return this.z2;
+ }
+
+ public Location[] getCornerLocations() {
+ Location[] result = new Location[8];
+ Block[] cornerBlocks = getCornerBlocks();
+ for (int i = 0; i < cornerBlocks.length; i++) {
+ result[i] = cornerBlocks[i].getLocation();
+ }
+ return result;
+ }
+
+ public Block[] getCornerBlocks() {
+ Block[] result = new Block[8];
+ World world = getWorld();
+ result[0] = world.getBlockAt(this.x1, this.y1, this.z1);
+ result[1] = world.getBlockAt(this.x1, this.y1, this.z2);
+ result[2] = world.getBlockAt(this.x1, this.y2, this.z1);
+ result[3] = world.getBlockAt(this.x1, this.y2, this.z2);
+ result[4] = world.getBlockAt(this.x2, this.y1, this.z1);
+ result[5] = world.getBlockAt(this.x2, this.y1, this.z2);
+ result[6] = world.getBlockAt(this.x2, this.y2, this.z1);
+ result[7] = world.getBlockAt(this.x2, this.y2, this.z2);
+ return result;
+ }
+
+ public Cuboid shift(CuboidDirection direction, int amount)
+ throws IllegalArgumentException {
+ return expand(direction, amount).expand(direction.opposite(), -amount);
+ }
+
+ public Cuboid inset(CuboidDirection direction, int amount)
+ throws IllegalArgumentException {
+ return outset(direction, -amount);
+ }
+
+ @SuppressWarnings("incomplete-switch")
+ public Cuboid expand(CuboidDirection direction, int amount)
+ throws IllegalArgumentException {
+ switch (direction) {
+ case BOTH:
+ return new Cuboid(this.worldName, this.x1 - amount, this.y1, this.z1, this.x2, this.y2, this.z2);
+ case EAST:
+ return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x2 + amount, this.y2, this.z2);
+ case DOWN:
+ return new Cuboid(this.worldName, this.x1, this.y1, this.z1 - amount, this.x2, this.y2, this.z2);
+ case HORIZONTAL:
+ return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x2, this.y2, this.z2 + amount);
+ case SOUTH:
+ return new Cuboid(this.worldName, this.x1, this.y1 - amount, this.z1, this.x2, this.y2, this.z2);
+ case NORTH:
+ return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x2, this.y2 + amount, this.z2);
+ }
+ throw new IllegalArgumentException("Invalid direction " + direction);
+ }
+
+ @SuppressWarnings("incomplete-switch")
+ public Cuboid outset(CuboidDirection direction, int amount)
+ throws IllegalArgumentException {
+ switch (direction) {
+ case UNKNOWN:
+ return expand(CuboidDirection.NORTH, amount).expand(CuboidDirection.SOUTH, amount).expand(CuboidDirection.EAST, amount).expand(CuboidDirection.WEST, amount);
+ case UP:
+ return expand(CuboidDirection.DOWN, amount).expand(CuboidDirection.UP, amount);
+ case VERTICAL:
+ return outset(CuboidDirection.HORIZONTAL, amount).outset(CuboidDirection.VERTICAL, amount);
+ }
+ throw new IllegalArgumentException("Invalid direction " + direction);
+ }
+
+ public boolean contains(Cuboid cuboid) {
+ return (contains(cuboid.getMinimumPoint())) || (contains(cuboid.getMaximumPoint()));
+ }
+
+ public boolean contains(Player player) {
+ return contains(player.getLocation());
+ }
+
+ public boolean contains(World world, int x, int z) {
+ return ((world == null) || (getWorld().equals(world))) && (x >= this.x1) && (x <= this.x2) && (z >= this.z1) && (z <= this.z2);
+ }
+
+ public boolean contains(int x, int y, int z) {
+ return (x >= this.x1) && (x <= this.x2) && (y >= this.y1) && (y <= this.y2) && (z >= this.z1) && (z <= this.z2);
+ }
+
+ public boolean contains(Block block) {
+ return contains(block.getLocation());
+ }
+
+ public boolean contains(Location location) {
+ if ((location == null) || (this.worldName == null)) {
+ return false;
+ }
+ World world = location.getWorld();
+ return (world != null) && (this.worldName.equals(location.getWorld().getName())) && (contains(location.getBlockX(), location.getBlockY(), location.getBlockZ()));
+ }
+
+ public int getVolume() {
+ return getSizeX() * getSizeY() * getSizeZ();
+ }
+
+ public int getArea() {
+ Location min = getMinimumPoint();
+ Location max = getMaximumPoint();
+ return (max.getBlockX() - min.getBlockX() + 1) * (max.getBlockZ() - min.getBlockZ() + 1);
+ }
+
+ public byte getAverageLightLevel() {
+ long total = 0L;
+ int count = 0;
+ for (Block block : this) {
+ if (block.isEmpty()) {
+ total += block.getLightLevel();
+ count++;
+ }
+ }
+ return count > 0 ? (byte) (int) (total / count) : 0;
+ }
+
+ public Location getMinimumPoint() {
+ return new Location(getWorld(), Math.min(this.x1, this.x2), Math.min(this.y1, this.y2), Math.min(this.z1, this.z2));
+ }
+
+ public Location getMaximumPoint() {
+ return new Location(getWorld(), Math.max(this.x1, this.x2), Math.max(this.y1, this.y2), Math.max(this.z1, this.z2));
+ }
+
+ public int getWidth() {
+ return getMaximumPoint().getBlockX() - getMinimumPoint().getBlockX();
+ }
+
+ public int getHeight() {
+ return getMaximumPoint().getBlockY() - getMinimumPoint().getBlockY();
+ }
+
+ public int getLength() {
+ return getMaximumPoint().getBlockZ() - getMinimumPoint().getBlockZ();
+ }
+
+ public Cuboid contract() {
+ return contract(CuboidDirection.DOWN).contract(CuboidDirection.SOUTH).contract(CuboidDirection.EAST).contract(CuboidDirection.UP).contract(CuboidDirection.NORTH).contract(CuboidDirection.WEST);
+ }
+
+ @SuppressWarnings("incomplete-switch")
+ public Cuboid contract(CuboidDirection direction) {
+ Cuboid face = getFace(direction.opposite());
+ switch (direction) {
+ case SOUTH:
+ while ((face.containsOnly(Material.AIR)) && (face.y1 > this.y1)) {
+ face = face.shift(CuboidDirection.DOWN, 1);
+ }
+ return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x2, face.y2, this.z2);
+ case NORTH:
+ while ((face.containsOnly(Material.AIR)) && (face.y2 < this.y2)) {
+ face = face.shift(CuboidDirection.UP, 1);
+ }
+ return new Cuboid(this.worldName, this.x1, face.y1, this.z1, this.x2, this.y2, this.z2);
+ case BOTH:
+ while ((face.containsOnly(Material.AIR)) && (face.x1 > this.x1)) {
+ face = face.shift(CuboidDirection.NORTH, 1);
+ }
+ return new Cuboid(this.worldName, this.x1, this.y1, this.z1, face.x2, this.y2, this.z2);
+ case EAST:
+ while ((face.containsOnly(Material.AIR)) && (face.x2 < this.x2)) {
+ face = face.shift(CuboidDirection.SOUTH, 1);
+ }
+ return new Cuboid(this.worldName, face.x1, this.y1, this.z1, this.x2, this.y2, this.z2);
+ case DOWN:
+ while ((face.containsOnly(Material.AIR)) && (face.z1 > this.z1)) {
+ face = face.shift(CuboidDirection.EAST, 1);
+ }
+ return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x2, this.y2, face.z2);
+ case HORIZONTAL:
+ while ((face.containsOnly(Material.AIR)) && (face.z2 < this.z2)) {
+ face = face.shift(CuboidDirection.WEST, 1);
+ }
+ return new Cuboid(this.worldName, this.x1, this.y1, face.z1, this.x2, this.y2, this.z2);
+ }
+ throw new IllegalArgumentException("Invalid direction " + direction);
+ }
+
+ @SuppressWarnings("incomplete-switch")
+ public Cuboid getFace(CuboidDirection direction) {
+ switch (direction) {
+ case SOUTH:
+ return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x2, this.y1, this.z2);
+ case NORTH:
+ return new Cuboid(this.worldName, this.x1, this.y2, this.z1, this.x2, this.y2, this.z2);
+ case BOTH:
+ return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x1, this.y2, this.z2);
+ case EAST:
+ return new Cuboid(this.worldName, this.x2, this.y1, this.z1, this.x2, this.y2, this.z2);
+ case DOWN:
+ return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x2, this.y2, this.z1);
+ case HORIZONTAL:
+ return new Cuboid(this.worldName, this.x1, this.y1, this.z2, this.x2, this.y2, this.z2);
+ }
+ throw new IllegalArgumentException("Invalid direction " + direction);
+ }
+
+ public boolean containsOnly(Material material) {
+ for (Block block : this) {
+ if (block.getType() != material) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public Cuboid getBoundingCuboid(Cuboid other) {
+ if (other == null) {
+ return this;
+ }
+ int xMin = Math.min(this.x1, other.x1);
+ int yMin = Math.min(this.y1, other.y1);
+ int zMin = Math.min(this.z1, other.z1);
+ int xMax = Math.max(this.x2, other.x2);
+ int yMax = Math.max(this.y2, other.y2);
+ int zMax = Math.max(this.z2, other.z2);
+ return new Cuboid(this.worldName, xMin, yMin, zMin, xMax, yMax, zMax);
+ }
+
+ public Block getRelativeBlock(int x, int y, int z) {
+ return getWorld().getBlockAt(this.x1 + x, this.y1 + y, this.z1 + z);
+ }
+
+ public Block getRelativeBlock(World world, int x, int y, int z) {
+ return world.getBlockAt(this.x1 + x, this.y1 + y, this.z1 + z);
+ }
+
+ public List getChunks() {
+ World world = getWorld();
+ int x1 = this.x1 & 0xFFFFFFF0;
+ int x2 = this.x2 & 0xFFFFFFF0;
+ int z1 = this.z1 & 0xFFFFFFF0;
+ int z2 = this.z2 & 0xFFFFFFF0;
+ List result = new ArrayList<>(x2 - x1 + 16 + (z2 - z1) * 16);
+ for (int x3 = x1; x3 <= x2; x3 += 16) {
+ for (int z3 = z1; z3 <= z2; z3 += 16) {
+ result.add(world.getChunkAt(x3 >> 4, z3 >> 4));
+ }
+ }
+ return result;
+ }
+
+ public Iterator iterator() {
+ return new CuboidBlockIterator(getWorld(), this.x1, this.y1, this.z1, this.x2, this.y2, this.z2);
+ }
+
+ public Iterator locationIterator() {
+ return new CuboidLocationIterator(getWorld(), this.x1, this.y1, this.z1, this.x2, this.y2, this.z2);
+ }
+
+ public Cuboid clone() {
+ try {
+ return (Cuboid) super.clone();
+ } catch (CloneNotSupportedException ex) {
+ throw new RuntimeException("This could never happen", ex);
+ }
+ }
+
+ public String toString() {
+ return "Cuboid: " + this.worldName + ',' + this.x1 + ',' + this.y1 + ',' + this.z1 + "=>" + this.x2 + ',' + this.y2 + ',' + this.z2;
+ }
+}
diff --git a/src/main/java/me/weebo/cuboid/CuboidBlockIterator.java b/src/main/java/me/weebo/cuboid/CuboidBlockIterator.java
new file mode 100644
index 0000000..4f608f4
--- /dev/null
+++ b/src/main/java/me/weebo/cuboid/CuboidBlockIterator.java
@@ -0,0 +1,54 @@
+package me.weebo.cuboid;
+
+import org.bukkit.World;
+import org.bukkit.block.Block;
+
+import java.util.Iterator;
+
+public class CuboidBlockIterator
+ implements Iterator {
+ private World world;
+ private int baseX;
+ private int baseY;
+ private int baseZ;
+ private int sizeX;
+ private int sizeY;
+ private int sizeZ;
+ private int x;
+ private int y;
+ private int z;
+
+ public CuboidBlockIterator(World world, int x1, int y1, int z1, int x2, int y2, int z2) {
+ this.world = world;
+ this.baseX = x1;
+ this.baseY = y1;
+ this.baseZ = z1;
+ this.sizeX = (Math.abs(x2 - x1) + 1);
+ this.sizeY = (Math.abs(y2 - y1) + 1);
+ this.sizeZ = (Math.abs(z2 - z1) + 1);
+ this.z = 0;
+ this.y = 0;
+ this.x = 0;
+ }
+
+ public boolean hasNext() {
+ return (this.x < this.sizeX) && (this.y < this.sizeY) && (this.z < this.sizeZ);
+ }
+
+ public Block next() {
+ Block block = this.world.getBlockAt(this.baseX + this.x, this.baseY + this.y, this.baseZ + this.z);
+ if (++this.x >= this.sizeX) {
+ this.x = 0;
+ if (++this.y >= this.sizeY) {
+ this.y = 0;
+ this.z += 1;
+ }
+ }
+ return block;
+ }
+
+ public void remove()
+ throws UnsupportedOperationException {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/src/main/java/me/weebo/cuboid/CuboidDirection.java b/src/main/java/me/weebo/cuboid/CuboidDirection.java
new file mode 100644
index 0000000..be544ae
--- /dev/null
+++ b/src/main/java/me/weebo/cuboid/CuboidDirection.java
@@ -0,0 +1,55 @@
+package me.weebo.cuboid;
+
+
+import org.bukkit.block.BlockFace;
+
+public enum CuboidDirection {
+ NORTH, EAST, SOUTH, WEST, UP, DOWN, HORIZONTAL, VERTICAL, BOTH, UNKNOWN;
+
+ private CuboidDirection() {
+ }
+
+ @SuppressWarnings("incomplete-switch")
+ public CuboidDirection opposite() {
+ switch (this) {
+ case BOTH:
+ return SOUTH;
+ case DOWN:
+ return WEST;
+ case EAST:
+ return NORTH;
+ case HORIZONTAL:
+ return EAST;
+ case UNKNOWN:
+ return VERTICAL;
+ case UP:
+ return HORIZONTAL;
+ case NORTH:
+ return DOWN;
+ case SOUTH:
+ return UP;
+ case VERTICAL:
+ return BOTH;
+ }
+ return UNKNOWN;
+ }
+
+ @SuppressWarnings("incomplete-switch")
+ public BlockFace toBukkitDirection() {
+ switch (this) {
+ case BOTH:
+ return BlockFace.NORTH;
+ case DOWN:
+ return BlockFace.EAST;
+ case EAST:
+ return BlockFace.SOUTH;
+ case HORIZONTAL:
+ return BlockFace.WEST;
+ case NORTH:
+ return BlockFace.UP;
+ case SOUTH:
+ return BlockFace.DOWN;
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/me/weebo/cuboid/CuboidLocationIterator.java b/src/main/java/me/weebo/cuboid/CuboidLocationIterator.java
new file mode 100644
index 0000000..c70f847
--- /dev/null
+++ b/src/main/java/me/weebo/cuboid/CuboidLocationIterator.java
@@ -0,0 +1,54 @@
+package me.weebo.cuboid;
+
+import org.bukkit.Location;
+import org.bukkit.World;
+
+import java.util.Iterator;
+
+public class CuboidLocationIterator
+ implements Iterator {
+ private World world;
+ private int baseX;
+ private int baseY;
+ private int baseZ;
+ private int sizeX;
+ private int sizeY;
+ private int sizeZ;
+ private int x;
+ private int y;
+ private int z;
+
+ public CuboidLocationIterator(World world, int x1, int y1, int z1, int x2, int y2, int z2) {
+ this.world = world;
+ this.baseX = x1;
+ this.baseY = y1;
+ this.baseZ = z1;
+ this.sizeX = (Math.abs(x2 - x1) + 1);
+ this.sizeY = (Math.abs(y2 - y1) + 1);
+ this.sizeZ = (Math.abs(z2 - z1) + 1);
+ this.z = 0;
+ this.y = 0;
+ this.x = 0;
+ }
+
+ public boolean hasNext() {
+ return (this.x < this.sizeX) && (this.y < this.sizeY) && (this.z < this.sizeZ);
+ }
+
+ public Location next() {
+ Location location = new Location(this.world, this.baseX + this.x, this.baseY + this.y, this.baseZ + this.z);
+ if (++this.x >= this.sizeX) {
+ this.x = 0;
+ if (++this.y >= this.sizeY) {
+ this.y = 0;
+ this.z += 1;
+ }
+ }
+ return location;
+ }
+
+ public void remove()
+ throws UnsupportedOperationException {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/src/main/java/me/weebo/listeners/InventoryListener.java b/src/main/java/me/weebo/listeners/InventoryListener.java
new file mode 100644
index 0000000..b6f77a5
--- /dev/null
+++ b/src/main/java/me/weebo/listeners/InventoryListener.java
@@ -0,0 +1,72 @@
+package me.weebo.listeners;
+
+import me.weebo.PotionSG;
+import me.weebo.managers.scenarios.InventoryManager;
+import me.weebo.managers.scenarios.Scenario;
+import me.weebo.utilities.C;
+import me.weebo.utilities.JsonMessage;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+
+public class InventoryListener implements Listener {
+
+ @EventHandler
+ public void onInventoryClick(InventoryClickEvent event) {
+ final Player player = (Player)event.getWhoClicked();
+ final ItemStack clicked = event.getCurrentItem();
+ final Inventory inventory = event.getInventory();
+
+ if (clicked == null) {
+ return;
+ }
+ if (clicked.getType() == Material.AIR) {
+ return;
+ }
+ InventoryManager manager = PotionSG.getInstance().getInventoryManager();
+ if (inventory.getTitle().equals("§b§lHost a Game")) {
+ event.setCancelled(true);
+ if (clicked.getItemMeta().getDisplayName().equalsIgnoreCase( "§cDisable All Scenarios")) {
+ for (Scenario scenario : PotionSG.getInstance().getScenarioManager().getScenarios()) {
+ scenario.setActive(false);
+ }
+ player.closeInventory();
+ manager.createScen(player, 1);
+ player.sendMessage( "§7All §fscenarios have been §cdisabled§f.");
+ return;
+ }
+ if (clicked.getItemMeta().getDisplayName().equalsIgnoreCase("§a§lHost Game")) {
+ if (player.hasPermission(PotionSG.PERM_HOST) || player.hasPermission(PotionSG.PERM_ACCESS) || player.hasPermission(PotionSG.PERM_MOD)) {
+ if (PotionSG.getInst().isIdle()) {
+ if (PotionSG.getInst().getCooldownTimer() > 0)
+ C.c(player, "&cPlease wait for another " + PotionSG.getInst().getCooldownTimer() + " seconds before hosting another game.");
+ else PotionSG.getInst().hostGame(player.getName());
+ } else if (PotionSG.getInst().isWaiting()) C.c(player, "&cThe game has already started!");
+ else C.c(player, "&cThe game has already started!");
+ } else
+ new JsonMessage().append(C.c("" + "&cHosting a game requires at least a rank")).save().send(player);
+ player.closeInventory();
+ return;
+ }
+ final Scenario scenario = PotionSG.getInstance().getScenarioManager().getScenario(clicked.getItemMeta().getDisplayName());
+ final ItemMeta meta = clicked.getItemMeta();
+ if (scenario != null) {
+ scenario.setActive(!scenario.isActive());
+ player.sendMessage("§fScenario §7" + scenario.getName() + " " + (scenario.isActive() ? "§fhas been §aenabled§f." : "§fhas been §cdisabled§f."));
+ meta.setLore(manager.getWithStatus(scenario));
+ clicked.setItemMeta(meta);
+ player.updateInventory();
+ return;
+ }
+ return;
+ }
+
+ }
+
+}
diff --git a/src/main/java/me/weebo/listeners/PlayerListeners.java b/src/main/java/me/weebo/listeners/PlayerListeners.java
new file mode 100644
index 0000000..831f118
--- /dev/null
+++ b/src/main/java/me/weebo/listeners/PlayerListeners.java
@@ -0,0 +1,409 @@
+package me.weebo.listeners;
+
+import me.weebo.PotionSG;
+import me.weebo.managers.Managers;
+import me.weebo.utilities.*;
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.Material;
+import org.bukkit.Sound;
+import org.bukkit.block.Chest;
+import org.bukkit.entity.Player;
+import org.bukkit.entity.TNTPrimed;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.Listener;
+import org.bukkit.event.block.Action;
+import org.bukkit.event.block.BlockBreakEvent;
+import org.bukkit.event.block.BlockPlaceEvent;
+import org.bukkit.event.entity.EntityDamageByEntityEvent;
+import org.bukkit.event.entity.EntityDamageEvent;
+import org.bukkit.event.entity.FoodLevelChangeEvent;
+import org.bukkit.event.entity.PlayerDeathEvent;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.event.inventory.InventoryCloseEvent;
+import org.bukkit.event.inventory.InventoryOpenEvent;
+import org.bukkit.event.inventory.InventoryType;
+import org.bukkit.event.player.*;
+import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
+import org.bukkit.help.HelpTopic;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.scheduler.BukkitRunnable;
+
+import java.util.List;
+import java.util.Random;
+
+/*
+ * Listens to events related to players.
+ */
+public class PlayerListeners implements Listener {
+
+ @EventHandler
+ public void interact(PlayerInteractEvent e) {
+ if ((e.getAction() == Action.LEFT_CLICK_BLOCK || e.getAction() == Action.RIGHT_CLICK_BLOCK)) {
+ if (!(Managers.getProfileManager().getProfile(e.getPlayer().getUniqueId()).isInGame() && PotionSG.getInst().getStartTimer() < 0) && !Managers.getProfileManager().getProfile(e.getPlayer().getUniqueId()).isBuild())
+ e.setCancelled(true);
+ if (e.getClickedBlock().getType() == Material.ENDER_CHEST) {
+ if (Managers.getProfileManager().getProfile(e.getPlayer().getUniqueId()).isInGame() && PotionSG.getInst().getStartTimer() < 0) {
+ e.setCancelled(true);
+ Managers.getMapManager().dropFeastItems(e.getClickedBlock().getLocation());
+ e.getClickedBlock().setType(Material.AIR);
+ e.getPlayer().playSound(e.getPlayer().getLocation(), Sound.GLASS, 10, 1);
+ }
+ }
+ }
+ if (e.getAction() == Action.LEFT_CLICK_BLOCK) {
+ if (e.getClickedBlock().getType() == Material.CHEST) {
+ if (Managers.getProfileManager().getProfile(e.getPlayer().getUniqueId()).isInGame() && PotionSG.getInst().getStartTimer() < 0) {
+ Chest chest = (Chest) e.getClickedBlock().getState();
+ if (!Managers.getMapManager().chestIsOpened(chest)) Managers.getMapManager().fillChest(chest);
+ e.getClickedBlock().setType(Material.AIR);
+ e.getPlayer().playSound(e.getPlayer().getLocation(), Sound.ZOMBIE_WOODBREAK, 10, 1);
+ }
+ }
+ }
+ if (e.getAction() == Action.LEFT_CLICK_BLOCK) {
+ if (e.getClickedBlock().getType() == Material.CHEST) {
+ if (Managers.getProfileManager().getProfile(e.getPlayer().getUniqueId()).isInGame() && PotionSG.getInst().getStartTimer() < 0) {
+ Managers.getMapManager().fillChest((Chest) e.getClickedBlock().getState());
+ e.getClickedBlock().setType(Material.AIR);
+ e.getPlayer().playSound(e.getPlayer().getLocation(), Sound.ZOMBIE_WOODBREAK, 10, 1);
+ }
+ }
+ }
+ if (e.getAction() == Action.LEFT_CLICK_AIR || e.getAction() == Action.LEFT_CLICK_BLOCK) {
+ if (e.getItem() != null && e.getItem().getType() != null && e.getItem().getItemMeta() != null && e.getItem().getItemMeta().getDisplayName() != null) {
+ if (equals(e, "Teleport")) {
+ e.setCancelled(true);
+ List list = PotionSG.getInst().getPlayersInGame();
+ e.getPlayer().teleport(list.get(new Random().nextInt(list.size())).getLocation());
+ }
+ }
+ }
+ if (e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK) {
+ Player p = e.getPlayer();
+ if (e.getItem() == null) return;
+ if (e.getItem().getType() == null) return;
+ if (e.getItem().getType() == Material.ENDER_PEARL) {
+ if (Managers.getPearlManager().isInCooldown(p)) {
+ e.setCancelled(true);
+ C.c(p, "&cYou are on pearl cooldown for " + Managers.getPearlManager().getCooldownIn1DP(p) + " seconds.");
+ } else Managers.getPearlManager().addPearlCooldown(p);
+ }
+ if (e.getItem().getItemMeta() == null) return;
+ if (e.getItem().getItemMeta().getDisplayName() == null) return;
+ e.setCancelled(true);
+ if (equals(e, "Join Current Game")) {
+ if (PotionSG.getInst().isIdle()) C.c(p, "&e\u26A0 &cThere is no game available.");
+ else if (PotionSG.getInst().isWaiting()) PotionSG.getInst().join(p);
+ else C.c(p, "&cThe game has already started, please use right-click the spectate item in your hotbar.");
+ } else if (equals(e, "Host a Game")) {
+ /*if (p.hasPermission(PotionSG.PERM_HOST) || p.hasPermission(PotionSG.PERM_ACCESS) || p.hasPermission(PotionSG.PERM_MOD)) {
+ if (PotionSG.getInst().isIdle()) {
+ if (PotionSG.getInst().getCooldownTimer() > 0)
+ C.c(p, "&e\u26A0 &cPlease wait for another " + PotionSG.getInst().getCooldownTimer() + " seconds before hosting another game.");
+ else PotionSG.getInst().hostGame(p.getName());
+ } else if (PotionSG.getInst().isWaiting()) C.c(p, "&e\u26A0 &cThe game has already started!");
+ else C.c(p, "&e\u26A0 &cThe game has already started!");
+ } else
+ new JsonMessage().append(C.c("&e\u26A0 " + C.CHAT_SECONDARY + "Hosting a game requires at least &6Inaros" + C.CHAT_SECONDARY + " or above. You can purchase ")).save().append(C.MAIN + "here").setClickAsURL("http://discord.nekros.club").setHoverAsTooltip(C.c("&eClick to go to our discord")).save().append(C.CHAT_SECONDARY + ".").save().send(p);*/
+ p.performCommand("host");
+ } else if (equals(e, "Spectate")) {
+ if (PotionSG.getInst().isIdle()) C.c(p, "&e\u26A0 &cThere is no game available.");
+ else if (PotionSG.getInst().isWaiting()) C.c(p, "&e\u26A0 &cThe game has not yet started.");
+ else if (PotionSG.getInst().getPlayersInGame().size() < 1) C.c(p, "&e\u26A0 &cThe game has ended.");
+ else PotionSG.getInst().spectate(p, true);
+ } else if (equals(e, "Disconnect")) p.kickPlayer(null);
+ else if (equals(e, "Leave Game")) {
+ PotionSG.getInst().msgAll(C.MAIN + p.getName() + C.CHAT_SECONDARY + " left the game.");
+ PotionSG.getInst().leaveGame(p);
+ } else if (equals(e, "Stop Spectating")) PotionSG.getInst().stopSpectating(p, true);
+ else if (equals(e, "Teleport")) p.openInventory(Managers.getUpdatedInventoryManager().getSpectateList());
+ else if (equals(e, "Leaderboard")) Managers.getLeaderboardManager().openLeaderboard(p);
+ else if (equals(e, "Preferences")) p.performCommand("settings");
+ }
+ }
+
+ private boolean equals(PlayerInteractEvent e, String name) {
+ return ChatColor.stripColor(e.getItem().getItemMeta().getDisplayName()).equals(name);
+ }
+
+ @SuppressWarnings("unused")
+ private boolean startsWith(PlayerInteractEvent e, String name) {
+ return ChatColor.stripColor(e.getItem().getItemMeta().getDisplayName()).startsWith(name);
+ }
+
+ @EventHandler
+ public void drop(PlayerDropItemEvent e) {
+ if (Managers.getProfileManager().getProfile(e.getPlayer().getUniqueId()).isInGame() && PotionSG.getInst().getStartTimer() < 0)
+ return;
+ if (!Managers.getProfileManager().getProfile(e.getPlayer().getUniqueId()).isBuild()) e.setCancelled(true);
+ }
+
+ @EventHandler
+ public void open(InventoryOpenEvent e) {
+ if (Managers.getProfileManager().getProfile(e.getPlayer().getUniqueId()).isInGame() && PotionSG.getInst().getStartTimer() < 0) {
+ if (e.getInventory().getType() != InventoryType.CHEST) return;
+ Chest chest = (Chest) e.getInventory().getHolder();
+ if (Managers.getMapManager().chestIsOpened(chest)) return;
+ Managers.getMapManager().fillChest(chest);
+ }
+ }
+
+// @EventHandler
+// public void onBrewing(BrewEvent e) {
+// BrewingStand brewingstand = (BrewingStand) e.getBlock().getState();
+// brewingstand.setBrewingTime(1);
+// }
+
+ @EventHandler
+ public void inv(InventoryClickEvent e) {
+ if (Managers.getProfileManager().getProfile(e.getWhoClicked().getUniqueId()).isInGame() && PotionSG.getInst().getStartTimer() < 0)
+ return;
+ if (Managers.getProfileManager().getProfile(e.getWhoClicked().getUniqueId()).isSpectating()) {
+ if (e.getCurrentItem() != null || e.getCurrentItem().getType() != Material.AIR) {
+ if (ChatColor.stripColor(e.getInventory().getTitle()).equals("Teleport to...")) {
+ if (Bukkit.getPlayer(ChatColor.stripColor(e.getCurrentItem().getItemMeta().getDisplayName())) != null)
+ e.getWhoClicked().teleport(Bukkit.getPlayer(ChatColor.stripColor(e.getCurrentItem().getItemMeta().getDisplayName())).getLocation());
+ } else e.setCancelled(true);
+ }
+ }
+ if (!Managers.getProfileManager().getProfile(e.getWhoClicked().getUniqueId()).isBuild()) e.setCancelled(true);
+ }
+
+ @EventHandler
+ public void interact(PlayerInteractEntityEvent e) {
+ if (e.getRightClicked() instanceof Player) {
+ Player t = (Player) e.getRightClicked();
+ if (e.getPlayer().getItemInHand() == null || e.getPlayer().getItemInHand().getType() == Material.AIR) return;
+ if (ChatColor.stripColor(e.getPlayer().getItemInHand().getItemMeta().getDisplayName()).equals("View Inventory")) {
+ if (Managers.getProfileManager().getProfile(t.getUniqueId()).isInGame() && Managers.getProfileManager().getProfile(e.getPlayer().getUniqueId()).isSpectating()) {
+ Inventory inv = Bukkit.createInventory(null, 45, ChatColor.YELLOW + "Inventory of " + t.getName());
+ int i = 27;
+ for (int j = 0; j <= 8; j++) {
+ inv.setItem(i, t.getInventory().getContents()[j]);
+ i++;
+ }
+ int k = 18;
+ for (int j = 27; j < t.getInventory().getContents().length; j++) {
+ inv.setItem(k, t.getInventory().getContents()[j]);
+ k++;
+ }
+ int l = 9;
+ for (int j = 18; j <= 26; j++) {
+ inv.setItem(l, t.getInventory().getContents()[j]);
+ l++;
+ }
+ int m = 0;
+ for (int j = 9; j <= 17; j++) {
+ inv.setItem(m, t.getInventory().getContents()[j]);
+ m++;
+ }
+ int n = 39;
+ for (ItemStack it : t.getInventory().getArmorContents()) {
+ inv.setItem(n, it);
+ n--;
+ }
+ e.getPlayer().openInventory(inv);
+ }
+ }
+ }
+ }
+
+ @EventHandler
+ public void hunger(FoodLevelChangeEvent e) {
+ if (!Managers.getProfileManager().getProfile(e.getEntity().getUniqueId()).isInGame() || (e.getFoodLevel() < ((Player) e.getEntity()).getFoodLevel() && new Random().nextInt(100) > 4))
+ e.setCancelled(true);
+ }
+
+ @EventHandler
+ public void damage(EntityDamageEvent e) {
+ if (e.getEntity() instanceof Player) {
+ if (Managers.getProfileManager().getProfile(e.getEntity().getUniqueId()).isInGame() && PotionSG.getInst().isPvp() && !Managers.getProfileManager().getProfile(e.getEntity().getUniqueId()).isFrozen())
+ return;
+ e.setCancelled(true);
+ }
+ }
+
+ @EventHandler
+ public void damage(EntityDamageByEntityEvent e) {
+ if (e.getEntity() instanceof Player && e.getDamager() instanceof Player) {
+ if (Managers.getProfileManager().getProfile(e.getEntity().getUniqueId()).isInGame() && Managers.getProfileManager().getProfile(e.getDamager().getUniqueId()).isInGame() && PotionSG.getInst().isPvp())
+ return;
+ e.setCancelled(true);
+ }
+ }
+
+ @EventHandler
+ public void pickup(PlayerPickupItemEvent e) {
+ if (Managers.getProfileManager().getProfile(e.getPlayer().getUniqueId()).isSpectating()) e.setCancelled(true);
+ }
+
+ @EventHandler
+ public void death(PlayerDeathEvent e) {
+ if (Managers.getProfileManager().getProfile(e.getEntity().getUniqueId()).isInGame()) {
+ if (e.getEntity().getKiller() != null && e.getEntity().getKiller() instanceof Player && !e.getEntity().getKiller().equals(e.getEntity())) Managers.getLeaderboardManager().addKill(e.getEntity().getKiller().getUniqueId());
+ e.getEntity().setHealth(20.0);
+ Managers.getPearlManager().removePearlCooldown(e.getEntity(), false);
+ e.getEntity().getWorld().strikeLightningEffect(e.getEntity().getLocation());
+ PotionSG.getInst().msg("&c" + e.getDeathMessage() + ".");
+ e.setDeathMessage(null);
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ if (PotionSG.getInst().getPlayersInGame().size() != 2)
+ PotionSG.getInst().spectate(e.getEntity(), false);
+ else {
+ PotionSG.getInst().leaveGame(e.getEntity());
+ PotionSG.getInst().check();
+ }
+ }
+ }.runTaskLater(PotionSG.getInst(), 2L);
+
+ }
+ }
+
+ @EventHandler
+ public void closeInv(InventoryCloseEvent e) {
+ if (Managers.getProfileManager().getProfile(e.getPlayer().getUniqueId()).isInGame() && PotionSG.getInst().getStartTimer() < 0) {
+ if (e.getInventory().getType() != InventoryType.CHEST) return;
+ if (!isEmpty(e.getInventory().getContents())) return;
+ Chest chest = (Chest) e.getInventory().getHolder();
+// Managers.getMapManager().addBlockRemoved(chest.getBlock());
+ chest.getBlock().setType(Material.AIR);
+ ((Player) e.getPlayer()).playSound(e.getPlayer().getLocation(), Sound.ZOMBIE_WOODBREAK, 10, 1);
+ }
+ }
+
+ private boolean isEmpty(ItemStack[] i) {
+ for (ItemStack item : i) if (item != null) return false;
+ return true;
+ }
+
+ @EventHandler(priority = EventPriority.MONITOR)
+ public void join(PlayerJoinEvent e) {
+ e.setJoinMessage(null);
+ if (LocationUtils.readLobbySpawn() != null) e.getPlayer().teleport(LocationUtils.readLobbySpawn());
+ Managers.getProfileManager().createProfile(e.getPlayer());
+ PlayerUtils.lobbyItems(e.getPlayer());
+ for (int i = 0; i < 100; i++) e.getPlayer().sendMessage("");
+ e.getPlayer().playSound(e.getPlayer().getLocation(), Sound.PORTAL_TRAVEL, 0.2F, 1);
+ /*C.c(e.getPlayer(),
+ "&7&m--------------------------------------------------",
+ "");
+ sendCenteredMessage(e.getPlayer(), C.MAIN + C.SERVER_NAME + C.SEASON);
+ String[] msg = new String[]{
+ "Whoooooooooooooooosh!",
+ "What should I type here?",
+ "Pretty sure you are here just for PotSG!",
+ "Yooo, Hanky with no brim!!",
+ "69w"
+// "HANKY CHEATED ON KAGUYA AND STOLE MY CHIKAAAA"
+ };
+ sendCenteredMessage(e.getPlayer(), "&6\u2730 " + C.CHAT_SECONDARY + msg[new Random().nextInt(msg.length)]);
+ C.c(e.getPlayer(), "", "&7&m--------------------------------------------------");*/
+ }
+
+ private final static int CENTER_PX = 154;
+
+ public static void sendCenteredMessage(Player player, String message) {
+ if (message == null || message.equals("")) player.sendMessage("");
+ message = ChatColor.translateAlternateColorCodes('&', message);
+ int messagePxSize = 0;
+ boolean previousCode = false;
+ boolean isBold = false;
+ for (char c : message.toCharArray()) {
+ if (c == '§') {
+ previousCode = true;
+ continue;
+ } else if (previousCode == true) {
+ previousCode = false;
+ if (c == 'l' || c == 'L') {
+ isBold = true;
+ continue;
+ } else isBold = false;
+ } else {
+ DefaultFontInfo dFI = DefaultFontInfo.getDefaultFontInfo(c);
+ messagePxSize += isBold ? dFI.getBoldLength() : dFI.getLength();
+ messagePxSize++;
+ }
+ }
+ int halvedMessageSize = messagePxSize / 2;
+ int toCompensate = CENTER_PX - halvedMessageSize;
+ int spaceLength = DefaultFontInfo.SPACE.getLength() + 1;
+ int compensated = 0;
+ StringBuilder sb = new StringBuilder();
+ while (compensated < toCompensate) {
+ sb.append(" ");
+ compensated += spaceLength;
+ }
+ C.c(player, sb.toString() + message);
+ }
+
+ @EventHandler
+ public void quit(PlayerQuitEvent e) {
+ e.setQuitMessage(null);
+ if (Managers.getProfileManager().getProfile(e.getPlayer().getUniqueId()).isInGame()) {
+ PotionSG.getInst().msg("&c" + e.getPlayer().getName() + " disconnected and has been disqualified.");
+ Managers.getProfileManager().getProfile(e.getPlayer().getUniqueId()).setInLobby();
+ PotionSG.getInst().check();
+ } else if (Managers.getProfileManager().getProfile(e.getPlayer().getUniqueId()).isWaiting()) PotionSG.getInst().msg(C.MAIN + e.getPlayer().getName() + C.CHAT_SECONDARY + " left the game.");
+ else if (Managers.getProfileManager().getProfile(e.getPlayer().getUniqueId()).isSpectating()) PotionSG.getInst().stopSpectating(e.getPlayer(), true);
+ Managers.getPearlManager().removePearlCooldown(e.getPlayer(), false);
+ Managers.getProfileManager().removeProfile(e.getPlayer());
+ }
+
+ @EventHandler
+ public void blockBreak(BlockBreakEvent e) {
+ if (!(Managers.getProfileManager().getProfile(e.getPlayer().getUniqueId()).isInGame() && PotionSG.getInst().getStartTimer() < 0) && !Managers.getProfileManager().getProfile(e.getPlayer().getUniqueId()).isBuild())
+ e.setCancelled(true);
+ //else Managers.getMapManager().addBlockRemoved(e.getBlock());
+ }
+
+ @EventHandler
+ public void blockPlace(BlockPlaceEvent e) {
+ if (!(Managers.getProfileManager().getProfile(e.getPlayer().getUniqueId()).isInGame() && PotionSG.getInst().getStartTimer() < 0) && !Managers.getProfileManager().getProfile(e.getPlayer().getUniqueId()).isBuild()) e.setCancelled(true);
+ else if (e.getBlockPlaced().getType() == Material.TNT) {
+ e.getBlockPlaced().setType(Material.AIR);
+ e.getBlockPlaced().getWorld().spawn(e.getBlockPlaced().getLocation(), TNTPrimed.class);
+ }
+ //else Managers.getMapManager().addBlockPlaced(e.getBlock());
+ }
+
+ @EventHandler
+ public void epearl(PlayerTeleportEvent e) {
+ if (e.getCause() == TeleportCause.ENDER_PEARL && (e.getTo().getX() < PotionSG.getInst().getBorderLocation1().getX() || e.getTo().getX() > PotionSG.getInst().getBorderLocation2().getX() || e.getTo().getZ() < PotionSG.getInst().getBorderLocation1().getZ() || e.getTo().getZ() > PotionSG.getInst().getBorderLocation2().getZ())) {
+ e.setCancelled(true);
+ e.getPlayer().getInventory().addItem(new EasyItem(Material.ENDER_PEARL).build());
+ C.c(e.getPlayer(), "&e\u26A0 &cYou cannot pearl outside the border.");
+ }
+ }
+
+ @EventHandler
+ public void cmd(PlayerCommandPreprocessEvent e) {
+ String str =
+// String[] str = new String[]{
+// "If you see this message, it means its time for you to type \"/help\".",
+// "Sorry, but it seems like that command does not exist!",
+// "We don't even know what that command is.",
+// "I know it's better to set this to \"Unknown command.\", but you guys are bored with that, I guess?",
+ "Unknown command. :(";
+// "Do you know what you are doing? Maybe type \"/help\" for help!"
+// };
+ if (!e.isCancelled()) {
+ String cmd = e.getMessage().split(" ")[0];
+ HelpTopic topic = Bukkit.getServer().getHelpMap().getHelpTopic(cmd);
+ if (topic == null || cmd.equalsIgnoreCase("me") || cmd.equalsIgnoreCase("say")) {
+ C.c(e.getPlayer(), "&e\u26A0 &c" + str/*[new Random().nextInt(str.length)]*/);
+ e.setCancelled(true);
+ }
+ }
+ }
+
+ @EventHandler
+ public void move(PlayerMoveEvent e) {
+ if (Managers.getProfileManager().getProfile(e.getPlayer().getUniqueId()).isInLobby() && e.getTo().getBlockY() < 0) e.getPlayer().teleport(LocationUtils.readLobbySpawn());
+ }
+
+}
diff --git a/src/main/java/me/weebo/listeners/WallBorderListener.java b/src/main/java/me/weebo/listeners/WallBorderListener.java
new file mode 100644
index 0000000..475b222
--- /dev/null
+++ b/src/main/java/me/weebo/listeners/WallBorderListener.java
@@ -0,0 +1,83 @@
+package me.weebo.listeners;
+
+import com.google.common.base.Predicate;
+import me.weebo.PotionSG;
+import me.weebo.barrier.VisualBlock;
+import me.weebo.barrier.VisualType;
+import me.weebo.cuboid.Cuboid;
+import org.bukkit.Location;
+import org.bukkit.World;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerMoveEvent;
+import org.bukkit.event.player.PlayerTeleportEvent;
+import org.bukkit.util.Vector;
+import me.weebo.utilities.LocationUtils;
+
+import java.util.Collection;
+
+public class WallBorderListener implements Listener {
+
+ @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
+ public void onPlayerMove(PlayerMoveEvent event) {
+ if (LocationUtils.readGameSpawn() != null) {
+ if (PotionSG.getInst().isStarted() && PotionSG.getInst().getRad() != 0 && event.getPlayer().getWorld().getName().equals(LocationUtils.readGameSpawn().getWorld().getName())) {
+ Location to = event.getTo();
+ int toX = to.getBlockX();
+ int toY = to.getBlockY();
+ int toZ = to.getBlockZ();
+ Location from = event.getFrom();
+ if ((from.getBlockX() != toX) || (from.getBlockY() != toY) || (from.getBlockZ() != toZ)) {
+ handlePositionChanged(event.getPlayer(), to.getWorld(), toX, toY, toZ);
+ }
+ }
+ }
+ }
+
+ @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
+ public void onPlayerTeleport(PlayerTeleportEvent event) {
+ onPlayerMove(event);
+ }
+
+ private void handlePositionChanged(Player player, final World toWorld, final int toX, final int toY, final int toZ) {
+ if (LocationUtils.readGameSpawn() != null) {
+ VisualType visualType = VisualType.WORLD_BORDER;
+
+ PotionSG.getInst().getVisualiseHandler().clearVisualBlocks(player, visualType, new Predicate() {
+ public boolean apply(VisualBlock visualBlock) {
+ Location other = visualBlock.getLocation();
+ return (other.getWorld().equals(toWorld)) && ((Math.abs(toX - other.getBlockX()) > 5) || (Math.abs(toY - other.getBlockY()) > 4) || (Math.abs(toZ - other.getBlockZ()) > 5));
+ }
+ });
+ int minHeight = toY - 3;
+ int maxHeight = toY + 4;
+
+ double x = PotionSG.getInst().getRad();
+ double z = PotionSG.getInst().getRad();
+
+ Location loc1 = new Location(toWorld, LocationUtils.readGameSpawn().getX() + x, 0.0D, LocationUtils.readGameSpawn().getZ() - z);
+ Location loc2 = new Location(toWorld, LocationUtils.readGameSpawn().getX() - x, 0.0D, LocationUtils.readGameSpawn().getZ() + z);
+
+ Cuboid cb = new Cuboid(loc1, loc2);
+
+ Collection edges = cb.edges();
+ for (Vector edge : edges) {
+ if (Math.abs(edge.getBlockX() - toX) <= 5) {
+ if (Math.abs(edge.getBlockZ() - toZ) <= 5) {
+ Location location = edge.toLocation(toWorld);
+ if (location != null) {
+ Location first = location.clone();
+ first.setY(minHeight);
+ Location second = location.clone();
+ second.setY(maxHeight);
+
+ PotionSG.getInst().getVisualiseHandler().generate(player, new Cuboid(first, second), visualType, false).size();
+ }
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/me/weebo/listeners/WorldListeners.java b/src/main/java/me/weebo/listeners/WorldListeners.java
new file mode 100644
index 0000000..e9b4252
--- /dev/null
+++ b/src/main/java/me/weebo/listeners/WorldListeners.java
@@ -0,0 +1,33 @@
+package me.weebo.listeners;
+
+import me.weebo.PotionSG;
+import org.bukkit.entity.EntityType;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.entity.CreatureSpawnEvent;
+import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
+import org.bukkit.event.weather.WeatherChangeEvent;
+
+/*
+ * Listen to events related to worlds.
+ */
+public class WorldListeners implements Listener {
+
+ @EventHandler
+ public void spawn(CreatureSpawnEvent e) {
+ if (PotionSG.getInst().isStarted() && e.getEntityType() == EntityType.SILVERFISH && e.getSpawnReason() == SpawnReason.SILVERFISH_BLOCK) return;
+ e.setCancelled(true);
+ }
+
+ @EventHandler
+ public void weather(WeatherChangeEvent e) {
+ e.setCancelled(e.toWeatherState());
+ }
+
+ @SuppressWarnings("deprecation")
+ public static void LeavesDecayEvent(org.bukkit.event.block.LeavesDecayEvent e) {
+ e.getBlock().setData((byte) (e.getBlock().getData() % 4));
+ e.setCancelled(true);
+ }
+
+}
diff --git a/src/main/java/me/weebo/managers/Managers.java b/src/main/java/me/weebo/managers/Managers.java
new file mode 100644
index 0000000..0107322
--- /dev/null
+++ b/src/main/java/me/weebo/managers/Managers.java
@@ -0,0 +1,20 @@
+package me.weebo.managers;
+
+import lombok.Getter;
+import me.weebo.managers.types.*;
+
+/*
+ * Handles all "manager" classes.
+ */
+public class Managers {
+
+ @Getter private static ProfileManager profileManager = new ProfileManager();
+ @Getter private static PearlManager pearlManager = new PearlManager();
+ @Getter private static MapManager mapManager = new MapManager();
+ @Getter private static WorldManager worldManager = new WorldManager();
+ @Getter private static UpdatedInventoryManager updatedInventoryManager = new UpdatedInventoryManager();
+ @Getter private static LeaderboardManager leaderboardManager = new LeaderboardManager();
+ @Getter private static HostManager hostManager = new HostManager();
+ @Getter private static TasksManager tasksManager = new TasksManager();
+
+}
diff --git a/src/main/java/me/weebo/managers/scenarios/InventoryManager.java b/src/main/java/me/weebo/managers/scenarios/InventoryManager.java
new file mode 100644
index 0000000..5f5d8bd
--- /dev/null
+++ b/src/main/java/me/weebo/managers/scenarios/InventoryManager.java
@@ -0,0 +1,139 @@
+package me.weebo.managers.scenarios;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import me.weebo.PotionSG;
+import org.bukkit.Bukkit;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+public class InventoryManager {
+
+ public InventoryManager() {
+
+ }
+
+ public List getActiveScenarios() {
+ final ArrayList Lore = new ArrayList();
+ for (final Scenario scenario: PotionSG.getInstance().getScenarioManager().getActiveScenarios()) {
+ Lore.add(scenario.getName());
+ }
+ if (Lore.size() == 0) {
+ Lore.add("§cThere isn't any active scenarios!");
+ }
+ return Lore;
+ }
+
+ public List getWithStatus(Scenario scenario) {
+ final ArrayList Lore = new ArrayList();
+ for (final String value: scenario.getDescription()) {
+ Lore.add(value);
+ if (value.contains(".")) {
+ Lore.add("");
+ Lore.add("§fStatus: " + (scenario.isActive() ? "§aEnabled" : "§cDisabled"));
+ }
+ }
+ return Lore;
+ }
+ public List getWithNonStatus(Scenario scenario) {
+ final ArrayList Lore = new ArrayList();
+ for (final String value: scenario.getDescription()) {
+ Lore.add(value);
+ }
+ return Lore;
+ }
+
+ public void createScen(Player player, int step) {
+ switch (step) {
+ case 1: {
+ final Inventory inv1 = Bukkit.createInventory(null, 36, "§b§lHost a Game");
+ for (int x = 0; x < 9; x++) {
+ if (x == 4) {
+ continue;
+ }
+ if (x == 1) {
+ continue;
+ }
+ if (x == 7) {
+ continue;
+ }
+ this.createDisplay(new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 8), inv1, x, " ", null);
+ }
+
+ final ArrayList totalscen = new ArrayList<>();
+ totalscen.add("");
+ totalscen.add("§7There are only §3" + PotionSG.getInst().getScenarioManager().getScenarios().size() + " §7currently however more can be");
+ totalscen.add("§a§ladded §7to the server if there's any good suggestions");
+ totalscen.add("§7for §3PotSG §7related scenarios");
+ totalscen.add("");
+ totalscen.add("§3§lExplanation §fon §3Scenarios:");
+ totalscen.add("§3Scenarios §7are special events which modify a");
+ totalscen.add("§7certain §3aspect §fof the game");
+ totalscen.add("");
+ totalscen.add("§7Number of Scenarios Enabled: §a" + PotionSG.getInst().getScenarioManager().getActiveScenarios().size() + "§7/§f" + PotionSG.getInst().getScenarioManager().getScenarios().size());
+
+ final ArrayList teamsize = new ArrayList();
+ teamsize.add("§fCurrent TeamSize: §aFFA §7| §cTo2");
+ teamsize.add("§f");
+ teamsize.add("§3§lNOTE: §fAs of currently you");
+ teamsize.add("§c§lCANNOT §fmodify the §3Team Size");
+ teamsize.add("§fsince this feature is being §3worked");
+ teamsize.add("§3on §fto make sure there's no §3bugs");
+
+ this.createDisplay(new ItemStack(Material.REDSTONE, 1, (short) 14), inv1, 4, "§cDisable All Scenarios", null);
+ this.createDisplay(new ItemStack(Material.BOOK, 1, (short) 14), inv1, 1, "§f* §3§lScenarios §f*", totalscen);
+ this.createDisplay(new ItemStack(Material.DIAMOND_CHESTPLATE, 0, (short) -1), inv1, 7, "§bTeam Size",teamsize);
+ int count = 9;
+ for (final Scenario scenario : PotionSG.getInst().getScenarioManager().getScenarios()) {
+ this.createDisplay(new ItemStack(scenario.getItem()), inv1, count, scenario.getName(), getWithStatus(scenario));
+ ++count;
+ }
+ for (int x = 27; x < 36; x++) {
+ if (x == 31) {
+ continue;
+ }
+ this.createDisplay(new ItemStack(Material.EMERALD, 0, (short) -1), inv1, 31, "§a§lHost Game",null);
+ this.createDisplay(new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 8), inv1, x, " ", null);
+ }
+ player.openInventory(inv1);
+ return;
+ }
+ case 2: {
+ final Inventory inv2 = Bukkit.createInventory(null, 27, "§3§lGame Information");
+ final ArrayList gameinfo = new ArrayList();
+ gameinfo.add("§f");
+ gameinfo.add("§fTeam Size: §3FFA");
+ gameinfo.add("§fNumber of scenarios enabled: §3" + PotionSG.getInst().getScenarioManager().getActiveScenarios().size() + "§7/§f" + PotionSG.getInst().getScenarioManager().getScenarios().size());
+ gameinfo.add("§3Scenarios §faffects a certain aspect of the game");
+ gameinfo.add("§fThe §3scenarios information §fwill be listed below via §3items");
+ this.createDisplay(new ItemStack(Material.BOOK, 1, (short) 14), inv2, 4, "§f* §3§lGame Information §f*", gameinfo);
+ int count = 9;
+ for (final Scenario scenario : PotionSG.getInst().getScenarioManager().getActiveScenarios()) {
+ this.createDisplay(new ItemStack(scenario.getItem()), inv2, count, scenario.getName(), getWithNonStatus(scenario));
+ ++count;
+ }
+ player.openInventory(inv2);
+ return;
+ }
+ }
+ }
+
+ public void createDisplay(ItemStack redwool, Inventory inv, int Slot, String name, Collection lore) {
+ final ItemStack item = new ItemStack(redwool);
+ final ItemMeta meta = item.getItemMeta();
+ meta.setDisplayName(name);
+ final ArrayList Lore = new ArrayList();
+ if (lore != null) {
+ Lore.addAll(lore);
+ meta.setLore(Lore);
+ }
+ item.setItemMeta(meta);
+ inv.setItem(Slot, item);
+ }
+
+}
diff --git a/src/main/java/me/weebo/managers/scenarios/Scenario.java b/src/main/java/me/weebo/managers/scenarios/Scenario.java
new file mode 100644
index 0000000..d8aca69
--- /dev/null
+++ b/src/main/java/me/weebo/managers/scenarios/Scenario.java
@@ -0,0 +1,27 @@
+package me.weebo.managers.scenarios;
+
+import org.bukkit.Material;
+
+public interface Scenario {
+
+ default String getName() {
+ return null;
+ }
+
+ default Material getItem() {
+ return null;
+ }
+
+ default String[] getDescription() {
+ return null;
+ }
+
+ default void setActive(boolean active) {
+ return;
+ }
+
+ default boolean isActive() {
+ return false;
+ }
+
+}
diff --git a/src/main/java/me/weebo/managers/scenarios/ScenarioManager.java b/src/main/java/me/weebo/managers/scenarios/ScenarioManager.java
new file mode 100644
index 0000000..3fbeac6
--- /dev/null
+++ b/src/main/java/me/weebo/managers/scenarios/ScenarioManager.java
@@ -0,0 +1,52 @@
+package me.weebo.managers.scenarios;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import lombok.Getter;
+import me.weebo.scenarios.Enchanter;
+import me.weebo.scenarios.NoFire;
+import me.weebo.scenarios.PreEnchants;
+import me.weebo.scenarios.Soup;
+
+
+public class ScenarioManager {
+
+ @Getter
+ List scenarios;
+
+ public ScenarioManager() {
+ scenarios = new ArrayList();
+ scenarios.add(new NoFire());
+ scenarios.add(new PreEnchants());
+ scenarios.add(new Soup());
+ scenarios.add(new Enchanter());
+ }
+ public List getActiveScenarios() {
+ final List list = new ArrayList();
+ for (final Scenario scenario: scenarios) {
+ if (scenario.isActive()) {
+ list.add(scenario);
+ }
+ }
+ return list;
+ }
+ public List getActiveScenarioNames() {
+ final List list = new ArrayList();
+ for (final Scenario scenario: scenarios) {
+ if (scenario.isActive()) {
+ list.add(scenario.getName());
+ }
+ }
+ return list;
+ }
+ public Scenario getScenario(String name) {
+ for (Scenario scenario: scenarios) {
+ if (name.equalsIgnoreCase(scenario.getName().replaceAll(" ", ""))) {
+ return scenario;
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/src/main/java/me/weebo/managers/types/HostManager.java b/src/main/java/me/weebo/managers/types/HostManager.java
new file mode 100644
index 0000000..4c7bbee
--- /dev/null
+++ b/src/main/java/me/weebo/managers/types/HostManager.java
@@ -0,0 +1,39 @@
+package me.weebo.managers.types;
+
+import lombok.Getter;
+import me.weebo.PotionSG;
+import org.bukkit.scheduler.BukkitRunnable;
+
+public class HostManager {
+
+ private final int TARGET_PLAYERS;
+ @Getter private static int additionalTime;
+
+ public HostManager() {
+ this.TARGET_PLAYERS = 10;
+ }
+
+ public void check() {
+ if (PotionSG.getInst().getPlayersWaiting().size() == TARGET_PLAYERS) startTask();
+ }
+
+ private void startTask() {
+ this.additionalTime = 120;
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ if (!PotionSG.getInst().isStarted() && PotionSG.getInst().getPlayersWaiting().size() >= TARGET_PLAYERS) {
+ if (additionalTime != 0) additionalTime--;
+ else {
+ PotionSG.getInst().start();
+ cancel();
+ }
+ } else {
+ additionalTime = 0;
+ cancel();
+ }
+ }
+ }.runTaskTimer(PotionSG.getInst(), 0L, 20L);
+ }
+
+}
diff --git a/src/main/java/me/weebo/managers/types/LeaderboardManager.java b/src/main/java/me/weebo/managers/types/LeaderboardManager.java
new file mode 100644
index 0000000..de5c401
--- /dev/null
+++ b/src/main/java/me/weebo/managers/types/LeaderboardManager.java
@@ -0,0 +1,96 @@
+package me.weebo.managers.types;
+
+import lombok.Getter;
+import me.weebo.utilities.C;
+import me.weebo.utilities.EasyItem;
+import me.weebo.utilities.FileUtils;
+import org.bukkit.Bukkit;
+import org.bukkit.Material;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+
+import java.util.*;
+
+import static java.util.stream.Collectors.toMap;
+
+public class LeaderboardManager {
+
+ @Getter private Map killsLB, winsLB;
+
+ public LeaderboardManager() {
+ killsLB = new HashMap<>();
+ winsLB = new HashMap<>();
+ updateWins();
+ updateKills();
+ }
+
+ public void openLeaderboard(Player p) {
+ Inventory inv = Bukkit.createInventory(null, 45, C.GUI_TITLE_COLOR + "Leaderboard");
+ inv.setItem(13, new EasyItem(Material.SKULL_ITEM).setName(C.GUI_MAIN_COLOR + "Your Statistics").setLore(C.GUI_FIRST_COLOR + "Kills: " + C.GUI_SECONDARY_COLOR + getKills(p.getUniqueId()), C.GUI_FIRST_COLOR + "Wins: " + C.GUI_SECONDARY_COLOR + getWins(p.getUniqueId())).setId((short) 3).build());
+ EasyItem kills = new EasyItem(Material.DIAMOND_SWORD).setName(C.GUI_MAIN_COLOR + "Top 10 Killers");
+ EasyItem wins = new EasyItem(Material.NETHER_STAR).setName(C.GUI_MAIN_COLOR + "Top 10 Winners");
+ int i = 1;
+ for (Map.Entry e : killsLB.entrySet()) {
+ if (i > 10) break;
+ kills.addLore(C.GUI_FIRST_COLOR + i + ". " + C.GUI_SECONDARY_COLOR + Bukkit.getOfflinePlayer(e.getKey()).getName() + C.GUI_THIRD_COLOR + " (" + e.getValue() + (e.getValue() == 1 ? " kill)" : " kills)"));
+ i++;
+ }
+ i = 1;
+ for (Map.Entry e : winsLB.entrySet()) {
+ if (i > 10) break;
+ wins.addLore(C.GUI_FIRST_COLOR + i + ". " + C.GUI_SECONDARY_COLOR + Bukkit.getOfflinePlayer(e.getKey()).getName() + C.GUI_THIRD_COLOR + " (" + e.getValue() + (e.getValue() == 1 ? " win)" : " wins)"));
+ i++;
+ }
+ inv.setItem(29, kills.build());
+ inv.setItem(33, wins.build());
+ p.openInventory(inv);
+ }
+
+ private void load() {
+ FileConfiguration fileconfig = FileUtils.getPlayerDataYML();
+ for (String s : fileconfig.getConfigurationSection("").getKeys(false)) killsLB.put(UUID.fromString(s), getKills(UUID.fromString(s)));
+ for (String s : fileconfig.getConfigurationSection("").getKeys(false)) winsLB.put(UUID.fromString(s), getWins(UUID.fromString(s)));
+ }
+
+ private void updateWins() {
+ load();
+ winsLB = winsLB.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByValue())).collect(toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e2, LinkedHashMap::new));
+ }
+
+ private void updateKills() {
+ load();
+ killsLB = killsLB.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByValue())).collect(toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e2, LinkedHashMap::new));
+ }
+
+ public int getKills(UUID id) {
+ FileConfiguration fileconfig = FileUtils.getPlayerDataYML();
+ return fileconfig.getInt(id.toString() + ".kills", 0);
+ }
+
+ public int getWins(UUID id) {
+ FileConfiguration fileconfig = FileUtils.getPlayerDataYML();
+ return fileconfig.getInt(id.toString() + ".wins", 0);
+ }
+
+ private void saveKills(UUID id, int kills) {
+ FileConfiguration fileconfig = FileUtils.getPlayerDataYML();
+ fileconfig.set(id.toString() + ".kills", kills);
+ FileUtils.saveProfilesFile();
+ }
+ private void saveWins(UUID id, int wins) {
+ FileConfiguration fileconfig = FileUtils.getPlayerDataYML();
+ fileconfig.set(id.toString() + ".wins", wins);
+ FileUtils.saveProfilesFile();
+ }
+
+ public void addKill(UUID id) {
+ saveKills(id, getKills(id) + 1);
+ updateKills();
+ }
+
+ public void addWin(UUID id) {
+ saveWins(id, getWins(id) + 1);
+ updateWins();
+ }
+}
diff --git a/src/main/java/me/weebo/managers/types/MapManager.java b/src/main/java/me/weebo/managers/types/MapManager.java
new file mode 100644
index 0000000..5d8eaa4
--- /dev/null
+++ b/src/main/java/me/weebo/managers/types/MapManager.java
@@ -0,0 +1,209 @@
+package me.weebo.managers.types;
+
+import lombok.Getter;
+import me.weebo.managers.Managers;
+import me.weebo.scenarios.Soup;
+import me.weebo.utilities.C;
+import me.weebo.utilities.EasyItem;
+import me.weebo.utilities.FileUtils;
+import me.weebo.utilities.LocationUtils;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.block.Chest;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.enchantments.Enchantment;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.EnchantmentStorageMeta;
+import org.bukkit.potion.PotionType;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * Manages maps.
+ */
+public class MapManager {
+
+ @Getter
+ private List arenas;
+ @Getter
+ private List chests;
+ Soup soup = null;
+ private ItemStack[] items, feastItems, soupItems, feastSoupItems;
+
+ public MapManager() {
+ arenas = new ArrayList<>();
+ chests = new ArrayList<>();
+ soupItems = new ItemStack[]{
+ new EasyItem(Material.ARROW).setAmount(16).build(),
+ new EasyItem(Material.BOW).build(),
+ new EasyItem(Material.COOKED_BEEF).setAmount(8).build(),
+ new EasyItem(Material.DIAMOND).setAmount(5).build(),
+ new EasyItem(Material.DIAMOND_SWORD).build(),
+ createEnchantedBook(Enchantment.DAMAGE_ALL, 1),
+ createEnchantedBook(Enchantment.ARROW_DAMAGE, 1),
+ createEnchantedBook(Enchantment.PROTECTION_ENVIRONMENTAL, 1),
+ new EasyItem(Material.ENDER_PEARL).setAmount(3).build(),
+ new EasyItem(Material.EXP_BOTTLE).setAmount(10).build(),
+ new EasyItem(Material.FLINT_AND_STEEL).build(),
+ new EasyItem(Material.GLOWSTONE_DUST).setAmount(5).build(),
+ new EasyItem(Material.SULPHUR).setAmount(5).build(),
+ new EasyItem(Material.GOLDEN_APPLE).setAmount(2).build(),
+ new EasyItem(Material.GOLDEN_CARROT).setAmount(8).build(),
+// new EasyItem(Material.IRON_INGOT).setAmount(10).build(),
+ new EasyItem(Material.MUSHROOM_SOUP).setAmount(5).build(),
+ new EasyItem(Material.MUSHROOM_SOUP).setAmount(5).build(),
+ new EasyItem(Material.MUSHROOM_SOUP).setAmount(5).build(),
+ new EasyItem(Material.MUSHROOM_SOUP).build(),
+ new EasyItem(Material.WEB).setAmount(3).build()};
+ items = new ItemStack[]{
+ new EasyItem(Material.ARROW).setAmount(16).build(),
+ new EasyItem(Material.BOW).build(),
+ new EasyItem(Material.COOKED_BEEF).setAmount(8).build(),
+ new EasyItem(Material.DIAMOND).setAmount(5).build(),
+ new EasyItem(Material.DIAMOND_SWORD).build(),
+ createEnchantedBook(Enchantment.DAMAGE_ALL, 1),
+ createEnchantedBook(Enchantment.ARROW_DAMAGE, 1),
+ createEnchantedBook(Enchantment.PROTECTION_ENVIRONMENTAL, 1),
+ new EasyItem(Material.ENDER_PEARL).setAmount(3).build(),
+ new EasyItem(Material.EXP_BOTTLE).setAmount(10).build(),
+ new EasyItem(Material.FLINT_AND_STEEL).build(),
+ new EasyItem(Material.GLOWSTONE_DUST).setAmount(5).build(),
+ new EasyItem(Material.SULPHUR).setAmount(5).build(),
+ new EasyItem(Material.GOLDEN_APPLE).setAmount(2).build(),
+ new EasyItem(Material.GOLDEN_CARROT).setAmount(8).build(),
+// new EasyItem(Material.IRON_INGOT).setAmount(10).build(),
+ new EasyItem(Material.POTION).setId((short) 16421).setAmount(5).build(),
+ new EasyItem(Material.POTION).setId((short) 16453).setAmount(5).build(),
+ new EasyItem(Material.POTION).setId((short) 8229).setAmount(5).build(),
+ new EasyItem(Material.POTION).setId((short) 8194).build(),
+ new EasyItem(Material.WEB).setAmount(3).build()};
+ feastSoupItems = new ItemStack[]{
+ new EasyItem(Material.ARROW).setAmount(32).build(),
+ new EasyItem(Material.BOW).addEnchant(Enchantment.ARROW_DAMAGE, 3).build(),
+ new EasyItem(Material.DIAMOND).setAmount(6).build(),
+ new EasyItem(Material.DIAMOND_SWORD).addEnchant(Enchantment.FIRE_ASPECT, 1).build(),
+ new EasyItem(Material.ENDER_PEARL).setAmount(5).build(),
+ new EasyItem(Material.EXP_BOTTLE).setAmount(10).build(),
+ new EasyItem(Material.FLINT_AND_STEEL).build(),
+ new EasyItem(Material.GOLDEN_APPLE).setAmount(3).build(),
+ new EasyItem(Material.MUSHROOM_SOUP).setId((short) 16421).setAmount(5).build(),
+ new EasyItem(Material.MUSHROOM_SOUP).setId((short) 16426).build(),
+ new EasyItem(Material.MUSHROOM_SOUP).setId((short) 16388).build(),
+ new EasyItem(Material.POTION).setId((short) 8226).build(),
+ new EasyItem(Material.POTION).setId((short) 8259).build(),
+ new EasyItem(Material.TNT).setAmount(3).build(),
+ new EasyItem(Material.WEB).setAmount(5).build()};
+ feastItems = new ItemStack[]{
+ new EasyItem(Material.ARROW).setAmount(32).build(),
+ new EasyItem(Material.BOW).addEnchant(Enchantment.ARROW_DAMAGE, 3).build(),
+ new EasyItem(Material.DIAMOND).setAmount(6).build(),
+ new EasyItem(Material.DIAMOND_SWORD).addEnchant(Enchantment.FIRE_ASPECT, 1).build(),
+ new EasyItem(Material.ENDER_PEARL).setAmount(5).build(),
+ new EasyItem(Material.EXP_BOTTLE).setAmount(10).build(),
+ new EasyItem(Material.FLINT_AND_STEEL).build(),
+ new EasyItem(Material.GOLDEN_APPLE).setAmount(3).build(),
+ new EasyItem(Material.POTION).setId((short) 16421).setAmount(5).build(),
+ new EasyItem(Material.POTION).setId((short) 16426).build(),
+ new EasyItem(Material.POTION).setId((short) 16388).build(),
+ new EasyItem(Material.POTION).setId((short) 8226).build(),
+ new EasyItem(Material.POTION).setId((short) 8259).build(),
+ new EasyItem(Material.TNT).setAmount(3).build(),
+ new EasyItem(Material.WEB).setAmount(5).build()};
+ }
+
+ private ItemStack createEnchantedBook(Enchantment ench, int level) {
+ ItemStack i = new ItemStack(Material.ENCHANTED_BOOK);
+ EnchantmentStorageMeta e = (EnchantmentStorageMeta) i.getItemMeta();
+ e.addStoredEnchant(ench, level, false);
+ i.setItemMeta(e);
+ return i;
+ }
+
+ public boolean chestIsOpened(Chest chest) {
+ return chests.contains(chest);
+ }
+
+ public void addArena(String name, Player p) {
+ if (!arenas.contains(name)) {
+ arenas.add(name);
+ LocationUtils.saveGameSpawn(p.getLocation(), name);
+ C.c(p, "&aYou have successfully created an arena named \"" + name + "\" and your current location will be the spawn of it.");
+ C.c(p, "&eWe have to make a backup of this world, expect lag!");
+ Managers.getWorldManager().saveRebuild(p.getLocation(), true);
+ } else C.c(p, "&e\u26A0 &cAn arena with that name already exists!");
+ }
+
+ public void removeArena(String name, Player p) {
+ if (arenas.contains(name)) {
+ arenas.remove(name);
+ LocationUtils.saveGameSpawn(null, name);
+ C.c(p, "&aYou have successfully removed that arena.");
+ } else C.c(p, "&e\u26A0 &cThat arena does not exist!");
+ }
+
+ public void loadArenas() {
+ YamlConfiguration config = FileUtils.getArenasYML();
+ if (config.getConfigurationSection("arenas") != null) {
+ for (String name : config.getConfigurationSection("arenas").getKeys(false)) arenas.add(name);
+ }
+ }
+
+ public void dropFeastItems(Location loc) {
+ Random rand = new Random();
+ for (int i = 0; i < new Random().nextInt(2) + 6; i++) {
+ ItemStack item = feastItems[rand.nextInt(feastItems.length)].clone();
+ item.setAmount(rand.nextInt(item.getAmount()) + 1);
+ loc.getWorld().dropItemNaturally(loc, item);
+ }
+ }
+
+ public void fillChest(Chest chest) {
+ Random rand = new Random();
+ chest.getInventory().clear();
+ for (int i = 0; i < rand.nextInt(2) + 5; i++) {
+ ItemStack item = items[rand.nextInt(items.length)].clone();
+ item.setAmount(rand.nextInt(item.getAmount()) + 1);
+ if ((item.getType() == Material.BOW || item.getType() == Material.FLINT_AND_STEEL || item.getType() == Material.DIAMOND_SWORD || item.getType() == Material.ENCHANTED_BOOK) &&
+ (chest.getInventory().contains(Material.BOW) || chest.getInventory().contains(Material.FLINT_AND_STEEL) || chest.getInventory().contains(Material.DIAMOND_SWORD) || chest.getInventory().contains(Material.ENCHANTED_BOOK))) {
+ i++;
+ continue;
+ }
+ chest.getInventory().addItem(item);
+ }
+ if (!chest.getInventory().contains(items[3].getType()) && rand.nextInt(10) < 8) {
+ ItemStack it = items[3].clone();
+ it.setAmount(rand.nextInt(it.getAmount()) + 1);
+ chest.getInventory().addItem(it);
+ }
+ if (!chest.getInventory().contains(items[15].getType())) {
+ ItemStack it = items[15].clone();
+ it.setAmount(rand.nextInt(it.getAmount()) + 1);
+ chest.getInventory().addItem(it);
+ if (rand.nextInt(10) < 3) {
+ ItemStack i = items[16].clone();
+ i.setAmount(rand.nextInt(i.getAmount()) + 1);
+ chest.getInventory().addItem(i);
+ }
+ }
+ chests.add(chest);
+ }
+
+ public void resetMap(Location loc) {
+ chests.clear();
+ Managers.getWorldManager().saveRebuild(loc, false);
+ }
+
+ public void replaceItems(Chest chest, Material m, int amount) {
+ if (soup.isActive()) {
+ if (Material.POTION.getData().equals(PotionType.INSTANT_HEAL)) {
+
+ }
+
+ }
+ }
+}
+
+
diff --git a/src/main/java/me/weebo/managers/types/PearlManager.java b/src/main/java/me/weebo/managers/types/PearlManager.java
new file mode 100644
index 0000000..9997f2e
--- /dev/null
+++ b/src/main/java/me/weebo/managers/types/PearlManager.java
@@ -0,0 +1,55 @@
+package me.weebo.managers.types;
+
+import java.text.DecimalFormat;
+import java.util.HashMap;
+import java.util.Map;
+
+import me.weebo.PotionSG;
+import me.weebo.utilities.C;
+import org.bukkit.entity.Player;
+import org.bukkit.scheduler.BukkitRunnable;
+
+import lombok.Getter;
+
+/*
+ * Manages ender pearls.
+ */
+public class PearlManager {
+
+ @Getter private Map m;
+
+ public PearlManager() {
+ m = new HashMap<>();
+ }
+
+ public void addPearlCooldown(Player p) {
+ m.put(p.getName(), System.currentTimeMillis());
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ if (p.isOnline()) removePearlCooldown(p, true);
+ }
+ }.runTaskLater(PotionSG.getInst(), 16 * 20L);
+ }
+
+ public void removePearlCooldown(Player p, boolean b) {
+ if (isInCooldown(p)) {
+ m.remove(p.getName());
+ if (b) C.c(p, C.CHAT_SECONDARY + "Your pearl cooldown has expired.");
+ }
+ }
+
+ public boolean isInCooldown(Player p) {
+ return m.containsKey(p.getName());
+ }
+
+ public long getCooldown(Player p) {
+ return m.get(p.getName()) + 16000L - System.currentTimeMillis();
+ }
+
+ public String getCooldownIn1DP(Player p) {
+ DecimalFormat value = new DecimalFormat("#.#");
+ return value.format(getCooldown(p) / 1000.0);
+ }
+
+}
diff --git a/src/main/java/me/weebo/managers/types/ProfileManager.java b/src/main/java/me/weebo/managers/types/ProfileManager.java
new file mode 100644
index 0000000..8238d9f
--- /dev/null
+++ b/src/main/java/me/weebo/managers/types/ProfileManager.java
@@ -0,0 +1,36 @@
+package me.weebo.managers.types;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import me.weebo.players.Profile;
+import org.bukkit.entity.Player;
+
+import lombok.Getter;
+
+/*
+ * Manages profiles.
+ */
+public class ProfileManager {
+
+ @Getter private List profiles;
+
+ public ProfileManager() {
+ profiles = new ArrayList<>();
+ }
+
+ public Profile getProfile(UUID id) {
+ for (Profile p : profiles) if (p.getId().equals(id)) return p;
+ return null;
+ }
+
+ public void createProfile(Player p) {
+ profiles.add(new Profile(p.getUniqueId()));
+ }
+
+ public void removeProfile(Player p) {
+ profiles.remove(getProfile(p.getUniqueId()));
+ }
+
+}
diff --git a/src/main/java/me/weebo/managers/types/SidebarManager.java b/src/main/java/me/weebo/managers/types/SidebarManager.java
new file mode 100644
index 0000000..f75abbd
--- /dev/null
+++ b/src/main/java/me/weebo/managers/types/SidebarManager.java
@@ -0,0 +1,121 @@
+package me.weebo.managers.types;
+
+import me.missionary.board.provider.BoardProvider;
+import me.weebo.PotionSG;
+import me.weebo.managers.Managers;
+import me.weebo.utilities.C;
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.entity.Player;
+import me.weebo.managers.scenarios.Scenario;
+import me.weebo.managers.scenarios.ScenarioManager;
+
+import java.lang.management.ManagementFactory;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+/*
+ * Manages sidebar (scoreboard).
+ */
+public class SidebarManager implements BoardProvider {
+
+ @Override
+ public String getTitle(Player player) {
+ return C.TITLE + C.SERVER_NAME + C.SB_SEPARATOR + C.SEASON;
+ }
+
+ @Override
+ public List getLines(Player player) {
+ List lines = new ArrayList<>();
+ lines.add("&7&m--------------------");
+ if (Managers.getProfileManager().getProfile(player.getUniqueId()).isInLobby()) {
+ lines.add(C.MAIN + "Online: " + C.SB_SECONDARY + Bukkit.getOnlinePlayers().size());
+ if (PotionSG.getInst().isInCooldown()) lines.add(C.MAIN + "Next game in " + C.SB_SECONDARY + formatTime(PotionSG.getInst().getCooldownTimer() + 1));
+ if (Managers.getHostManager().getAdditionalTime() != 0) lines.add(C.MAIN + "Game starts in " + C.SB_SECONDARY + formatTime(Managers.getHostManager().getAdditionalTime()));
+ if (Managers.getProfileManager().getProfile(player.getUniqueId()).isBuild()) {
+ lines.add("");
+ lines.add("&e&lIN BUILD MODE");
+ }
+ if (PotionSG.getInst().isWaiting() || PotionSG.getInst().isStarted()) {
+ lines.add("&7&m--------------------");
+ lines.add(C.TITLE + "&lGame " + (PotionSG.getInst().isWaiting() ? "&7(Waiting)" : "&7(Started)"));
+ lines.add(C.MAIN + " Host: " + C.SB_SECONDARY + PotionSG.getInst().getHost());
+ lines.add(C.MAIN + (PotionSG.getInst().isWaiting() ? " Players: " + C.SB_SECONDARY + PotionSG.getInst().getPlayersWaiting().size(): " Remaining: " + C.SB_SECONDARY + PotionSG.getInst().getPlayersInGame().size()) );
+ }
+ } else if (Managers.getProfileManager().getProfile(player.getUniqueId()).isWaiting()) {
+ lines.add(C.MAIN + "Online: " + C.SB_SECONDARY + Bukkit.getOnlinePlayers().size());
+ if (PotionSG.getInst().isInCooldown()) lines.add(C.MAIN + "Next game in " + C.SB_SECONDARY + formatTime(PotionSG.getInst().getCooldownTimer() + 1));
+ if (Managers.getHostManager().getAdditionalTime() != 0) lines.add(C.MAIN + "Game starts in " + C.SB_SECONDARY + formatTime(Managers.getHostManager().getAdditionalTime()));
+ if (Managers.getProfileManager().getProfile(player.getUniqueId()).isBuild()) {
+ lines.add("");
+ lines.add("&e&lIN BUILD MODE");
+ }
+ if (PotionSG.getInst().isWaiting() || PotionSG.getInst().isStarted()) {
+ lines.add("&7&m--------------------");
+ lines.add("&fGame " + C.SB_SECONDARY + "PotSG-1" + " &7(Waiting)");
+ lines.add(C.MAIN + " Host: " + C.SB_SECONDARY + PotionSG.getInst().getHost());
+ lines.add(C.MAIN + " Players: " + C.SB_SECONDARY + PotionSG.getInst().getPlayersWaiting().size());
+ lines.add(C.MAIN + " Team Size: " + C.SB_SECONDARY + "FFA");
+ ScenarioManager smanager = PotionSG.getInstance().getScenarioManager();
+ if (smanager.getActiveScenarios().size() > 0) {
+ lines.add("");
+ lines.add(C.MAIN + "Scenarios: ");
+ for (Scenario param: smanager.getActiveScenarios()) {
+ lines.add(ChatColor.GRAY + "- " + ChatColor.DARK_AQUA + param.getName());
+ }
+ }
+ }
+ } else if (Managers.getProfileManager().getProfile(player.getUniqueId()).isInGame() || Managers.getProfileManager().getProfile(player.getUniqueId()).isSpectating()) {
+ if (PotionSG.getInst().getStartTimer() > 0) {
+ lines.add(C.MAIN + "Game starts in " + C.SB_SECONDARY + ((int) PotionSG.getInst().getStartTimer() + 1) + C.MAIN + "...");
+ } else {
+ lines.add(C.MAIN + "Game Time: " + C.SB_SECONDARY + formatTime(PotionSG.getInst().getGameTimer() + 1));
+ lines.add(C.MAIN + "Players Alive: " + C.SB_SECONDARY + PotionSG.getInst().getPlayersInGame().size());
+ lines.add(C.MAIN + "Spectators: " + C.SB_SECONDARY + PotionSG.getInst().getSpectators().size());
+ //lines.add(C.MAIN + "Kills: " + C.SB_SECONDARY + "0");
+
+ if (PotionSG.getInst().getPvpTimer() > -1) {
+ lines.add("");
+ lines.add(C.MAIN + "PvP Enables in " + C.SB_SECONDARY + formatTime(PotionSG.getInst().getPvpTimer() + 1));
+ }
+ else if (PotionSG.getInst().getFeastTimer() > -1) {
+ lines.add("");
+ lines.add(C.MAIN + "Feast: " + C.SB_SECONDARY + formatTime(PotionSG.getInst().getFeastTimer() + 1));
+ }
+ else if (PotionSG.getInst().getBorderTimer() > -1) {
+ lines.add("");
+ lines.add(C.MAIN + "Border: " + C.SB_SECONDARY + PotionSG.getInst().getRad() + (PotionSG.getInst().getRad() > PotionSG.getInst().getTargetRad() ? " (" + PotionSG.getInst().getBorderTimer() + ")" : ""));
+ }
+ }
+ }
+ lines.add("");
+ lines.add(C.SB_IP_COLOR + C.SERVER_IP);
+ lines.add("&7&m--------------------");
+ return lines;
+ }
+
+ @SuppressWarnings("restriction")
+ private String getMemory() {
+ Runtime r = Runtime.getRuntime();
+ DecimalFormat df = new DecimalFormat("#.#");
+ String used = df.format((r.totalMemory() - r.freeMemory()) / 1073741824D);
+ String total = df.format(((com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean()).getTotalPhysicalMemorySize() / 1073741824D);
+ return used + "/" + total + " GB";
+ }
+
+ private String formatTime(int time) {
+ final int min = time / 60;
+ final int sec = time % 60;
+
+ final String strMin = zero(min);
+ final String strSec = zero(sec);
+
+ return String.format("%s:%s",strMin,strSec);
+ }
+
+ private String zero(int number) {
+ return (number >=10)? Integer.toString(number):String.format("0%s",Integer.toString(number));
+ }
+
+}
diff --git a/src/main/java/me/weebo/managers/types/TasksManager.java b/src/main/java/me/weebo/managers/types/TasksManager.java
new file mode 100644
index 0000000..3d87e15
--- /dev/null
+++ b/src/main/java/me/weebo/managers/types/TasksManager.java
@@ -0,0 +1,26 @@
+package me.weebo.managers.types;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import me.weebo.PotionSG;
+import me.weebo.tasks.GameTask;
+import org.bukkit.Bukkit;
+import org.bukkit.scheduler.BukkitTask;
+
+import lombok.Getter;
+
+public class TasksManager {
+
+ @Getter
+ public Map scheduledTasks = new HashMap<>();
+
+ public void schedule(String id, GameTask run, long time, long repeat) {
+ scheduledTasks.put(id, Bukkit.getScheduler().runTaskTimer(PotionSG.getInstance(), run, time, repeat));
+ }
+
+ public void stop(String id) {
+ scheduledTasks.remove(id).cancel();
+ }
+
+}
diff --git a/src/main/java/me/weebo/managers/types/UpdatedInventoryManager.java b/src/main/java/me/weebo/managers/types/UpdatedInventoryManager.java
new file mode 100644
index 0000000..bea1b7d
--- /dev/null
+++ b/src/main/java/me/weebo/managers/types/UpdatedInventoryManager.java
@@ -0,0 +1,43 @@
+package me.weebo.managers.types;
+
+import java.util.List;
+
+import me.weebo.PotionSG;
+import me.weebo.utilities.C;
+import me.weebo.utilities.EasyItem;
+import org.bukkit.Bukkit;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.scheduler.BukkitRunnable;
+
+import lombok.Getter;
+
+public class UpdatedInventoryManager extends BukkitRunnable {
+
+ @Getter private Inventory spectateList;
+
+ public UpdatedInventoryManager() {
+ spectateList = Bukkit.createInventory(null, 54, C.c(C.GUI_TITLE_COLOR + "Teleport to..."));
+ runTaskTimer(PotionSG.getInst(), 0L, 20L);
+ }
+
+ @Override
+ public void run() {
+ if (PotionSG.getInst().isStarted()) {
+ spectateList.clear();
+ List list = PotionSG.getInst().getPlayersInGame();
+ for (int i = 0; i < list.size(); i++) spectateList.setItem(i, new EasyItem(Material.SKULL_ITEM).setId((short) 3).setName(C.CHAT_SECONDARY + list.get(i).getName()).build());
+ }
+ }
+
+// private int size(int original) {
+// if (original < 10) return 9;
+// else if (original < 19) return 18;
+// else if (original < 28) return 27;
+// else if (original < 37) return 36;
+// else if (original < 46) return 45;
+// else return 54;
+// }
+
+}
diff --git a/src/main/java/me/weebo/managers/types/WorldManager.java b/src/main/java/me/weebo/managers/types/WorldManager.java
new file mode 100644
index 0000000..e19758b
--- /dev/null
+++ b/src/main/java/me/weebo/managers/types/WorldManager.java
@@ -0,0 +1,86 @@
+package me.weebo.managers.types;
+
+import me.weebo.PotionSG;
+import me.weebo.utilities.C;
+import me.weebo.utilities.WorldUtils;
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.GameMode;
+import org.bukkit.Location;
+import org.bukkit.entity.Player;
+
+public class WorldManager {
+
+ private boolean success;
+ private String world;
+ private Player[] playerInWorldn;
+ private Location[] playerInWorldLocn;
+ private GameMode[] playerInWorldGMn;
+
+ public void saveRebuild(Location loc, boolean save) {
+ world = loc.getWorld().getName();
+ Bukkit.getScheduler().runTask(PotionSG.getInst(), new Runnable() {
+ @SuppressWarnings("deprecation")
+ public void run() {
+ C.c(Bukkit.getConsoleSender(), ChatColor.GOLD + (save ? "Saving" : "Rebuilding") + " the world '" + loc.getWorld() + "...");
+ Player[] playerInWorld = new Player[Bukkit.getOnlinePlayers().size()];
+ Location[] playerInWorldLoc = new Location[Bukkit.getOnlinePlayers().size()];
+ GameMode[] playerInWorldLGM = new GameMode[Bukkit.getOnlinePlayers().size()];
+ int i = 0;
+ if (loc.getWorld().equals(Bukkit.getServer().getWorlds().get(0))) C.c(Bukkit.getConsoleSender(), ChatColor.RED + "Cannot backup the world as it is the default world!");
+ else {
+ Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), "mv load " + world);
+ for (Player pInWorld : Bukkit.getServer().getOnlinePlayers()) {
+ if (pInWorld.getWorld().equals(loc.getWorld())) {
+ playerInWorld[i] = pInWorld;
+ playerInWorldLoc[i] = pInWorld.getLocation();
+ playerInWorldLGM[i] = pInWorld.getGameMode();
+ Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), "mvtp " + pInWorld.getName() + " e:" + Bukkit.getServer().getWorlds().get(0).getName() + ":" + Bukkit.getServer().getWorlds().get(0).getSpawnLocation().getX() + "," + Bukkit.getServer().getWorlds().get(0).getSpawnLocation().getY() + "," + Bukkit.getServer().getWorlds().get(0).getSpawnLocation().getZ());
+ }
+ i++;
+ }
+ }
+ Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), "mv unload " + world);
+ if (save) success = WorldUtils.copy(world, world + "_default#backup");
+ else success = WorldUtils.copy(world + "_default#backup", world);
+ playerInWorldLocn = playerInWorldLoc;
+ playerInWorldn = playerInWorld;
+ playerInWorldGMn = playerInWorldLGM;
+ Bukkit.getScheduler().runTask(PotionSG.getInst(), new Runnable() {
+ Player[] playerInWorld = playerInWorldn;
+ Location[] playerInWorldLoc = playerInWorldLocn;
+ GameMode[] playerInWorldGM = playerInWorldGMn;
+ public void run() {
+ Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), "mv load " + world);
+ boolean loaded = false;
+ while (!loaded) {
+ loaded = Boolean.valueOf(Bukkit.getServer().getWorlds().contains(Bukkit.getWorld(world)));
+ if (loaded) {
+ playerInWorldLocn = this.playerInWorldLoc;
+ playerInWorldn = this.playerInWorld;
+ playerInWorldGMn = this.playerInWorldGM;
+ Bukkit.getScheduler().runTaskLater(PotionSG.getInst(), new Runnable() {
+ Player[] playerInWorld = playerInWorldn;
+ Location[] playerInWorldLoc = playerInWorldLocn;
+ public void run() {
+ for (int i = 0; i < this.playerInWorld.length; i++) if (this.playerInWorld[i] != null) Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), "mvtp " + this.playerInWorld[i].getName() + " e:" + this.playerInWorldLoc[i].getWorld().getName() + ":" + this.playerInWorldLoc[i].getX() + "," + this.playerInWorldLoc[i].getY() + "," + this.playerInWorldLoc[i].getZ());
+ }
+ }, 10L);
+ Bukkit.getScheduler().runTaskLater(PotionSG.getInst(), new Runnable() {
+ Player[] playerInWorld = playerInWorldn;
+ GameMode[] playerInWorldGM = playerInWorldGMn;
+ public void run() {
+ for (int i = 0; i < this.playerInWorld.length; i++) if (this.playerInWorld[i] != null) this.playerInWorld[i].setGameMode(this.playerInWorldGM[i]);
+ }
+ }, 20L);
+ }
+ }
+ }
+ });
+ if (success) C.c(Bukkit.getConsoleSender(), "&aSuccessfully " + (save ? "saved" : "rebuilded") + " the world '" + world + "'.");
+ else C.c(Bukkit.getConsoleSender(), "&cFailed to " + (save ? "save" : "rebuild") + " the world '" + world + "'.");
+ }
+ });
+ }
+
+}
diff --git a/src/main/java/me/weebo/menu/Button.java b/src/main/java/me/weebo/menu/Button.java
new file mode 100644
index 0000000..9fd32ba
--- /dev/null
+++ b/src/main/java/me/weebo/menu/Button.java
@@ -0,0 +1,67 @@
+package me.weebo.menu;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.bukkit.Material;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+import lombok.Getter;
+import lombok.Setter;
+
+public class Button {
+
+ @Getter
+ Button button;
+
+ @Getter @Setter
+ ItemStack item;
+
+ @Getter
+ String name;
+
+ @Getter
+ List lore;
+
+ @Getter @Setter
+ int slot;
+
+ @Getter @Setter
+ Page nextPage;
+
+ public Button(ItemStack item, String name, List lore, int slot, String command) {
+ this.item = item;
+ this.name = name;
+ this.lore = lore;
+ this.slot = slot;
+ this.button = this;
+ }
+
+ public Button() {
+ this.item = new ItemStack(Material.AIR);
+ this.name = "None";
+ this.lore = new ArrayList();
+ this.slot = 0;
+ this.button = this;
+ }
+
+ public void setName(String name) {
+ final ItemMeta meta = item.getItemMeta();
+ meta.setDisplayName(name);
+ item.setItemMeta(meta);
+ }
+
+ public void setLore(List lore) {
+ final ItemMeta meta = item.getItemMeta();
+ meta.setLore(lore);
+ item.setItemMeta(meta);
+ }
+
+ public void addLore(String lore) {
+ final ItemMeta meta = item.getItemMeta();
+ this.lore.add(lore);
+ meta.setLore(this.lore);
+ item.setItemMeta(meta);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/me/weebo/menu/Menu.java b/src/main/java/me/weebo/menu/Menu.java
new file mode 100644
index 0000000..ef36368
--- /dev/null
+++ b/src/main/java/me/weebo/menu/Menu.java
@@ -0,0 +1,37 @@
+package me.weebo.menu;
+
+import me.weebo.PotionSG;
+import org.bukkit.entity.Player;
+
+import lombok.Getter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Menu {
+
+ @Getter
+ Menu menu;
+
+ @Getter
+ List pages;
+
+ public Menu() {
+ this.pages = new ArrayList();
+ this.menu = this;
+ }
+
+ public Page getPage(int page) {
+ return pages.get(page);
+ }
+
+ public void addPage(Page page) {
+ this.pages.add(page);
+ }
+
+ public void show(Player player) {
+ this.pages.get(0).build(player);
+ PotionSG.getInstance().getPlayerMenu().put(player.getUniqueId(), this.pages.get(0));
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/me/weebo/menu/MenuListener.java b/src/main/java/me/weebo/menu/MenuListener.java
new file mode 100644
index 0000000..58c21d4
--- /dev/null
+++ b/src/main/java/me/weebo/menu/MenuListener.java
@@ -0,0 +1,56 @@
+package me.weebo.menu;
+
+import me.weebo.PotionSG;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.event.inventory.InventoryCloseEvent;
+
+public class MenuListener implements Listener {
+
+ @EventHandler
+ public void onInventoryClick(InventoryClickEvent event) {
+ if(event.getWhoClicked() instanceof Player) {
+ final Player player = (Player) event.getWhoClicked();
+ final Page page = PotionSG.getInstance().getPlayerMenu().get(player.getUniqueId());
+ if(page == null) {
+ return;
+ }
+ event.setCancelled(true);
+ if(page.isGoToNextPageOnEveryClick()) {
+ player.closeInventory();
+ page.getNextPage().build(player);
+ return;
+ }
+
+ final int slot = event.getRawSlot();
+ final Button button = page.getButton(slot);
+ if(button != null && button.getNextPage() != null) {
+ player.closeInventory();
+ button.getNextPage().build(player);
+ return;
+ }
+
+ if(page.getNextPageButton() != null && page.getNextPageButton().equals(button)) {
+ player.closeInventory();
+ page.getNextPage().build(player);
+ return;
+ }
+
+ if(page.getPreviousPageButton() != null && page.getPreviousPageButton().equals(button)) {
+ player.closeInventory();
+ page.getPreviousPage().build(player);
+ return;
+ }
+ }
+ }
+
+ @EventHandler
+ public void InventoryClose(InventoryCloseEvent event) {
+ if(event.getPlayer() instanceof Player) {
+ PotionSG.getInstance().getPlayerMenu().remove(event.getPlayer().getUniqueId());
+ }
+ }
+
+}
diff --git a/src/main/java/me/weebo/menu/Page.java b/src/main/java/me/weebo/menu/Page.java
new file mode 100644
index 0000000..8a7a0a3
--- /dev/null
+++ b/src/main/java/me/weebo/menu/Page.java
@@ -0,0 +1,90 @@
+package me.weebo.menu;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import me.weebo.PotionSG;
+import org.bukkit.Bukkit;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+
+import lombok.Getter;
+import lombok.Setter;
+
+public class Page {
+
+ @Getter
+ Menu menu;
+
+ @Getter @Setter
+ String title;
+
+ @Getter
+ int rows;
+
+ @Getter
+ List