diff --git a/.gitignore b/.gitignore
index eda2b5917a..9251ca7e61 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,42 +1,47 @@
-.DS_Store
-/BuildAll/nbproject/private/
-/EssentialsProtect/nbproject/private/
-/EssentialsChat/nbproject/private/
-/EssentialsGroupBridge/nbproject/private/
-/EssentialsGeoIP/nbproject/private/
-/EssentialsSpawn/nbproject/private/
-/EssentialsXMPP/nbproject/private/
-/EssentialsGroupManager/nbproject/private/
-/BuildAll/build/
-/EssentialsGroupBridge/dist/
-/EssentialsGroupBridge/build/
-/EssentialsGeoIP/dist/
-/EssentialsGeoIP/build/
-/EssentialsGroupManager/build/
-/EssentialsGroupManager/dist/
-/BuildAll/dist/
-/EssentialsChat/build/
-/EssentialsChat/dist/
-/EssentialsSpawn/build/
-/EssentialsSpawn/dist/
-/EssentialsXMPP/dist/
-/EssentialsXMPP/build/
-/EssentialsProtect/dist/
-/EssentialsProtect/build/
-/EssentialsPermissionsCommands/nbproject/private/
-/EssentialsPermissionsCommands/build/
-/EssentialsPermissionsCommands/dist/
-/Essentials/nbproject/private/
-/Essentials/dist/
-/Essentials/build/
-/YamlAnnotations/
-/EssentialsUpdate/nbproject/private/
-/EssentialsRelease/
-/EssentialsUpdate/dist/
-/EssentialsUpdate/build/
-/WebPush/apikey.php
-/WebPush/nbproject/private
-/.idea
+.DS_Store
+/BuildAll/nbproject/private/
+/EssentialsProtect/nbproject/private/
+/EssentialsChat/nbproject/private/
+/EssentialsGroupBridge/nbproject/private/
+/EssentialsGeoIP/nbproject/private/
+/EssentialsSpawn/nbproject/private/
+/EssentialsXMPP/nbproject/private/
+/EssentialsGroupManager/nbproject/private/
+/BuildAll/build/
+/EssentialsGroupBridge/dist/
+/EssentialsGroupBridge/build/
+/EssentialsGeoIP/dist/
+/EssentialsGeoIP/build/
+/EssentialsGroupManager/build/
+/EssentialsGroupManager/dist/
+/BuildAll/dist/
+/EssentialsChat/build/
+/EssentialsChat/dist/
+/EssentialsSpawn/build/
+/EssentialsSpawn/dist/
+/EssentialsXMPP/dist/
+/EssentialsXMPP/build/
+/EssentialsProtect/dist/
+/EssentialsProtect/build/
+/EssentialsPermissionsCommands/nbproject/private/
+/EssentialsPermissionsCommands/build/
+/EssentialsPermissionsCommands/dist/
+/Essentials/nbproject/private/
+/Essentials/dist/
+/Essentials/build/
+/YamlAnnotations/
+/EssentialsUpdate/nbproject/private/
+/EssentialsRelease/
+/EssentialsUpdate/dist/
+/EssentialsUpdate/build/
+/WebPush/apikey.php
+/WebPush/nbproject/private
+/.idea
*.iml
/EssentialsGroupManager/bin
-/EssentialsGroupManager/.externalToolBuilders
\ No newline at end of file
+/EssentialsGroupManager/.externalToolBuilders
+/EssentialsAntiBuild/nbproject/private/
+/EssentialsAntiBuild/dist/
+/EssentialsAntiBuild/build/
+/jars
+/out
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000000..b68a6c4952
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,17 @@
+language: java
+jdk:
+ - oraclejdk7
+ - openjdk7
+ - openjdk6
+script: ant collect
+notifications:
+ irc:
+ channels:
+ - "irc.esper.net#lain"
+ on_success: change
+ on_failure: always
+ email:
+ recipients:
+ - "khobbits@ess3.net"
+ on_success: change
+ on_failure: always
\ No newline at end of file
diff --git a/BuildAll/nbproject/build-impl.xml b/BuildAll/nbproject/build-impl.xml
index 1f8bcbaaea..3c7d317da7 100644
--- a/BuildAll/nbproject/build-impl.xml
+++ b/BuildAll/nbproject/build-impl.xml
@@ -12,9 +12,9 @@ is divided into following sections:
- execution
- debugging
- javadoc
- - junit compilation
- - junit execution
- - junit debugging
+ - test compilation
+ - test execution
+ - test debugging
- applet
- cleanup
@@ -181,6 +181,7 @@ is divided into following sections:
+
@@ -225,6 +226,27 @@ is divided into following sections:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -357,11 +379,52 @@ is divided into following sections:
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -370,32 +433,270 @@ is divided into following sections:
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No tests executed.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
@@ -427,10 +728,13 @@ is divided into following sections:
-
+
Must set JVM to use for profiling in profiler.info.jvm
Must set profiler agent JVM arguments in profiler.info.jvmargs.agent
+
@@ -488,6 +792,7 @@ is divided into following sections:
+
@@ -504,6 +809,7 @@ is divided into following sections:
+
@@ -511,6 +817,7 @@ is divided into following sections:
+
@@ -537,6 +844,9 @@ is divided into following sections:
+
+
+
@@ -582,7 +892,7 @@ is divided into following sections:
-
+
-
+
+
+ This target only works when run from inside the NetBeans IDE.
@@ -862,8 +1176,9 @@ is divided into following sections:
-
+
Must select one file in the IDE or set profile.class
+ This target only works when run from inside the NetBeans IDE.
@@ -871,12 +1186,8 @@ is divided into following sections:
-
-
+
+ This target only works when run from inside the NetBeans IDE.
@@ -888,12 +1199,8 @@ is divided into following sections:
-
-
+
+ This target only works when run from inside the NetBeans IDE.
@@ -915,6 +1222,42 @@ is divided into following sections:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select one file in the IDE or set run.class
+
+
+
+
+
+ Must select some files in the IDE or set test.includes
+
+
+
+
+ Must select one file in the IDE or set run.class
+
+
+
+
+ Must select one file in the IDE or set applet.url
+
+
+
@@ -1001,14 +1344,14 @@ is divided into following sections:
-
+
Some tests failed; see details above.
@@ -1021,39 +1364,40 @@ is divided into following sections:
Must select some files in the IDE or set test.includes
-
+
Some tests failed; see details above.
+
+ Must select some files in the IDE or set test.class
+ Must select some method in the IDE or set test.method
+
+
+
+ Some tests failed; see details above.
+
+
-
+
Must select one file in the IDE or set test.class
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Must select one file in the IDE or set test.class
+ Must select some method in the IDE or set test.method
+
+
@@ -1128,15 +1472,15 @@ is divided into following sections:
-
-
+
+
-
-
+
+
@@ -1174,9 +1518,12 @@ is divided into following sections:
-
-
-
+
+
+
+
+
+
diff --git a/BuildAll/nbproject/genfiles.properties b/BuildAll/nbproject/genfiles.properties
index 8068c7fc04..b95cd73c29 100644
--- a/BuildAll/nbproject/genfiles.properties
+++ b/BuildAll/nbproject/genfiles.properties
@@ -1,8 +1,8 @@
-build.xml.data.CRC32=51b33957
+build.xml.data.CRC32=cab45985
build.xml.script.CRC32=7a797370
-build.xml.stylesheet.CRC32=28e38971@1.44.1.45
+build.xml.stylesheet.CRC32=28e38971@1.50.3.46
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
-nbproject/build-impl.xml.data.CRC32=51b33957
-nbproject/build-impl.xml.script.CRC32=c5170bed
-nbproject/build-impl.xml.stylesheet.CRC32=fcddb364@1.50.1.46
+nbproject/build-impl.xml.data.CRC32=b4df970c
+nbproject/build-impl.xml.script.CRC32=8905537e
+nbproject/build-impl.xml.stylesheet.CRC32=6ddba6b6@1.53.1.46
diff --git a/BuildAll/nbproject/project.properties b/BuildAll/nbproject/project.properties
index 246ea1240f..a18e718e52 100644
--- a/BuildAll/nbproject/project.properties
+++ b/BuildAll/nbproject/project.properties
@@ -66,10 +66,10 @@ jar.compress=true
javac.classpath=\
${reference.Essentials.jar}:\
${reference.EssentialsChat.jar}:\
+ ${reference.EssentialsAntiBuild.jar}:\
${reference.EssentialsProtect.jar}:\
${reference.EssentialsSpawn.jar}:\
${reference.EssentialsGeoIP.jar}:\
- ${reference.EssentialsGroupBridge.jar}:\
${reference.EssentialsXMPP.jar}:\
${reference.EssentialsGroupManager.jar}
# Space-separated list of extra javac options
@@ -101,16 +101,16 @@ platform.active=default_platform
project.Essentials=../Essentials
project.EssentialsChat=../EssentialsChat
project.EssentialsGeoIP=../EssentialsGeoIP
-project.EssentialsGroupBridge=../EssentialsGroupBridge
project.EssentialsGroupManager=../EssentialsGroupManager
+project.EssentialsAntiBuild=../EssentialsAntiBuild
project.EssentialsProtect=../EssentialsProtect
project.EssentialsSpawn=../EssentialsSpawn
project.EssentialsXMPP=../EssentialsXMPP
reference.Essentials.jar=${project.Essentials}/dist/Essentials.jar
reference.EssentialsChat.jar=${project.EssentialsChat}/dist/EssentialsChat.jar
reference.EssentialsGeoIP.jar=${project.EssentialsGeoIP}/dist/EssentialsGeoIP.jar
-reference.EssentialsGroupBridge.jar=${project.EssentialsGroupBridge}/dist/EssentialsGroupBridge.jar
reference.EssentialsGroupManager.jar=${project.EssentialsGroupManager}/dist/EssentialsGroupManager.jar
+reference.EssentialsAntiBuild.jar=${project.EssentialsAntiBuild}/dist/EssentialsAntiBuild.jar
reference.EssentialsProtect.jar=${project.EssentialsProtect}/dist/EssentialsProtect.jar
reference.EssentialsSpawn.jar=${project.EssentialsSpawn}/dist/EssentialsSpawn.jar
reference.EssentialsXMPP.jar=${project.EssentialsXMPP}/dist/EssentialsXMPP.jar
diff --git a/BuildAll/nbproject/project.xml b/BuildAll/nbproject/project.xml
index 420233ac92..a7afa7da68 100644
--- a/BuildAll/nbproject/project.xml
+++ b/BuildAll/nbproject/project.xml
@@ -40,7 +40,7 @@
jar
- EssentialsGroupBridge
+ EssentialsGroupManager
jar
jar
@@ -48,7 +48,7 @@
jar
- EssentialsGroupManager
+ EssentialsAntiBuild
jar
jar
diff --git a/Essentials/nbproject/build-impl.xml b/Essentials/nbproject/build-impl.xml
index f79ca7e26d..7a011527b1 100644
--- a/Essentials/nbproject/build-impl.xml
+++ b/Essentials/nbproject/build-impl.xml
@@ -12,9 +12,9 @@ is divided into following sections:
- execution
- debugging
- javadoc
- - junit compilation
- - junit execution
- - junit debugging
+ - test compilation
+ - test execution
+ - test debugging
- applet
- cleanup
@@ -181,6 +181,7 @@ is divided into following sections:
+
@@ -225,6 +226,27 @@ is divided into following sections:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -357,11 +379,57 @@ is divided into following sections:
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -369,33 +437,277 @@ is divided into following sections:
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No tests executed.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
@@ -427,10 +739,13 @@ is divided into following sections:
-
+
Must set JVM to use for profiling in profiler.info.jvm
Must set profiler agent JVM arguments in profiler.info.jvmargs.agent
+
@@ -488,6 +803,7 @@ is divided into following sections:
+
@@ -504,6 +820,7 @@ is divided into following sections:
+
@@ -511,6 +828,7 @@ is divided into following sections:
+
@@ -537,6 +855,9 @@ is divided into following sections:
+
+
+
@@ -582,7 +903,7 @@ is divided into following sections:
-
+
-
+
+
+ This target only works when run from inside the NetBeans IDE.
@@ -813,8 +1138,9 @@ is divided into following sections:
-
+
Must select one file in the IDE or set profile.class
+ This target only works when run from inside the NetBeans IDE.
@@ -822,12 +1148,8 @@ is divided into following sections:
-
-
+
+ This target only works when run from inside the NetBeans IDE.
@@ -839,12 +1161,8 @@ is divided into following sections:
-
-
+
+ This target only works when run from inside the NetBeans IDE.
@@ -866,6 +1184,42 @@ is divided into following sections:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select one file in the IDE or set run.class
+
+
+
+
+
+ Must select some files in the IDE or set test.includes
+
+
+
+
+ Must select one file in the IDE or set run.class
+
+
+
+
+ Must select one file in the IDE or set applet.url
+
+
+
@@ -952,14 +1306,14 @@ is divided into following sections:
-
+
Some tests failed; see details above.
@@ -972,39 +1326,40 @@ is divided into following sections:
Must select some files in the IDE or set test.includes
-
+
Some tests failed; see details above.
+
+ Must select some files in the IDE or set test.class
+ Must select some method in the IDE or set test.method
+
+
+
+ Some tests failed; see details above.
+
+
-
+
Must select one file in the IDE or set test.class
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Must select one file in the IDE or set test.class
+ Must select some method in the IDE or set test.method
+
+
@@ -1076,9 +1431,12 @@ is divided into following sections:
-
-
-
+
+
+
+
+
+
diff --git a/Essentials/nbproject/genfiles.properties b/Essentials/nbproject/genfiles.properties
index 8d631fddf4..8b1c292649 100644
--- a/Essentials/nbproject/genfiles.properties
+++ b/Essentials/nbproject/genfiles.properties
@@ -4,8 +4,8 @@ build.xml.stylesheet.CRC32=28e38971@1.38.2.45
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
nbproject/build-impl.xml.data.CRC32=a830bc14
-nbproject/build-impl.xml.script.CRC32=a9f8842a
-nbproject/build-impl.xml.stylesheet.CRC32=fcddb364@1.50.1.46
+nbproject/build-impl.xml.script.CRC32=21ffdddf
+nbproject/build-impl.xml.stylesheet.CRC32=c6d2a60f@1.56.1.46
nbproject/profiler-build-impl.xml.data.CRC32=ab78ce15
nbproject/profiler-build-impl.xml.script.CRC32=abda56ed
nbproject/profiler-build-impl.xml.stylesheet.CRC32=f10cf54c@1.11.1
diff --git a/Essentials/nbproject/project.properties b/Essentials/nbproject/project.properties
index 7a5ffe7bbb..f749b85535 100644
--- a/Essentials/nbproject/project.properties
+++ b/Essentials/nbproject/project.properties
@@ -1,5 +1,5 @@
annotation.processing.enabled=true
-annotation.processing.enabled.in.editor=false
+annotation.processing.enabled.in.editor=true
annotation.processing.processors.list=lombok.core.AnnotationProcessor
annotation.processing.run.all.processors=false
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
@@ -68,7 +68,6 @@ file.reference.BOSEconomy7.jar=../lib/BOSEconomy7.jar
file.reference.bPermissions.jar=../lib/bPermissions.jar
file.reference.bpermissions2.jar=../lib/bpermissions2.jar
file.reference.bukkit.jar=../lib/bukkit.jar
-file.reference.craftbukkit.jar=../lib/craftbukkit.jar
file.reference.iCo4.jar=../lib/iCo4.jar
file.reference.iCo5.jar=../lib/iCo5.jar
file.reference.iCo6.jar=../lib/iCo6.jar
@@ -79,6 +78,7 @@ file.reference.PermissionsBukkit-1.2.jar=../lib/PermissionsBukkit-1.2.jar
file.reference.PermissionsEx.jar=../lib/PermissionsEx.jar
file.reference.Privileges.jar=..\\lib\\Privileges.jar
file.reference.Vault.jar=../lib/Vault.jar
+file.reference.SimplyPerms.jar=../lib/SimplyPerms.jar
includes=**
jar.archive.disabled=${jnlp.enabled}
jar.compress=true
@@ -96,12 +96,12 @@ javac.classpath=\
${file.reference.lombok.jar}:\
${reference.EssentialsGroupManager.jar}:\
${file.reference.bukkit.jar}:\
- ${file.reference.craftbukkit.jar}:\
${file.reference.Vault.jar}:\
${file.reference.Privileges.jar}:\
- ${file.reference.bpermissions2.jar}
+ ${file.reference.bpermissions2.jar}:\
+ ${file.reference.SimplyPerms.jar}
# Space-separated list of extra javac options
-javac.compilerargs=
+javac.compilerargs=-Xlint:unchecked
javac.deprecation=false
javac.processorpath=\
${javac.classpath}
diff --git a/Essentials/src/book.txt b/Essentials/src/book.txt
new file mode 100644
index 0000000000..164910fb7e
--- /dev/null
+++ b/Essentials/src/book.txt
@@ -0,0 +1,18 @@
+This is the book file.
+
+This file format works similar to the info.txt, motd.txt and rules.txt
+
+Place content in here that you would like to be used by books ingame.
+
+You can use this content by using the book: meta option in kits or item spawning.
+
+#Colors
+Minecraft colors:
+&0 &&0 &1 &&1 &2 &&2 &3 &&3
+&4 &&4 &5 &&5 &6 &&6 &7 &&7
+&8 &&8 &9 &&9 &a &&a &b &&b
+&c &&c &d &&d &e &&e &f &&f
+&0
+&&k &kMagic&r &&l &lBold
+&&m &mStrike&r &&n &nUline
+&&o &oItalic&r &&r &rReset
\ No newline at end of file
diff --git a/Essentials/src/com/earth2me/essentials/AlternativeCommandsHandler.java b/Essentials/src/com/earth2me/essentials/AlternativeCommandsHandler.java
index e75644ad53..e9cb6fe193 100644
--- a/Essentials/src/com/earth2me/essentials/AlternativeCommandsHandler.java
+++ b/Essentials/src/com/earth2me/essentials/AlternativeCommandsHandler.java
@@ -121,13 +121,14 @@ public PluginCommand getAlternative(final String label)
return commands.get(0);
}
- public void executed(final String label, final String otherLabel)
+ public void executed(final String label, final PluginCommand pc)
{
+ final String altString = pc.getPlugin().getName() + ":" + pc.getLabel();
if (ess.getSettings().isDebug())
{
- LOGGER.log(Level.INFO, "Essentials: Alternative command " + label + " found, using " + otherLabel);
+ LOGGER.log(Level.INFO, "Essentials: Alternative command " + label + " found, using " + altString);
}
- disabledList.put(label, otherLabel);
+ disabledList.put(label, altString);
}
public Map disabledCommands()
diff --git a/Essentials/src/com/earth2me/essentials/Backup.java b/Essentials/src/com/earth2me/essentials/Backup.java
index baa90e561e..3b7d9297c1 100644
--- a/Essentials/src/com/earth2me/essentials/Backup.java
+++ b/Essentials/src/com/earth2me/essentials/Backup.java
@@ -25,16 +25,33 @@ public Backup(final IEssentials ess)
server = ess.getServer();
if (server.getOnlinePlayers().length > 0)
{
- startTask();
+ ess.runTaskAsynchronously(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ startTask();
+ }
+ });
}
}
- void onPlayerJoin()
+ public void onPlayerJoin()
{
startTask();
}
- private void startTask()
+ public synchronized void stopTask()
+ {
+ running = false;
+ if (taskId != -1)
+ {
+ server.getScheduler().cancelTask(taskId);
+ }
+ taskId = -1;
+ }
+
+ private synchronized void startTask()
{
if (!running)
{
@@ -61,7 +78,8 @@ public void run()
{
return;
}
- if ("save-all".equalsIgnoreCase(command)) {
+ if ("save-all".equalsIgnoreCase(command))
+ {
final CommandSender cs = server.getConsoleSender();
server.dispatchCommand(cs, "save-all");
active = false;
@@ -72,7 +90,7 @@ public void run()
server.dispatchCommand(cs, "save-all");
server.dispatchCommand(cs, "save-off");
- ess.scheduleAsyncDelayedTask(
+ ess.runTaskAsynchronously(
new Runnable()
{
@Override
@@ -123,11 +141,7 @@ public void run()
server.dispatchCommand(cs, "save-on");
if (server.getOnlinePlayers().length == 0)
{
- running = false;
- if (taskId != -1)
- {
- server.getScheduler().cancelTask(taskId);
- }
+ stopTask();
}
active = false;
LOGGER.log(Level.INFO, _("backupFinished"));
diff --git a/Essentials/src/com/earth2me/essentials/DescParseTickFormat.java b/Essentials/src/com/earth2me/essentials/DescParseTickFormat.java
index 9c40acacc7..91efe3c0ad 100644
--- a/Essentials/src/com/earth2me/essentials/DescParseTickFormat.java
+++ b/Essentials/src/com/earth2me/essentials/DescParseTickFormat.java
@@ -269,11 +269,11 @@ public static Date ticksToDate(long ticks)
// How many ingame days have passed since the server start?
final long days = ticks / ticksPerDay;
- ticks = ticks - days * ticksPerDay;
+ ticks -= days * ticksPerDay;
// How many hours on the last day?
final long hours = ticks / ticksPerHour;
- ticks = ticks - hours * ticksPerHour;
+ ticks -= hours * ticksPerHour;
// How many minutes on the last day?
final long minutes = (long)Math.floor(ticks / ticksPerMinute);
diff --git a/Essentials/src/com/earth2me/essentials/Enchantments.java b/Essentials/src/com/earth2me/essentials/Enchantments.java
index 060dfd2c1e..e30bff1c1f 100644
--- a/Essentials/src/com/earth2me/essentials/Enchantments.java
+++ b/Essentials/src/com/earth2me/essentials/Enchantments.java
@@ -5,112 +5,144 @@
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
-import java.util.regex.Pattern;
import org.bukkit.enchantments.Enchantment;
public class Enchantments
{
- private static final transient Pattern NUMPATTERN = Pattern.compile("\\d+");
private static final Map ENCHANTMENTS = new HashMap();
+ private static final Map ALIASENCHANTMENTS = new HashMap();
static
{
ENCHANTMENTS.put("alldamage", Enchantment.DAMAGE_ALL);
- ENCHANTMENTS.put("alldmg", Enchantment.DAMAGE_ALL);
+ ALIASENCHANTMENTS.put("alldmg", Enchantment.DAMAGE_ALL);
ENCHANTMENTS.put("sharpness", Enchantment.DAMAGE_ALL);
- ENCHANTMENTS.put("sharp", Enchantment.DAMAGE_ALL);
-
- ENCHANTMENTS.put("arthropodsdamage", Enchantment.DAMAGE_ARTHROPODS);
+ ALIASENCHANTMENTS.put("sharp", Enchantment.DAMAGE_ALL);
+ ALIASENCHANTMENTS.put("dal", Enchantment.DAMAGE_ALL);
+
ENCHANTMENTS.put("ardmg", Enchantment.DAMAGE_ARTHROPODS);
ENCHANTMENTS.put("baneofarthropods", Enchantment.DAMAGE_ARTHROPODS);
- ENCHANTMENTS.put("baneofarthropod", Enchantment.DAMAGE_ARTHROPODS);
- ENCHANTMENTS.put("arthropod", Enchantment.DAMAGE_ARTHROPODS);
+ ALIASENCHANTMENTS.put("baneofarthropod", Enchantment.DAMAGE_ARTHROPODS);
+ ALIASENCHANTMENTS.put("arthropod", Enchantment.DAMAGE_ARTHROPODS);
+ ALIASENCHANTMENTS.put("dar", Enchantment.DAMAGE_ARTHROPODS);
ENCHANTMENTS.put("undeaddamage", Enchantment.DAMAGE_UNDEAD);
ENCHANTMENTS.put("smite", Enchantment.DAMAGE_UNDEAD);
+ ALIASENCHANTMENTS.put("du", Enchantment.DAMAGE_UNDEAD);
ENCHANTMENTS.put("digspeed", Enchantment.DIG_SPEED);
ENCHANTMENTS.put("efficiency", Enchantment.DIG_SPEED);
- ENCHANTMENTS.put("minespeed", Enchantment.DIG_SPEED);
- ENCHANTMENTS.put("cutspeed", Enchantment.DIG_SPEED);
+ ALIASENCHANTMENTS.put("minespeed", Enchantment.DIG_SPEED);
+ ALIASENCHANTMENTS.put("cutspeed", Enchantment.DIG_SPEED);
+ ALIASENCHANTMENTS.put("ds", Enchantment.DIG_SPEED);
+ ALIASENCHANTMENTS.put("eff", Enchantment.DIG_SPEED);
ENCHANTMENTS.put("durability", Enchantment.DURABILITY);
- ENCHANTMENTS.put("dura", Enchantment.DURABILITY);
+ ALIASENCHANTMENTS.put("dura", Enchantment.DURABILITY);
ENCHANTMENTS.put("unbreaking", Enchantment.DURABILITY);
+ ALIASENCHANTMENTS.put("d", Enchantment.DURABILITY);
+
+ ENCHANTMENTS.put("thorns", Enchantment.THORNS);
+ ENCHANTMENTS.put("highcrit", Enchantment.THORNS);
+ ALIASENCHANTMENTS.put("thorn", Enchantment.THORNS);
+ ALIASENCHANTMENTS.put("highercrit", Enchantment.THORNS);
+ ALIASENCHANTMENTS.put("t", Enchantment.THORNS);
ENCHANTMENTS.put("fireaspect", Enchantment.FIRE_ASPECT);
ENCHANTMENTS.put("fire", Enchantment.FIRE_ASPECT);
- ENCHANTMENTS.put("meleefire", Enchantment.FIRE_ASPECT);
- ENCHANTMENTS.put("meleeflame", Enchantment.FIRE_ASPECT);
+ ALIASENCHANTMENTS.put("meleefire", Enchantment.FIRE_ASPECT);
+ ALIASENCHANTMENTS.put("meleeflame", Enchantment.FIRE_ASPECT);
+ ALIASENCHANTMENTS.put("fa", Enchantment.FIRE_ASPECT);
ENCHANTMENTS.put("knockback", Enchantment.KNOCKBACK);
+ ALIASENCHANTMENTS.put("kback", Enchantment.KNOCKBACK);
+ ALIASENCHANTMENTS.put("kb", Enchantment.KNOCKBACK);
+ ALIASENCHANTMENTS.put("k", Enchantment.KNOCKBACK);
- ENCHANTMENTS.put("blockslootbonus", Enchantment.LOOT_BONUS_BLOCKS);
+ ALIASENCHANTMENTS.put("blockslootbonus", Enchantment.LOOT_BONUS_BLOCKS);
ENCHANTMENTS.put("fortune", Enchantment.LOOT_BONUS_BLOCKS);
+ ALIASENCHANTMENTS.put("fort", Enchantment.LOOT_BONUS_BLOCKS);
+ ALIASENCHANTMENTS.put("lbb", Enchantment.LOOT_BONUS_BLOCKS);
- ENCHANTMENTS.put("mobslootbonus", Enchantment.LOOT_BONUS_MOBS);
+ ALIASENCHANTMENTS.put("mobslootbonus", Enchantment.LOOT_BONUS_MOBS);
ENCHANTMENTS.put("mobloot", Enchantment.LOOT_BONUS_MOBS);
ENCHANTMENTS.put("looting", Enchantment.LOOT_BONUS_MOBS);
+ ALIASENCHANTMENTS.put("lbm", Enchantment.LOOT_BONUS_MOBS);
- ENCHANTMENTS.put("oxygen", Enchantment.OXYGEN);
+ ALIASENCHANTMENTS.put("oxygen", Enchantment.OXYGEN);
ENCHANTMENTS.put("respiration", Enchantment.OXYGEN);
- ENCHANTMENTS.put("breathing", Enchantment.OXYGEN);
+ ALIASENCHANTMENTS.put("breathing", Enchantment.OXYGEN);
ENCHANTMENTS.put("breath", Enchantment.OXYGEN);
+ ALIASENCHANTMENTS.put("o", Enchantment.OXYGEN);
ENCHANTMENTS.put("protection", Enchantment.PROTECTION_ENVIRONMENTAL);
- ENCHANTMENTS.put("prot", Enchantment.PROTECTION_ENVIRONMENTAL);
+ ALIASENCHANTMENTS.put("prot", Enchantment.PROTECTION_ENVIRONMENTAL);
ENCHANTMENTS.put("protect", Enchantment.PROTECTION_ENVIRONMENTAL);
+ ALIASENCHANTMENTS.put("p", Enchantment.PROTECTION_ENVIRONMENTAL);
- ENCHANTMENTS.put("explosionsprotection", Enchantment.PROTECTION_EXPLOSIONS);
- ENCHANTMENTS.put("explosionprotection", Enchantment.PROTECTION_EXPLOSIONS);
- ENCHANTMENTS.put("expprot", Enchantment.PROTECTION_EXPLOSIONS);
- ENCHANTMENTS.put("blastprotection", Enchantment.PROTECTION_EXPLOSIONS);
+ ALIASENCHANTMENTS.put("explosionsprotection", Enchantment.PROTECTION_EXPLOSIONS);
+ ALIASENCHANTMENTS.put("explosionprotection", Enchantment.PROTECTION_EXPLOSIONS);
+ ALIASENCHANTMENTS.put("expprot", Enchantment.PROTECTION_EXPLOSIONS);
+ ALIASENCHANTMENTS.put("blastprotection", Enchantment.PROTECTION_EXPLOSIONS);
ENCHANTMENTS.put("blastprotect", Enchantment.PROTECTION_EXPLOSIONS);
+ ALIASENCHANTMENTS.put("pe", Enchantment.PROTECTION_EXPLOSIONS);
- ENCHANTMENTS.put("fallprotection", Enchantment.PROTECTION_FALL);
+ ALIASENCHANTMENTS.put("fallprotection", Enchantment.PROTECTION_FALL);
ENCHANTMENTS.put("fallprot", Enchantment.PROTECTION_FALL);
ENCHANTMENTS.put("featherfall", Enchantment.PROTECTION_FALL);
- ENCHANTMENTS.put("featherfalling", Enchantment.PROTECTION_FALL);
+ ALIASENCHANTMENTS.put("featherfalling", Enchantment.PROTECTION_FALL);
+ ALIASENCHANTMENTS.put("pfa", Enchantment.PROTECTION_FALL);
- ENCHANTMENTS.put("fireprotection", Enchantment.PROTECTION_FIRE);
- ENCHANTMENTS.put("flameprotection", Enchantment.PROTECTION_FIRE);
+ ALIASENCHANTMENTS.put("fireprotection", Enchantment.PROTECTION_FIRE);
+ ALIASENCHANTMENTS.put("flameprotection", Enchantment.PROTECTION_FIRE);
ENCHANTMENTS.put("fireprotect", Enchantment.PROTECTION_FIRE);
- ENCHANTMENTS.put("flameprotect", Enchantment.PROTECTION_FIRE);
+ ALIASENCHANTMENTS.put("flameprotect", Enchantment.PROTECTION_FIRE);
+ ENCHANTMENTS.put("fireprot", Enchantment.PROTECTION_FIRE);
+ ALIASENCHANTMENTS.put("flameprot", Enchantment.PROTECTION_FIRE);
+ ALIASENCHANTMENTS.put("pf", Enchantment.PROTECTION_FIRE);
ENCHANTMENTS.put("projectileprotection", Enchantment.PROTECTION_PROJECTILE);
ENCHANTMENTS.put("projprot", Enchantment.PROTECTION_PROJECTILE);
+ ALIASENCHANTMENTS.put("pp", Enchantment.PROTECTION_PROJECTILE);
ENCHANTMENTS.put("silktouch", Enchantment.SILK_TOUCH);
- ENCHANTMENTS.put("softtouch", Enchantment.SILK_TOUCH);
+ ALIASENCHANTMENTS.put("softtouch", Enchantment.SILK_TOUCH);
+ ALIASENCHANTMENTS.put("st", Enchantment.SILK_TOUCH);
ENCHANTMENTS.put("waterworker", Enchantment.WATER_WORKER);
ENCHANTMENTS.put("aquaaffinity", Enchantment.WATER_WORKER);
+ ALIASENCHANTMENTS.put("watermine", Enchantment.WATER_WORKER);
+ ALIASENCHANTMENTS.put("ww", Enchantment.WATER_WORKER);
- ENCHANTMENTS.put("firearrow", Enchantment.ARROW_FIRE);
+ ALIASENCHANTMENTS.put("firearrow", Enchantment.ARROW_FIRE);
ENCHANTMENTS.put("flame", Enchantment.ARROW_FIRE);
ENCHANTMENTS.put("flamearrow", Enchantment.ARROW_FIRE);
+ ALIASENCHANTMENTS.put("af", Enchantment.ARROW_FIRE);
ENCHANTMENTS.put("arrowdamage", Enchantment.ARROW_DAMAGE);
ENCHANTMENTS.put("power", Enchantment.ARROW_DAMAGE);
- ENCHANTMENTS.put("arrowpower", Enchantment.ARROW_DAMAGE);
+ ALIASENCHANTMENTS.put("arrowpower", Enchantment.ARROW_DAMAGE);
+ ALIASENCHANTMENTS.put("ad", Enchantment.ARROW_DAMAGE);
ENCHANTMENTS.put("arrowknockback", Enchantment.ARROW_KNOCKBACK);
- ENCHANTMENTS.put("arrowkb", Enchantment.ARROW_KNOCKBACK);
+ ALIASENCHANTMENTS.put("arrowkb", Enchantment.ARROW_KNOCKBACK);
ENCHANTMENTS.put("punch", Enchantment.ARROW_KNOCKBACK);
- ENCHANTMENTS.put("arrowpunch", Enchantment.ARROW_KNOCKBACK);
+ ALIASENCHANTMENTS.put("arrowpunch", Enchantment.ARROW_KNOCKBACK);
+ ALIASENCHANTMENTS.put("ak", Enchantment.ARROW_KNOCKBACK);
- ENCHANTMENTS.put("infinitearrows", Enchantment.ARROW_INFINITE);
+ ALIASENCHANTMENTS.put("infinitearrows", Enchantment.ARROW_INFINITE);
ENCHANTMENTS.put("infarrows", Enchantment.ARROW_INFINITE);
ENCHANTMENTS.put("infinity", Enchantment.ARROW_INFINITE);
- ENCHANTMENTS.put("infinite", Enchantment.ARROW_INFINITE);
- ENCHANTMENTS.put("unlimited", Enchantment.ARROW_INFINITE);
- ENCHANTMENTS.put("unlimitedarrows", Enchantment.ARROW_INFINITE);
+ ALIASENCHANTMENTS.put("infinite", Enchantment.ARROW_INFINITE);
+ ALIASENCHANTMENTS.put("unlimited", Enchantment.ARROW_INFINITE);
+ ALIASENCHANTMENTS.put("unlimitedarrows", Enchantment.ARROW_INFINITE);
+ ALIASENCHANTMENTS.put("ai", Enchantment.ARROW_INFINITE);
}
public static Enchantment getByName(String name) {
Enchantment enchantment;
- if (NUMPATTERN.matcher(name).matches()) {
+ if (Util.isInt(name)) {
enchantment = Enchantment.getById(Integer.parseInt(name));
} else {
enchantment = Enchantment.getByName(name.toUpperCase(Locale.ENGLISH));
@@ -119,6 +151,10 @@ public static Enchantment getByName(String name) {
{
enchantment = ENCHANTMENTS.get(name.toLowerCase(Locale.ENGLISH));
}
+ if (enchantment == null)
+ {
+ enchantment = ALIASENCHANTMENTS.get(name.toLowerCase(Locale.ENGLISH));
+ }
return enchantment;
}
diff --git a/Essentials/src/com/earth2me/essentials/Essentials.java b/Essentials/src/com/earth2me/essentials/Essentials.java
index 8790e70223..d9b1af096f 100644
--- a/Essentials/src/com/earth2me/essentials/Essentials.java
+++ b/Essentials/src/com/earth2me/essentials/Essentials.java
@@ -20,7 +20,6 @@
import static com.earth2me.essentials.I18n._;
import com.earth2me.essentials.api.Economy;
import com.earth2me.essentials.api.IJails;
-import com.earth2me.essentials.commands.EssentialsCommand;
import com.earth2me.essentials.commands.IEssentialsCommand;
import com.earth2me.essentials.commands.NoChargeException;
import com.earth2me.essentials.commands.NotEnoughArgumentsException;
@@ -36,7 +35,6 @@
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -49,9 +47,12 @@
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.PluginCommand;
+import org.bukkit.command.SimpleCommandMap;
+import org.bukkit.command.defaults.VanillaCommand;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
+import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.world.WorldLoadEvent;
@@ -62,12 +63,13 @@
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitScheduler;
+import org.bukkit.scheduler.BukkitTask;
import org.yaml.snakeyaml.error.YAMLException;
public class Essentials extends JavaPlugin implements IEssentials
{
- public static final int BUKKIT_VERSION = 2149;
+ public static final int BUKKIT_VERSION = 2754;
private static final Logger LOGGER = Logger.getLogger("Minecraft");
private transient ISettings settings;
private final transient TNTExplodeListener tntListener = new TNTExplodeListener(this);
@@ -86,6 +88,7 @@ public class Essentials extends JavaPlugin implements IEssentials
private transient Metrics metrics;
private transient EssentialsTimer timer;
private transient List vanishedPlayers = new ArrayList();
+ private transient SimpleCommandMap scm;
@Override
public ISettings getSettings()
@@ -124,6 +127,7 @@ public void onEnable()
i18n = new I18n(this);
i18n.onEnable();
execTimer.mark("I18n1");
+ scm = new SimpleCommandMap(this.getServer());
final PluginManager pm = getServer().getPluginManager();
for (Plugin plugin : pm.getPlugins())
{
@@ -178,6 +182,8 @@ public void onEnable()
itemDb = new ItemDb(this);
confList.add(itemDb);
execTimer.mark("Init(Worth/ItemDB)");
+ jails = new Jails(this);
+ confList.add(jails);
reload();
}
catch (YAMLException exception)
@@ -209,6 +215,40 @@ public void onPlayerJoin(final PlayerJoinEvent event)
backup = new Backup(this);
permissionsHandler = new PermissionsHandler(this, settings.useBukkitPermissions());
alternativeCommandsHandler = new AlternativeCommandsHandler(this);
+
+ timer = new EssentialsTimer(this);
+ scheduleSyncRepeatingTask(timer, 1000, 50);
+
+ Economy.setEss(this);
+ execTimer.mark("RegHandler");
+
+ final MetricsStarter metricsStarter = new MetricsStarter(this);
+ if (metricsStarter.getStart() != null && metricsStarter.getStart() == true)
+ {
+ runTaskLaterAsynchronously(metricsStarter, 1);
+ }
+ else if (metricsStarter.getStart() != null && metricsStarter.getStart() == false)
+ {
+ final MetricsListener metricsListener = new MetricsListener(this, metricsStarter);
+ pm.registerEvents(metricsListener, this);
+ }
+
+ final String timeroutput = execTimer.end();
+ if (getSettings().isDebug())
+ {
+ LOGGER.log(Level.INFO, "Essentials load " + timeroutput);
+ }
+ }
+
+ private void registerListeners(PluginManager pm)
+ {
+ HandlerList.unregisterAll(this);
+
+ if (getSettings().isDebug())
+ {
+ LOGGER.log(Level.INFO, "Registering Listeners");
+ }
+
final EssentialsPluginListener serverListener = new EssentialsPluginListener(this);
pm.registerEvents(serverListener, this);
confList.add(serverListener);
@@ -234,34 +274,9 @@ public void onPlayerJoin(final PlayerJoinEvent event)
final EssentialsWorldListener worldListener = new EssentialsWorldListener(this);
pm.registerEvents(worldListener, this);
- //TODO: Check if this should be here, and not above before reload()
- jails = new Jails(this);
- confList.add(jails);
-
pm.registerEvents(tntListener, this);
- timer = new EssentialsTimer(this);
- getScheduler().scheduleSyncRepeatingTask(this, timer, 100, 100);
-
- Economy.setEss(this);
- execTimer.mark("RegListeners");
-
- final MetricsStarter metricsStarter = new MetricsStarter(this);
- if (metricsStarter.getStart() != null && metricsStarter.getStart() == true)
- {
- getScheduler().scheduleAsyncDelayedTask(this, metricsStarter, 1);
- }
- else if (metricsStarter.getStart() != null && metricsStarter.getStart() == false)
- {
- final MetricsListener metricsListener = new MetricsListener(this, metricsStarter);
- pm.registerEvents(metricsListener, this);
- }
-
- final String timeroutput = execTimer.end();
- if (getSettings().isDebug())
- {
- LOGGER.log(Level.INFO, "Essentials load " + timeroutput);
- }
+ jails.resetListener();
}
@Override
@@ -276,7 +291,9 @@ public void onDisable()
p.sendMessage(_("unvanishedReload"));
}
}
+ cleanupOpenInventories();
i18n.onDisable();
+ backup.stopTask();
Economy.setEss(null);
Trade.closeLog();
}
@@ -293,6 +310,9 @@ public void reload()
}
i18n.updateLocale(settings.getLocale());
+
+ final PluginManager pm = getServer().getPluginManager();
+ registerListeners(pm);
}
@Override
@@ -310,7 +330,7 @@ public boolean onCommandEssentials(final CommandSender sender, final Command com
final PluginCommand pc = alternativeCommandsHandler.getAlternative(commandLabel);
if (pc != null)
{
- alternativeCommandsHandler.executed(commandLabel, pc.getLabel());
+ alternativeCommandsHandler.executed(commandLabel, pc);
try
{
return pc.execute(sender, commandLabel, args);
@@ -330,11 +350,10 @@ public boolean onCommandEssentials(final CommandSender sender, final Command com
if (sender instanceof Player)
{
user = getUser(sender);
- LOGGER.log(Level.INFO, String.format("[PLAYER_COMMAND] %s: /%s %s ", ((Player)sender).getName(), commandLabel, EssentialsCommand.getFinalArg(args, 0)));
}
// New mail notification
- if (user != null && !getSettings().isCommandDisabled("mail") && !commandLabel.equals("mail") && user.isAuthorized("essentials.mail"))
+ if (user != null && !getSettings().isCommandDisabled("mail") && !command.getName().equals("mail") && user.isAuthorized("essentials.mail"))
{
final List mail = user.getMails();
if (mail != null && !mail.isEmpty())
@@ -343,9 +362,26 @@ public boolean onCommandEssentials(final CommandSender sender, final Command com
}
}
+ //Print version even if admin command is not available
+ if (commandLabel.equalsIgnoreCase("essversion"))
+ {
+ sender.sendMessage("This server is running Essentials " + getDescription().getVersion());
+ return true;
+ }
+
// Check for disabled commands
if (getSettings().isCommandDisabled(commandLabel))
{
+ if (scm != null)
+ {
+ for (VanillaCommand cmd : scm.getFallbackCommands())
+ {
+ if (cmd.matches(commandLabel))
+ {
+ cmd.execute(sender, commandLabel, args);
+ }
+ }
+ }
return true;
}
@@ -371,6 +407,19 @@ public boolean onCommandEssentials(final CommandSender sender, final Command com
return true;
}
+ if (user != null && user.isJailed() && !user.isAuthorized(cmd, "essentials.jail.allow."))
+ {
+ if (user.getJailTimeout() > 0)
+ {
+ user.sendMessage(_("playerJailedFor", user.getName(), Util.formatDateDiff(user.getJailTimeout())));
+ }
+ else
+ {
+ user.sendMessage(_("jailMessage"));
+ }
+ return true;
+ }
+
// Run the command
try
{
@@ -411,6 +460,26 @@ public boolean onCommandEssentials(final CommandSender sender, final Command com
}
}
+ public void cleanupOpenInventories()
+ {
+ for (Player player : getServer().getOnlinePlayers())
+ {
+ User user = getUser(player);
+ if (user.isRecipeSee())
+ {
+ user.getPlayer().getOpenInventory().getTopInventory().clear();
+ user.getPlayer().getOpenInventory().close();
+ user.setRecipeSee(false);
+ }
+ if (user.isInvSee() || user.isEnderSee())
+ {
+ user.getPlayer().getOpenInventory().close();
+ user.setInvSee(false);
+ user.setEnderSee(false);
+ }
+ }
+ }
+
@Override
public void showError(final CommandSender sender, final Throwable exception, final String commandLabel)
{
@@ -470,16 +539,22 @@ public User getUser(final Object base)
}
if (base instanceof String)
{
- final User user = userMap.getUser((String)base);
- if (user != null && user.getBase() instanceof OfflinePlayer)
- {
- ((OfflinePlayer)user.getBase()).setName((String)base);
- }
- return user;
+ return getOfflineUser((String)base);
}
return null;
}
+ @Override
+ public User getOfflineUser(final String name)
+ {
+ final User user = userMap.getUser(name);
+ if (user != null && user.getBase() instanceof OfflinePlayer)
+ {
+ ((OfflinePlayer)user.getBase()).setName(name);
+ }
+ return user;
+ }
+
private User getUser(final T base)
{
if (base == null)
@@ -491,6 +566,13 @@ private User getUser(final T base)
{
return (User)base;
}
+
+ if (userMap == null)
+ {
+ LOGGER.log(Level.WARNING, "Essentials userMap not initialized");
+ return null;
+ }
+
User user = userMap.getUser(base.getName());
if (user == null)
@@ -504,17 +586,6 @@ private User getUser(final T base)
return user;
}
- @Override
- public User getOfflineUser(final String name)
- {
- final User user = userMap.getUser(name);
- if (user != null && user.getBase() instanceof OfflinePlayer)
- {
- ((OfflinePlayer)user.getBase()).setName(name);
- }
- return user;
- }
-
@Override
public World getWorld(final String name)
{
@@ -567,9 +638,15 @@ public int broadcastMessage(final IUser sender, final String message)
}
@Override
- public int scheduleAsyncDelayedTask(final Runnable run)
+ public BukkitTask runTaskAsynchronously(final Runnable run)
+ {
+ return this.getScheduler().runTaskAsynchronously(this, run);
+ }
+
+ @Override
+ public BukkitTask runTaskLaterAsynchronously(final Runnable run, final long delay)
{
- return this.getScheduler().scheduleAsyncDelayedTask(this, run);
+ return this.getScheduler().runTaskLaterAsynchronously(this, run, delay);
}
@Override
@@ -638,6 +715,7 @@ public List getVanishedPlayers()
return vanishedPlayers;
}
+
private static class EssentialsWorldListener implements Listener, Runnable
{
private transient final IEssentials ess;
diff --git a/Essentials/src/com/earth2me/essentials/EssentialsBlockListener.java b/Essentials/src/com/earth2me/essentials/EssentialsBlockListener.java
index 0c6bec0fee..c5c35d9018 100644
--- a/Essentials/src/com/earth2me/essentials/EssentialsBlockListener.java
+++ b/Essentials/src/com/earth2me/essentials/EssentialsBlockListener.java
@@ -28,8 +28,7 @@ public void onBlockPlace(final BlockPlaceEvent event)
return;
}
final User user = ess.getUser(event.getPlayer());
- final boolean unlimitedForUser = user.hasUnlimited(is);
- if (unlimitedForUser && user.getGameMode() == GameMode.SURVIVAL)
+ if (user.hasUnlimited(is) && user.getGameMode() == GameMode.SURVIVAL)
{
ess.scheduleSyncDelayedTask(
new Runnable()
diff --git a/Essentials/src/com/earth2me/essentials/EssentialsConf.java b/Essentials/src/com/earth2me/essentials/EssentialsConf.java
index b2cb1fd125..26f9d1c9da 100644
--- a/Essentials/src/com/earth2me/essentials/EssentialsConf.java
+++ b/Essentials/src/com/earth2me/essentials/EssentialsConf.java
@@ -5,43 +5,51 @@
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
-import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CoderResult;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
+import java.util.*;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;
-import org.bukkit.Location;
-import org.bukkit.Material;
-import org.bukkit.Server;
-import org.bukkit.World;
+import org.bukkit.*;
+import org.bukkit.OfflinePlayer;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack;
+import org.bukkit.util.Vector;
public class EssentialsConf extends YamlConfiguration
{
private static final Logger LOGGER = Logger.getLogger("Minecraft");
- private transient File configFile;
- private transient String templateName = null;
- private transient Class> resourceClass = EssentialsConf.class;
+ private final File configFile;
+ private String templateName = null;
+ private Class> resourceClass = EssentialsConf.class;
private static final Charset UTF8 = Charset.forName("UTF-8");
+ private static final ExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadExecutor();
+ private final AtomicInteger pendingDiskWrites = new AtomicInteger(0);
public EssentialsConf(final File configFile)
{
super();
- this.configFile = configFile;
+ this.configFile = configFile.getAbsoluteFile();
}
+ private final byte[] bytebuffer = new byte[1024];
public synchronized void load()
{
- configFile = configFile.getAbsoluteFile();
+ if (pendingDiskWrites.get() != 0)
+ {
+ LOGGER.log(Level.INFO, "File " + configFile + " not read, because it's not yet written to disk.");
+ return;
+ }
if (!configFile.getParentFile().exists())
{
if (!configFile.getParentFile().mkdirs())
@@ -94,18 +102,7 @@ public synchronized void load()
}
else
{
- try
- {
- LOGGER.log(Level.INFO, _("creatingEmptyConfig", configFile.toString()));
- if (!configFile.createNewFile())
- {
- LOGGER.log(Level.SEVERE, _("failedToCreateConfig", configFile.toString()));
- }
- }
- catch (IOException ex)
- {
- LOGGER.log(Level.SEVERE, _("failedToCreateConfig", configFile.toString()), ex);
- }
+ return;
}
}
@@ -115,9 +112,12 @@ public synchronized void load()
final FileInputStream inputStream = new FileInputStream(configFile);
try
{
- final FileChannel channel = inputStream.getChannel();
final ByteBuffer buffer = ByteBuffer.allocate((int)configFile.length());
- channel.read(buffer);
+ int length;
+ while ((length = inputStream.read(bytebuffer)) != -1)
+ {
+ buffer.put(bytebuffer, 0, length);
+ }
buffer.rewind();
final CharBuffer data = CharBuffer.allocate((int)configFile.length());
CharsetDecoder decoder = UTF8.newDecoder();
@@ -232,6 +232,148 @@ public void setTemplateName(final String templateName, final Class> resClass)
this.resourceClass = resClass;
}
+ public void save()
+ {
+ try
+ {
+ save(configFile);
+ }
+ catch (IOException ex)
+ {
+ LOGGER.log(Level.SEVERE, ex.getMessage(), ex);
+ }
+ }
+
+ public void saveWithError() throws IOException
+ {
+ save(configFile);
+ }
+
+ @Override
+ public synchronized void save(final File file) throws IOException
+ {
+ delayedSave(file);
+ }
+
+ public synchronized void forceSave()
+ {
+ try
+ {
+ Future> future = delayedSave(configFile);
+ if (future != null)
+ {
+ future.get();
+ }
+ }
+ catch (InterruptedException ex)
+ {
+ LOGGER.log(Level.SEVERE, ex.getMessage(), ex);
+ }
+ catch (ExecutionException ex)
+ {
+ LOGGER.log(Level.SEVERE, ex.getMessage(), ex);
+ }
+ }
+
+ private Future> delayedSave(final File file)
+ {
+ //long startTime = System.nanoTime();
+ if (file == null)
+ {
+ throw new IllegalArgumentException("File cannot be null");
+ }
+
+ final String data = saveToString();
+
+ if (data.length() == 0)
+ {
+ return null;
+ }
+
+ pendingDiskWrites.incrementAndGet();
+
+ Future> future = EXECUTOR_SERVICE.submit(new WriteRunner(configFile, data, pendingDiskWrites));
+
+ //LOGGER.log(Level.INFO, configFile + " prepared for writing in " + (System.nanoTime() - startTime) + " nsec.");
+
+ return future;
+ }
+
+
+ private static class WriteRunner implements Runnable
+ {
+ private final File configFile;
+ private final String data;
+ private final AtomicInteger pendingDiskWrites;
+
+ private WriteRunner(final File configFile, final String data, final AtomicInteger pendingDiskWrites)
+ {
+ this.configFile = configFile;
+ this.data = data;
+ this.pendingDiskWrites = pendingDiskWrites;
+ }
+
+ @Override
+ public void run()
+ {
+ //long startTime = System.nanoTime();
+ synchronized (configFile)
+ {
+ if (pendingDiskWrites.get() > 1)
+ {
+ // Writes can be skipped, because they are stored in a queue (in the executor).
+ // Only the last is actually written.
+ pendingDiskWrites.decrementAndGet();
+ //LOGGER.log(Level.INFO, configFile + " skipped writing in " + (System.nanoTime() - startTime) + " nsec.");
+ return;
+ }
+ try
+ {
+ Files.createParentDirs(configFile);
+
+ if (!configFile.exists())
+ {
+ try
+ {
+ LOGGER.log(Level.INFO, _("creatingEmptyConfig", configFile.toString()));
+ if (!configFile.createNewFile())
+ {
+ LOGGER.log(Level.SEVERE, _("failedToCreateConfig", configFile.toString()));
+ return;
+ }
+ }
+ catch (IOException ex)
+ {
+ LOGGER.log(Level.SEVERE, _("failedToCreateConfig", configFile.toString()), ex);
+ return;
+ }
+ }
+
+
+ final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(configFile), UTF8);
+
+ try
+ {
+ writer.write(data);
+ }
+ finally
+ {
+ writer.close();
+ }
+ }
+ catch (IOException e)
+ {
+ LOGGER.log(Level.SEVERE, e.getMessage(), e);
+ }
+ finally
+ {
+ //LOGGER.log(Level.INFO, configFile + " written to disk in " + (System.nanoTime() - startTime) + " nsec.");
+ pendingDiskWrites.decrementAndGet();
+ }
+ }
+ }
+ }
+
public boolean hasProperty(final String path)
{
return isSet(path);
@@ -316,81 +458,297 @@ public void setProperty(final String path, final ItemStack stack)
set(path, map);
}
- public long getLong(final String path, final long def)
+ public void setProperty(String path, List object)
{
- try
- {
- final Number num = (Number)get(path);
- return num == null ? def : num.longValue();
- }
- catch (ClassCastException ex)
- {
- return def;
- }
+ set(path, new ArrayList(object));
+ }
+
+ public void setProperty(String path, Map object)
+ {
+ set(path, new LinkedHashMap(object));
+ }
+
+ public Object getProperty(String path)
+ {
+ return get(path);
+ }
+
+ public void setProperty(String path, Object object)
+ {
+ set(path, object);
+ }
+
+ public void removeProperty(String path)
+ {
+ set(path, null);
}
@Override
- public double getDouble(final String path, final double def)
+ public synchronized Object get(String path)
{
- try
- {
- Number num = (Number)get(path);
- return num == null ? def : num.doubleValue();
- }
- catch (ClassCastException ex)
- {
- return def;
- }
+ return super.get(path);
}
- public void save()
+ @Override
+ public synchronized Object get(String path, Object def)
{
- try
- {
- save(configFile);
- }
- catch (IOException ex)
- {
- LOGGER.log(Level.SEVERE, ex.getMessage(), ex);
- }
+ return super.get(path, def);
}
@Override
- public synchronized void save(final File file) throws IOException
+ public synchronized boolean getBoolean(String path)
{
- if (file == null)
- {
- throw new IllegalArgumentException("File cannot be null");
- }
+ return super.getBoolean(path);
+ }
- Files.createParentDirs(file);
+ @Override
+ public synchronized boolean getBoolean(String path, boolean def)
+ {
+ return super.getBoolean(path, def);
+ }
- final String data = saveToString();
+ @Override
+ public synchronized List getBooleanList(String path)
+ {
+ return super.getBooleanList(path);
+ }
- final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(file), UTF8);
+ @Override
+ public synchronized List getByteList(String path)
+ {
+ return super.getByteList(path);
+ }
- try
- {
- writer.write(data);
- }
- finally
- {
- writer.close();
- }
+ @Override
+ public synchronized List getCharacterList(String path)
+ {
+ return super.getCharacterList(path);
}
- public Object getProperty(String path)
+ @Override
+ public synchronized ConfigurationSection getConfigurationSection(String path)
{
- return get(path);
+ return super.getConfigurationSection(path);
}
- public void setProperty(String path, Object object)
+ @Override
+ public synchronized double getDouble(String path)
{
- set(path, object);
+ return super.getDouble(path);
}
- public void removeProperty(String path)
+ @Override
+ public synchronized double getDouble(final String path, final double def)
{
- set(path, null);
+ return super.getDouble(path, def);
+ }
+
+ @Override
+ public synchronized List getDoubleList(String path)
+ {
+ return super.getDoubleList(path);
+ }
+
+ @Override
+ public synchronized List getFloatList(String path)
+ {
+ return super.getFloatList(path);
+ }
+
+ @Override
+ public synchronized int getInt(String path)
+ {
+ return super.getInt(path);
+ }
+
+ @Override
+ public synchronized int getInt(String path, int def)
+ {
+ return super.getInt(path, def);
+ }
+
+ @Override
+ public synchronized List getIntegerList(String path)
+ {
+ return super.getIntegerList(path);
+ }
+
+ @Override
+ public synchronized ItemStack getItemStack(String path, ItemStack def)
+ {
+ return super.getItemStack(path, def);
+ }
+
+ @Override
+ public synchronized Set getKeys(boolean deep)
+ {
+ return super.getKeys(deep);
+ }
+
+ @Override
+ public synchronized List> getList(String path)
+ {
+ return super.getList(path);
+ }
+
+ @Override
+ public synchronized List> getList(String path, List> def)
+ {
+ return super.getList(path, def);
+ }
+
+ @Override
+ public synchronized long getLong(String path)
+ {
+ return super.getLong(path);
+ }
+
+ @Override
+ public synchronized long getLong(final String path, final long def)
+ {
+ return super.getLong(path, def);
+ }
+
+ @Override
+ public synchronized List getLongList(String path)
+ {
+ return super.getLongList(path);
+ }
+
+ public synchronized Map getMap()
+ {
+ return map;
+ }
+
+ @Override
+ public synchronized List