From cb21bc4d7a67f0974c2773fdd0f5376f177c068e Mon Sep 17 00:00:00 2001 From: Zenexer Date: Wed, 30 Mar 2011 04:03:21 +0000 Subject: [PATCH] 2.1 prerelease, part 2 of 3 git-svn-id: https://svn.java.net/svn/essentials~svn/trunk2.1@1015 e251c2fe-e539-e718-e476-b85c1f46cddb --- BuildAll/build.xml | 74 + BuildAll/nbproject/build-impl.xml | 1142 ++++++++++++ BuildAll/nbproject/genfiles.properties | 8 + BuildAll/nbproject/private/config.properties | 0 BuildAll/nbproject/private/private.properties | 6 + BuildAll/nbproject/project.properties | 90 + BuildAll/nbproject/project.xml | 68 + Essentials/.gitignore | 7 + Essentials/build.xml | 75 + Essentials/nbproject/build-impl.xml | 1058 +++++++++++ Essentials/nbproject/genfiles.properties | 11 + .../nbproject/private/private.properties | 1 + Essentials/nbproject/project.properties | 76 + Essentials/nbproject/project.xml | 19 + Essentials/settings/Editor.zip | Bin 0 -> 18717 bytes .../src/com/earth2me/essentials/Backup.java | 82 + .../com/earth2me/essentials/Essentials.java | 684 +++++++ .../essentials/EssentialsBlockListener.java | 214 +++ .../earth2me/essentials/EssentialsConf.java | 120 ++ .../EssentialsEcoBlockListener.java | 159 ++ .../essentials/EssentialsEntityListener.java | 65 + .../essentials/EssentialsPlayerListener.java | 452 +++++ .../src/com/earth2me/essentials/IConf.java | 5 + .../essentials/InventoryWorkaround.java | 136 ++ .../src/com/earth2me/essentials/ItemDb.java | 110 ++ .../src/com/earth2me/essentials/Jail.java | 117 ++ .../src/com/earth2me/essentials/Mob.java | 122 ++ .../com/earth2me/essentials/NetherPortal.java | 167 ++ .../earth2me/essentials/OfflinePlayer.java | 351 ++++ .../earth2me/essentials/PlayerExtension.java | 141 ++ .../earth2me/essentials/PlayerWrapper.java | 416 +++++ .../src/com/earth2me/essentials/Settings.java | 348 ++++ .../src/com/earth2me/essentials/Spawn.java | 87 + .../com/earth2me/essentials/TargetBlock.java | 599 ++++++ .../earth2me/essentials/TeleportTimer.java | 73 + .../src/com/earth2me/essentials/User.java | 695 +++++++ .../src/com/earth2me/essentials/Warps.java | 244 +++ .../essentials/commands/Commandafk.java | 32 + .../essentials/commands/Commandantioch.java | 39 + .../essentials/commands/Commandback.java | 22 + .../essentials/commands/Commandbackup.java | 43 + .../essentials/commands/Commandbalance.java | 23 + .../essentials/commands/Commandban.java | 42 + .../essentials/commands/Commandbanip.java | 30 + .../essentials/commands/Commandbigtree.java | 56 + .../essentials/commands/Commandbroadcast.java | 32 + .../essentials/commands/Commandburn.java | 32 + .../commands/Commandclearinventory.java | 99 + .../essentials/commands/Commandcompass.java | 32 + .../essentials/commands/Commanddeljail.java | 33 + .../essentials/commands/Commanddelwarp.java | 41 + .../essentials/commands/Commanddepth.java | 24 + .../essentials/commands/Commandeco.java | 82 + .../commands/Commandessentials.java | 30 + .../essentials/commands/Commandext.java | 29 + .../essentials/commands/Commandgc.java | 29 + .../essentials/commands/Commandgetpos.java | 33 + .../essentials/commands/Commandgive.java | 49 + .../essentials/commands/Commandgod.java | 32 + .../essentials/commands/Commandheal.java | 53 + .../essentials/commands/Commandhelp.java | 129 ++ .../essentials/commands/Commandhelpop.java | 33 + .../essentials/commands/Commandhome.java | 21 + .../essentials/commands/Commandinvsee.java | 39 + .../essentials/commands/Commanditem.java | 45 + .../essentials/commands/Commandjails.java | 37 + .../essentials/commands/Commandjump.java | 50 + .../essentials/commands/Commandkick.java | 41 + .../essentials/commands/Commandkickall.java | 55 + .../essentials/commands/Commandkill.java | 33 + .../essentials/commands/Commandkit.java | 150 ++ .../essentials/commands/Commandlist.java | 93 + .../essentials/commands/Commandmail.java | 52 + .../essentials/commands/Commandme.java | 43 + .../essentials/commands/Commandmotd.java | 25 + .../essentials/commands/Commandmsg.java | 85 + .../essentials/commands/Commandmute.java | 64 + .../essentials/commands/Commandnick.java | 129 ++ .../essentials/commands/Commandnuble.java | 21 + .../essentials/commands/Commandpay.java | 42 + .../essentials/commands/Commandping.java | 26 + .../essentials/commands/Commandplugin.java | 161 ++ .../essentials/commands/Commandr.java | 37 + .../essentials/commands/Commandrealname.java | 40 + .../essentials/commands/Commandreloadall.java | 37 + .../essentials/commands/Commandrules.java | 23 + .../essentials/commands/Commandsell.java | 63 + .../essentials/commands/Commandsethome.java | 22 + .../essentials/commands/Commandsetjail.java | 28 + .../essentials/commands/Commandsetwarp.java | 30 + .../essentials/commands/Commandspawner.java | 41 + .../essentials/commands/Commandspawnmob.java | 188 ++ .../essentials/commands/Commandsuicide.java | 23 + .../essentials/commands/Commandtime.java | 63 + .../commands/Commandtogglejail.java | 67 + .../essentials/commands/Commandtop.java | 26 + .../essentials/commands/Commandtp.java | 61 + .../essentials/commands/Commandtpa.java | 34 + .../essentials/commands/Commandtpaccept.java | 40 + .../essentials/commands/Commandtpahere.java | 33 + .../essentials/commands/Commandtpdeny.java | 37 + .../essentials/commands/Commandtphere.java | 34 + .../essentials/commands/Commandtpo.java | 34 + .../essentials/commands/Commandtpohere.java | 31 + .../essentials/commands/Commandtppos.java | 42 + .../essentials/commands/Commandtptoggle.java | 21 + .../essentials/commands/Commandtree.java | 64 + .../essentials/commands/Commandunban.java | 35 + .../essentials/commands/Commandunbanip.java | 35 + .../essentials/commands/Commandwarp.java | 74 + .../essentials/commands/Commandwhois.java | 44 + .../essentials/commands/Commandworld.java | 67 + .../essentials/commands/Commandworth.java | 48 + .../commands/EssentialsCommand.java | 80 + .../commands/IEssentialsCommand.java | 20 + Essentials/src/config.yml | 385 ++++ Essentials/src/items.csv | 887 +++++++++ Essentials/src/plugin.yml | 248 +++ .../earth2me/essentials/EssentialsTest.java | 60 + .../earth2me/essentials/PermissionsTest.java | 17 + .../com/earth2me/essentials/UserTest.java | 72 + .../workdir/EssentialsGroupManager/config.yml | 0 Essentials/workdir/banned-ips.txt | 0 Essentials/workdir/banned-players.txt | 0 Essentials/workdir/ops.txt | 0 .../workdir/plugins/Permissions/default.yml | 0 Essentials/workdir/server.log | 264 +++ Essentials/workdir/server.log.1 | 0 Essentials/workdir/server.log.1.lck | 0 Essentials/workdir/server.properties | 13 + Essentials/workdir/userdata/TestPlayer1.yml | 2 + Essentials/workdir/white-list.txt | 0 EssentialsChat/build.xml | 76 + EssentialsChat/nbproject/build-impl.xml | 1072 +++++++++++ EssentialsChat/nbproject/genfiles.properties | 8 + .../nbproject/private/private.properties | 1 + EssentialsChat/nbproject/project.properties | 79 + EssentialsChat/nbproject/project.xml | 28 + .../essentials/chat/EssentialsChat.java | 43 + .../chat/EssentialsChatPlayerListener.java | 61 + .../essentials/chat/EssentialsChatWorker.java | 122 ++ EssentialsChat/src/plugin.yml | 8 + EssentialsGroupBridge/build.xml | 74 + .../nbproject/build-impl.xml | 1047 +++++++++++ .../nbproject/genfiles.properties | 8 + .../nbproject/private/private.properties | 1 + .../nbproject/project.properties | 78 + EssentialsGroupBridge/nbproject/project.xml | 25 + .../src/com/nijiko/Messaging.class | Bin 0 -> 2604 bytes .../src/com/nijiko/Misc$string.class | Bin 0 -> 982 bytes .../src/com/nijiko/Misc.class | Bin 0 -> 3980 bytes .../configuration/ConfigurationHandler.class | Bin 0 -> 788 bytes .../configuration/DefaultConfiguration.class | Bin 0 -> 435 bytes .../com/nijiko/database/Wrapper$Type.class | Bin 0 -> 1107 bytes .../src/com/nijiko/database/Wrapper.class | Bin 0 -> 5428 bytes .../src/com/nijiko/permissions/Control.class | Bin 0 -> 27337 bytes .../permissions/PermissionHandler.class | Bin 0 -> 3198 bytes .../bukkit/Permissions/Permissions.java | 102 + .../permissions/NijikoPermissionsProxy.java | 428 +++++ EssentialsGroupBridge/src/plugin.yml | 3 + EssentialsGroupManager/build.xml | 74 + .../nbproject/build-impl.xml | 1033 +++++++++++ .../nbproject/genfiles.properties | 8 + .../nbproject/private/private.properties | 1 + .../nbproject/project.properties | 73 + EssentialsGroupManager/nbproject/project.xml | 15 + EssentialsGroupManager/src/config.yml | 14 + EssentialsGroupManager/src/groups.yml | 172 ++ .../groupmanager/GMConfiguration.java | 120 ++ .../anjocaido/groupmanager/GroupManager.java | 1634 +++++++++++++++++ .../anjocaido/groupmanager/data/DataUnit.java | 114 ++ .../anjocaido/groupmanager/data/Group.java | 122 ++ .../groupmanager/data/GroupVariables.java | 87 + .../org/anjocaido/groupmanager/data/User.java | 187 ++ .../groupmanager/data/UserVariables.java | 45 + .../groupmanager/data/Variables.java | 192 ++ .../dataholder/OverloadedWorldHolder.java | 204 ++ .../dataholder/WorldDataHolder.java | 939 ++++++++++ .../dataholder/worlds/WorldsHolder.java | 423 +++++ .../permissions/AnjoPermissionsHandler.java | 856 +++++++++ .../PermissionsReaderInterface.java | 163 ++ .../groupmanager/utils/GMLoggerHandler.java | 26 + .../utils/GroupManagerPermissions.java | 51 + .../utils/PermissionCheckResult.java | 66 + .../utils/StringPermissionComparator.java | 50 + .../anjocaido/groupmanager/utils/Tasks.java | 111 ++ EssentialsGroupManager/src/plugin.yml | 165 ++ EssentialsGroupManager/src/users.yml | 59 + EssentialsProtect/MANIFEST.MF | 2 + EssentialsProtect/build.xml | 86 + EssentialsProtect/nbproject/build-impl.xml | 1072 +++++++++++ .../nbproject/genfiles.properties | 8 + .../nbproject/private/private.properties | 1 + .../nbproject/project.properties | 91 + EssentialsProtect/nbproject/project.xml | 28 + EssentialsProtect/src/README.TXT | 30 + .../essentials/protect/EssentialsProtect.java | 154 ++ .../EssentialsProtectBlockListener.java | 272 +++ .../protect/EssentialsProtectData.java | 533 ++++++ .../EssentialsProtectEntityListener.java | 197 ++ .../EssentialsProtectPlayerListener.java | 70 + .../protect/EssentialsProtectRegions.java | 5 + .../EssentialsProtectSqlProperties.java | 12 + .../protect/data/IProtectedBlock.java | 15 + .../essentials/protect/data/OwnedBlock.java | 9 + .../protect/data/ProtectedBlockJDBC.java | 292 +++ .../protect/data/ProtectedBlockMemory.java | 205 +++ .../protect/data/ProtectedBlockMySQL.java | 89 + .../protect/data/ProtectedBlockSQLite.java | 87 + EssentialsProtect/src/plugin.yml | 8 + EssentialsSpawn/build.xml | 76 + EssentialsSpawn/nbproject/build-impl.xml | 1072 +++++++++++ EssentialsSpawn/nbproject/genfiles.properties | 8 + .../nbproject/private/private.properties | 1 + EssentialsSpawn/nbproject/project.properties | 76 + EssentialsSpawn/nbproject/project.xml | 28 + .../essentials/spawn/Commandsetspawn.java | 24 + .../essentials/spawn/Commandspawn.java | 23 + .../essentials/spawn/EssentialsSpawn.java | 65 + .../spawn/EssentialsSpawnPlayerListener.java | 51 + .../spawn/EssentialsSpawnWorker.java | 56 + EssentialsSpawn/src/plugin.yml | 15 + build.inc.xml | 7 + ...-modules-java-j2seproject-copylibstask.jar | Bin 0 -> 17873 bytes lib/Permissions.jar | Bin 0 -> 32227 bytes lib/c3p0-0.9.1.2.jar | Bin 0 -> 610790 bytes lib/craftbukkit-0.0.1-SNAPSHOT.jar | Bin 0 -> 1458639 bytes lib/gson.jar | Bin 0 -> 164986 bytes lib/iConomy.jar | Bin 0 -> 65038 bytes lib/junit/junit-3.8.2-api.zip | Bin 0 -> 72555 bytes lib/junit/junit-3.8.2.jar | Bin 0 -> 118932 bytes lib/junit_4/junit-4.5-api.zip | Bin 0 -> 184067 bytes lib/junit_4/junit-4.5-src.jar | Bin 0 -> 109014 bytes lib/junit_4/junit-4.5.jar | Bin 0 -> 196787 bytes lib/mysql.jar | Bin 0 -> 703265 bytes lib/nblibraries.properties | 12 + lib/sqlite.jar | Bin 0 -> 1304214 bytes 237 files changed, 28831 insertions(+) create mode 100644 BuildAll/build.xml create mode 100644 BuildAll/nbproject/build-impl.xml create mode 100644 BuildAll/nbproject/genfiles.properties create mode 100644 BuildAll/nbproject/private/config.properties create mode 100644 BuildAll/nbproject/private/private.properties create mode 100644 BuildAll/nbproject/project.properties create mode 100644 BuildAll/nbproject/project.xml create mode 100644 Essentials/.gitignore create mode 100644 Essentials/build.xml create mode 100644 Essentials/nbproject/build-impl.xml create mode 100644 Essentials/nbproject/genfiles.properties create mode 100644 Essentials/nbproject/private/private.properties create mode 100644 Essentials/nbproject/project.properties create mode 100644 Essentials/nbproject/project.xml create mode 100644 Essentials/settings/Editor.zip create mode 100644 Essentials/src/com/earth2me/essentials/Backup.java create mode 100644 Essentials/src/com/earth2me/essentials/Essentials.java create mode 100644 Essentials/src/com/earth2me/essentials/EssentialsBlockListener.java create mode 100644 Essentials/src/com/earth2me/essentials/EssentialsConf.java create mode 100644 Essentials/src/com/earth2me/essentials/EssentialsEcoBlockListener.java create mode 100644 Essentials/src/com/earth2me/essentials/EssentialsEntityListener.java create mode 100644 Essentials/src/com/earth2me/essentials/EssentialsPlayerListener.java create mode 100644 Essentials/src/com/earth2me/essentials/IConf.java create mode 100644 Essentials/src/com/earth2me/essentials/InventoryWorkaround.java create mode 100644 Essentials/src/com/earth2me/essentials/ItemDb.java create mode 100644 Essentials/src/com/earth2me/essentials/Jail.java create mode 100644 Essentials/src/com/earth2me/essentials/Mob.java create mode 100644 Essentials/src/com/earth2me/essentials/NetherPortal.java create mode 100644 Essentials/src/com/earth2me/essentials/OfflinePlayer.java create mode 100644 Essentials/src/com/earth2me/essentials/PlayerExtension.java create mode 100644 Essentials/src/com/earth2me/essentials/PlayerWrapper.java create mode 100644 Essentials/src/com/earth2me/essentials/Settings.java create mode 100644 Essentials/src/com/earth2me/essentials/Spawn.java create mode 100644 Essentials/src/com/earth2me/essentials/TargetBlock.java create mode 100644 Essentials/src/com/earth2me/essentials/TeleportTimer.java create mode 100644 Essentials/src/com/earth2me/essentials/User.java create mode 100644 Essentials/src/com/earth2me/essentials/Warps.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandafk.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandantioch.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandback.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandbackup.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandbalance.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandban.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandbanip.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandbigtree.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandbroadcast.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandburn.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandclearinventory.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandcompass.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commanddeljail.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commanddelwarp.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commanddepth.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandeco.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandessentials.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandext.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandgc.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandgetpos.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandgive.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandgod.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandheal.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandhelp.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandhelpop.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandhome.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandinvsee.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commanditem.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandjails.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandjump.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandkick.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandkickall.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandkill.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandkit.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandlist.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandmail.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandme.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandmotd.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandmsg.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandmute.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandnick.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandnuble.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandpay.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandping.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandplugin.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandr.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandrealname.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandreloadall.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandrules.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandsell.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandsethome.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandsetjail.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandsetwarp.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandspawner.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandspawnmob.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandsuicide.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandtime.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandtogglejail.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandtop.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandtp.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandtpa.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandtpaccept.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandtpahere.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandtpdeny.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandtphere.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandtpo.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandtpohere.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandtppos.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandtptoggle.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandtree.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandunban.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandunbanip.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandwarp.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandwhois.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandworld.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/Commandworth.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/EssentialsCommand.java create mode 100644 Essentials/src/com/earth2me/essentials/commands/IEssentialsCommand.java create mode 100644 Essentials/src/config.yml create mode 100644 Essentials/src/items.csv create mode 100644 Essentials/src/plugin.yml create mode 100644 Essentials/test/com/earth2me/essentials/EssentialsTest.java create mode 100644 Essentials/test/com/earth2me/essentials/PermissionsTest.java create mode 100644 Essentials/test/com/earth2me/essentials/UserTest.java create mode 100644 Essentials/workdir/EssentialsGroupManager/config.yml create mode 100644 Essentials/workdir/banned-ips.txt create mode 100644 Essentials/workdir/banned-players.txt create mode 100644 Essentials/workdir/ops.txt create mode 100644 Essentials/workdir/plugins/Permissions/default.yml create mode 100644 Essentials/workdir/server.log create mode 100644 Essentials/workdir/server.log.1 create mode 100644 Essentials/workdir/server.log.1.lck create mode 100644 Essentials/workdir/server.properties create mode 100644 Essentials/workdir/userdata/TestPlayer1.yml create mode 100644 Essentials/workdir/white-list.txt create mode 100644 EssentialsChat/build.xml create mode 100644 EssentialsChat/nbproject/build-impl.xml create mode 100644 EssentialsChat/nbproject/genfiles.properties create mode 100644 EssentialsChat/nbproject/private/private.properties create mode 100644 EssentialsChat/nbproject/project.properties create mode 100644 EssentialsChat/nbproject/project.xml create mode 100644 EssentialsChat/src/com/earth2me/essentials/chat/EssentialsChat.java create mode 100644 EssentialsChat/src/com/earth2me/essentials/chat/EssentialsChatPlayerListener.java create mode 100644 EssentialsChat/src/com/earth2me/essentials/chat/EssentialsChatWorker.java create mode 100644 EssentialsChat/src/plugin.yml create mode 100644 EssentialsGroupBridge/build.xml create mode 100644 EssentialsGroupBridge/nbproject/build-impl.xml create mode 100644 EssentialsGroupBridge/nbproject/genfiles.properties create mode 100644 EssentialsGroupBridge/nbproject/private/private.properties create mode 100644 EssentialsGroupBridge/nbproject/project.properties create mode 100644 EssentialsGroupBridge/nbproject/project.xml create mode 100644 EssentialsGroupBridge/src/com/nijiko/Messaging.class create mode 100644 EssentialsGroupBridge/src/com/nijiko/Misc$string.class create mode 100644 EssentialsGroupBridge/src/com/nijiko/Misc.class create mode 100644 EssentialsGroupBridge/src/com/nijiko/configuration/ConfigurationHandler.class create mode 100644 EssentialsGroupBridge/src/com/nijiko/configuration/DefaultConfiguration.class create mode 100644 EssentialsGroupBridge/src/com/nijiko/database/Wrapper$Type.class create mode 100644 EssentialsGroupBridge/src/com/nijiko/database/Wrapper.class create mode 100644 EssentialsGroupBridge/src/com/nijiko/permissions/Control.class create mode 100644 EssentialsGroupBridge/src/com/nijiko/permissions/PermissionHandler.class create mode 100644 EssentialsGroupBridge/src/com/nijikokun/bukkit/Permissions/Permissions.java create mode 100644 EssentialsGroupBridge/src/org/anjocaido/groupmanager/permissions/NijikoPermissionsProxy.java create mode 100644 EssentialsGroupBridge/src/plugin.yml create mode 100644 EssentialsGroupManager/build.xml create mode 100644 EssentialsGroupManager/nbproject/build-impl.xml create mode 100644 EssentialsGroupManager/nbproject/genfiles.properties create mode 100644 EssentialsGroupManager/nbproject/private/private.properties create mode 100644 EssentialsGroupManager/nbproject/project.properties create mode 100644 EssentialsGroupManager/nbproject/project.xml create mode 100644 EssentialsGroupManager/src/config.yml create mode 100644 EssentialsGroupManager/src/groups.yml create mode 100644 EssentialsGroupManager/src/org/anjocaido/groupmanager/GMConfiguration.java create mode 100644 EssentialsGroupManager/src/org/anjocaido/groupmanager/GroupManager.java create mode 100644 EssentialsGroupManager/src/org/anjocaido/groupmanager/data/DataUnit.java create mode 100644 EssentialsGroupManager/src/org/anjocaido/groupmanager/data/Group.java create mode 100644 EssentialsGroupManager/src/org/anjocaido/groupmanager/data/GroupVariables.java create mode 100644 EssentialsGroupManager/src/org/anjocaido/groupmanager/data/User.java create mode 100644 EssentialsGroupManager/src/org/anjocaido/groupmanager/data/UserVariables.java create mode 100644 EssentialsGroupManager/src/org/anjocaido/groupmanager/data/Variables.java create mode 100644 EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/OverloadedWorldHolder.java create mode 100644 EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/WorldDataHolder.java create mode 100644 EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/worlds/WorldsHolder.java create mode 100644 EssentialsGroupManager/src/org/anjocaido/groupmanager/permissions/AnjoPermissionsHandler.java create mode 100644 EssentialsGroupManager/src/org/anjocaido/groupmanager/permissions/PermissionsReaderInterface.java create mode 100644 EssentialsGroupManager/src/org/anjocaido/groupmanager/utils/GMLoggerHandler.java create mode 100644 EssentialsGroupManager/src/org/anjocaido/groupmanager/utils/GroupManagerPermissions.java create mode 100644 EssentialsGroupManager/src/org/anjocaido/groupmanager/utils/PermissionCheckResult.java create mode 100644 EssentialsGroupManager/src/org/anjocaido/groupmanager/utils/StringPermissionComparator.java create mode 100644 EssentialsGroupManager/src/org/anjocaido/groupmanager/utils/Tasks.java create mode 100644 EssentialsGroupManager/src/plugin.yml create mode 100644 EssentialsGroupManager/src/users.yml create mode 100644 EssentialsProtect/MANIFEST.MF create mode 100644 EssentialsProtect/build.xml create mode 100644 EssentialsProtect/nbproject/build-impl.xml create mode 100644 EssentialsProtect/nbproject/genfiles.properties create mode 100644 EssentialsProtect/nbproject/private/private.properties create mode 100644 EssentialsProtect/nbproject/project.properties create mode 100644 EssentialsProtect/nbproject/project.xml create mode 100644 EssentialsProtect/src/README.TXT create mode 100644 EssentialsProtect/src/com/earth2me/essentials/protect/EssentialsProtect.java create mode 100644 EssentialsProtect/src/com/earth2me/essentials/protect/EssentialsProtectBlockListener.java create mode 100644 EssentialsProtect/src/com/earth2me/essentials/protect/EssentialsProtectData.java create mode 100644 EssentialsProtect/src/com/earth2me/essentials/protect/EssentialsProtectEntityListener.java create mode 100644 EssentialsProtect/src/com/earth2me/essentials/protect/EssentialsProtectPlayerListener.java create mode 100644 EssentialsProtect/src/com/earth2me/essentials/protect/EssentialsProtectRegions.java create mode 100644 EssentialsProtect/src/com/earth2me/essentials/protect/EssentialsProtectSqlProperties.java create mode 100644 EssentialsProtect/src/com/earth2me/essentials/protect/data/IProtectedBlock.java create mode 100644 EssentialsProtect/src/com/earth2me/essentials/protect/data/OwnedBlock.java create mode 100644 EssentialsProtect/src/com/earth2me/essentials/protect/data/ProtectedBlockJDBC.java create mode 100644 EssentialsProtect/src/com/earth2me/essentials/protect/data/ProtectedBlockMemory.java create mode 100644 EssentialsProtect/src/com/earth2me/essentials/protect/data/ProtectedBlockMySQL.java create mode 100644 EssentialsProtect/src/com/earth2me/essentials/protect/data/ProtectedBlockSQLite.java create mode 100644 EssentialsProtect/src/plugin.yml create mode 100644 EssentialsSpawn/build.xml create mode 100644 EssentialsSpawn/nbproject/build-impl.xml create mode 100644 EssentialsSpawn/nbproject/genfiles.properties create mode 100644 EssentialsSpawn/nbproject/private/private.properties create mode 100644 EssentialsSpawn/nbproject/project.properties create mode 100644 EssentialsSpawn/nbproject/project.xml create mode 100644 EssentialsSpawn/src/com/earth2me/essentials/spawn/Commandsetspawn.java create mode 100644 EssentialsSpawn/src/com/earth2me/essentials/spawn/Commandspawn.java create mode 100644 EssentialsSpawn/src/com/earth2me/essentials/spawn/EssentialsSpawn.java create mode 100644 EssentialsSpawn/src/com/earth2me/essentials/spawn/EssentialsSpawnPlayerListener.java create mode 100644 EssentialsSpawn/src/com/earth2me/essentials/spawn/EssentialsSpawnWorker.java create mode 100644 EssentialsSpawn/src/plugin.yml create mode 100644 build.inc.xml create mode 100644 lib/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar create mode 100644 lib/Permissions.jar create mode 100644 lib/c3p0-0.9.1.2.jar create mode 100644 lib/craftbukkit-0.0.1-SNAPSHOT.jar create mode 100644 lib/gson.jar create mode 100644 lib/iConomy.jar create mode 100644 lib/junit/junit-3.8.2-api.zip create mode 100644 lib/junit/junit-3.8.2.jar create mode 100644 lib/junit_4/junit-4.5-api.zip create mode 100644 lib/junit_4/junit-4.5-src.jar create mode 100644 lib/junit_4/junit-4.5.jar create mode 100644 lib/mysql.jar create mode 100644 lib/nblibraries.properties create mode 100644 lib/sqlite.jar diff --git a/BuildAll/build.xml b/BuildAll/build.xml new file mode 100644 index 000000000..496f85c34 --- /dev/null +++ b/BuildAll/build.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + Builds, tests, and runs the project BuildAll. + + + diff --git a/BuildAll/nbproject/build-impl.xml b/BuildAll/nbproject/build-impl.xml new file mode 100644 index 000000000..09a0e0d9d --- /dev/null +++ b/BuildAll/nbproject/build-impl.xml @@ -0,0 +1,1142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + + + + + + java -cp "${run.classpath.with.dist.jar}" ${main.class} + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + + + + + + + + Must select one file in the IDE or set profile.class + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + 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 applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BuildAll/nbproject/genfiles.properties b/BuildAll/nbproject/genfiles.properties new file mode 100644 index 000000000..55c9a217a --- /dev/null +++ b/BuildAll/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=60061751 +build.xml.script.CRC32=7a797370 +build.xml.stylesheet.CRC32=28e38971@1.42.1.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=60061751 +nbproject/build-impl.xml.script.CRC32=5fce336c +nbproject/build-impl.xml.stylesheet.CRC32=19debb58@1.42.1.45 diff --git a/BuildAll/nbproject/private/config.properties b/BuildAll/nbproject/private/config.properties new file mode 100644 index 000000000..e69de29bb diff --git a/BuildAll/nbproject/private/private.properties b/BuildAll/nbproject/private/private.properties new file mode 100644 index 000000000..999794c06 --- /dev/null +++ b/BuildAll/nbproject/private/private.properties @@ -0,0 +1,6 @@ +compile.on.save=false +do.depend=false +do.jar=true +javac.debug=true +javadoc.preview=true +user.properties.file=C:\\Users\\Paul\\.netbeans\\7.0beta2\\build.properties diff --git a/BuildAll/nbproject/project.properties b/BuildAll/nbproject/project.properties new file mode 100644 index 000000000..6b8e235e1 --- /dev/null +++ b/BuildAll/nbproject/project.properties @@ -0,0 +1,90 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.title=BuildAll +application.vendor=Paul +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/BuildAll.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +includes=** +jar.compress=false +javac.classpath=\ + ${reference.Essentials.jar}:\ + ${reference.EssentialsChat.jar}:\ + ${reference.EssentialsGroupBridge.jar}:\ + ${reference.EssentialsGroupManager.jar}:\ + ${reference.EssentialsProtect.jar}:\ + ${reference.EssentialsSpawn.jar} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.5 +javac.target=1.5 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir}:\ + ${libs.junit.classpath}:\ + ${libs.junit_4.classpath} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +project.Essentials=../Essentials +project.EssentialsChat=../EssentialsChat +project.EssentialsGroupBridge=../EssentialsGroupBridge +project.EssentialsGroupManager=../EssentialsGroupManager +project.EssentialsProtect=../EssentialsProtect +project.EssentialsSpawn=../EssentialsSpawn +reference.Essentials.jar=${project.Essentials}/dist/Essentials.jar +reference.EssentialsChat.jar=${project.EssentialsChat}/dist/EssentialsChat.jar +reference.EssentialsGroupBridge.jar=${project.EssentialsGroupBridge}/dist/EssentialsGroupBridge.jar +reference.EssentialsGroupManager.jar=${project.EssentialsGroupManager}/dist/EssentialsGroupManager.jar +reference.EssentialsProtect.jar=${project.EssentialsProtect}/dist/original-EssentialsProtect.jar +reference.EssentialsSpawn.jar=${project.EssentialsSpawn}/dist/EssentialsSpawn.jar +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project +# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value +# or test-sys-prop.name=value to set system properties for unit tests): +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/BuildAll/nbproject/project.xml b/BuildAll/nbproject/project.xml new file mode 100644 index 000000000..86e1cc4a7 --- /dev/null +++ b/BuildAll/nbproject/project.xml @@ -0,0 +1,68 @@ + + + org.netbeans.modules.java.j2seproject + + + BuildAll + + + + + + + + + ..\lib\nblibraries.properties + + + + Essentials + jar + + jar + clean + jar + + + EssentialsChat + jar + + jar + clean + jar + + + EssentialsGroupBridge + jar + + jar + clean + jar + + + EssentialsGroupManager + jar + + jar + clean + jar + + + EssentialsProtect + jar + + jar + clean + jar + + + EssentialsSpawn + jar + + jar + clean + jar + + + + diff --git a/Essentials/.gitignore b/Essentials/.gitignore new file mode 100644 index 000000000..437c8c683 --- /dev/null +++ b/Essentials/.gitignore @@ -0,0 +1,7 @@ +# NetBeans cruft +/build +/dist +/nbproject/private + +# Mac cruft +.DS_Store diff --git a/Essentials/build.xml b/Essentials/build.xml new file mode 100644 index 000000000..0742d234f --- /dev/null +++ b/Essentials/build.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + Builds, tests, and runs the project Essentials. + + + diff --git a/Essentials/nbproject/build-impl.xml b/Essentials/nbproject/build-impl.xml new file mode 100644 index 000000000..131d7414d --- /dev/null +++ b/Essentials/nbproject/build-impl.xml @@ -0,0 +1,1058 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + + + + + + java -cp "${run.classpath.with.dist.jar}" ${main.class} + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + + + + + + + + Must select one file in the IDE or set profile.class + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + 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 applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Essentials/nbproject/genfiles.properties b/Essentials/nbproject/genfiles.properties new file mode 100644 index 000000000..169fb44fa --- /dev/null +++ b/Essentials/nbproject/genfiles.properties @@ -0,0 +1,11 @@ +build.xml.data.CRC32=7d758acf +build.xml.script.CRC32=3233ee78 +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=ab78ce15 +nbproject/build-impl.xml.script.CRC32=4b464ee6 +nbproject/build-impl.xml.stylesheet.CRC32=19debb58@1.42.1.45 +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/private/private.properties b/Essentials/nbproject/private/private.properties new file mode 100644 index 000000000..94183418a --- /dev/null +++ b/Essentials/nbproject/private/private.properties @@ -0,0 +1 @@ +user.properties.file=C:\\Users\\Paul\\.netbeans\\7.0beta2\\build.properties diff --git a/Essentials/nbproject/project.properties b/Essentials/nbproject/project.properties new file mode 100644 index 000000000..67c5646c9 --- /dev/null +++ b/Essentials/nbproject/project.properties @@ -0,0 +1,76 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.title=Essentials +application.vendor=Paul +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/Essentials.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +file.reference.craftbukkit-0.0.1-SNAPSHOT.jar=..\\lib\\craftbukkit-0.0.1-SNAPSHOT.jar +file.reference.iConomy.jar=..\\lib\\iConomy.jar +file.reference.Permissions.jar=..\\lib\\Permissions.jar +includes=** +jar.compress=false +javac.classpath=\ + ${file.reference.iConomy.jar}:\ + ${file.reference.Permissions.jar}:\ + ${file.reference.craftbukkit-0.0.1-SNAPSHOT.jar} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.5 +javac.target=1.5 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project +# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value +# or test-sys-prop.name=value to set system properties for unit tests): +run.jvmargs=-Djline.terminal=jline.UnsupportedTerminal +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/Essentials/nbproject/project.xml b/Essentials/nbproject/project.xml new file mode 100644 index 000000000..aa1a9f770 --- /dev/null +++ b/Essentials/nbproject/project.xml @@ -0,0 +1,19 @@ + + + org.netbeans.modules.java.j2seproject + + + Essentials + + + + + + + + + ../lib\nblibraries.properties + + + + diff --git a/Essentials/settings/Editor.zip b/Essentials/settings/Editor.zip new file mode 100644 index 0000000000000000000000000000000000000000..7635328f8b9f4289992a488625b474398eff1a57 GIT binary patch literal 18717 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 A$p8QV literal 0 HcmV?d00001 diff --git a/Essentials/src/com/earth2me/essentials/Backup.java b/Essentials/src/com/earth2me/essentials/Backup.java new file mode 100644 index 000000000..aa0cb1476 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/Backup.java @@ -0,0 +1,82 @@ +package com.earth2me.essentials; + +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.bukkit.command.CommandSender; +import org.bukkit.craftbukkit.CraftServer; + +public class Backup implements Runnable { + private static final Logger logger = Logger.getLogger("Minecraft"); + private CraftServer server; + private boolean running = false; + private int taskId = -1; + private boolean active = false; + + public Backup() { + server = (CraftServer)Essentials.getStatic().getServer(); + if (server.getOnlinePlayers().length > 0) { + startTask(); + } + } + + void onPlayerJoin() { + startTask(); + } + + private void startTask() { + if (!running) { + long interval = Essentials.getSettings().getBackupInterval()*1200; // minutes -> ticks + if (interval < 1200) { + return; + } + taskId = server.getScheduler().scheduleSyncRepeatingTask(Essentials.getStatic(), this, interval, interval); + running = true; + } + } + + public void run() { + if (active) return; + active = true; + final String command = Essentials.getSettings().getBackupCommand(); + if (command == null || "".equals(command)) { + return; + } + logger.log(Level.INFO, "Backup started"); + final CommandSender cs = server.getServer().console; + server.dispatchCommand(cs, "save-all"); + server.dispatchCommand(cs, "save-off"); + + server.getScheduler().scheduleAsyncDelayedTask(Essentials.getStatic(), + new Runnable() { + + public void run() { + try { + Process child = Runtime.getRuntime().exec(command); + child.waitFor(); + } catch (InterruptedException ex) { + logger.log(Level.SEVERE, null, ex); + } catch (IOException ex) { + logger.log(Level.SEVERE, null, ex); + } finally { + server.getScheduler().scheduleSyncDelayedTask(Essentials.getStatic(), + new Runnable() { + + public void run() { + server.dispatchCommand(cs, "save-on"); + if (server.getOnlinePlayers().length == 0) { + running = false; + if (taskId != -1) { + server.getScheduler().cancelTask(taskId); + } + } + active = false; + logger.log(Level.INFO, "Backup finished"); + } + }); + } + } + }); + } + +} diff --git a/Essentials/src/com/earth2me/essentials/Essentials.java b/Essentials/src/com/earth2me/essentials/Essentials.java new file mode 100644 index 000000000..f9bd1d655 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/Essentials.java @@ -0,0 +1,684 @@ +package com.earth2me.essentials; + +import com.earth2me.essentials.commands.EssentialsCommand; +import java.io.*; +import java.util.*; +import java.util.logging.*; +import org.bukkit.*; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import com.earth2me.essentials.commands.IEssentialsCommand; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.bukkit.command.PluginCommand; +import org.bukkit.craftbukkit.scheduler.CraftScheduler; +import org.bukkit.entity.Player; +import org.bukkit.event.Event.Priority; +import org.bukkit.event.Event.Type; +import org.bukkit.plugin.*; +import org.bukkit.plugin.java.*; +import org.yaml.snakeyaml.*; +import org.yaml.snakeyaml.constructor.SafeConstructor; +import org.yaml.snakeyaml.reader.UnicodeReader; + + +public class Essentials extends JavaPlugin +{ + public static final String AUTHORS = "Zenexer, ementalo, Aelux, Brettflan, KimKandor, snowleo and ceulemans."; + public static final int minBukkitBuildVersion = 556; + private static final Logger logger = Logger.getLogger("Minecraft"); + private static final Yaml yaml = new Yaml(new SafeConstructor()); + private static Map users; + private static Settings settings; + private static final Object usersLock = new Object(); + public static Object permissions = null; + public final Map tpcRequests = new HashMap(); + public final Map tpcHere = new HashMap(); + public final List away = new ArrayList(); + private EssentialsPlayerListener playerListener; + private EssentialsBlockListener blockListener; + private EssentialsEntityListener entityListener; + private static Essentials staticThis = null; + public Spawn spawn; + private Jail jail; + private Warps warps; + private List confList; + public ArrayList bans = new ArrayList(); + public ArrayList bannedIps = new ArrayList(); + public Backup backup; + + public Essentials() throws IOException + { + loadClasses(); + } + + public static void ensureEnabled(Server server) + { + PluginManager pm = server.getPluginManager(); + Essentials ess = (Essentials)pm.getPlugin("Essentials"); + if (!ess.isEnabled()) + pm.enablePlugin(ess); + loadClasses(); + } + + @SuppressWarnings("CallToThreadDumpStack") + public static void loadClasses() + { + final String[] classes = new String[] + { + "commands.IEssentialsCommand", + "commands.EssentialsCommand", + "User", + "TargetBlock", + "Spawn", + "Settings", + "OfflinePlayer", + "ItemDb", + "Mob" + }; + + try + { + for (String c : classes) + Essentials.class.getClassLoader().loadClass("com.earth2me.essentials." + c); + } + catch (Throwable ex) + { + ex.printStackTrace(); + } + } + + public static Essentials getStatic() + { + return staticThis; + } + + public static Settings getSettings() + { + return settings; + } + + public void setupPermissions() + { + Plugin permPlugin = this.getServer().getPluginManager().getPlugin("Permissions"); + if (permissions == null && permPlugin != null) permissions = permPlugin; + } + + public Player getPlayer(String[] args, int pos) + throws IndexOutOfBoundsException, NoSuchFieldException + { + if (args.length <= pos) throw new IndexOutOfBoundsException("§cInvalid command syntax. Did you forget an argument?"); + List matches = getServer().matchPlayer(args[0]); + if (matches.size() < 1) throw new NoSuchFieldException("§cNo matching players could be found."); + return matches.get(0); + } + + public void setStatic() + { + staticThis = this; + } + + @SuppressWarnings("LoggerStringConcat") + public void onEnable() + { + setStatic(); + confList = new ArrayList(); + settings = new Settings(this.getDataFolder()); + confList.add(settings); + this.spawn = new Spawn(getServer(), this.getDataFolder()); + confList.add(spawn); + warps = new Warps(getServer(), this.getDataFolder()); + confList.add(warps); + reload(); + this.backup = new Backup(); + + PluginManager pm = getServer().getPluginManager(); + for (Plugin plugin : pm.getPlugins()) { + if (plugin.getDescription().getName().startsWith("Essentials")) { + if (!plugin.getDescription().getVersion().equals(this.getDescription().getVersion())) { + logger.log(Level.WARNING, "Version mismatch! Please update "+plugin.getDescription().getName()+" to the same version."); + } + } + } + Matcher versionMatch = Pattern.compile("git-Bukkit-([0-9]+).([0-9]+).([0-9]+)-[0-9]+-[0-9a-z]+-b([0-9]+)jnks.*").matcher(getServer().getVersion()); + if (versionMatch.matches()) { + int versionNumber = Integer.parseInt(versionMatch.group(4)); + if (versionNumber < minBukkitBuildVersion) { + logger.log(Level.WARNING, "Bukkit version is not the recommended build for Essentials."); + } + } else { + logger.log(Level.INFO, "Bukkit version format changed. Version not checked."); + } + + + playerListener = new EssentialsPlayerListener(this); + pm.registerEvent(Type.PLAYER_JOIN, playerListener, Priority.Monitor, this); + pm.registerEvent(Type.PLAYER_QUIT, playerListener, Priority.Monitor, this); + pm.registerEvent(Type.PLAYER_CHAT, playerListener, Priority.Monitor, this); + if (getSettings().getNetherPortalsEnabled()) + pm.registerEvent(Type.PLAYER_MOVE, playerListener, Priority.High, this); + pm.registerEvent(Type.PLAYER_LOGIN, playerListener, Priority.High, this); + pm.registerEvent(Type.PLAYER_TELEPORT, playerListener, Priority.High, this); + pm.registerEvent(Type.PLAYER_INTERACT, playerListener, Priority.Monitor, this); + + blockListener = new EssentialsBlockListener(this); + pm.registerEvent(Type.SIGN_CHANGE, blockListener, Priority.Monitor, this); + pm.registerEvent(Type.BLOCK_BREAK, blockListener, Priority.Monitor, this); + pm.registerEvent(Type.BLOCK_PLACE, blockListener, Priority.Monitor, this); + + entityListener = new EssentialsEntityListener(this); + pm.registerEvent(Type.ENTITY_DAMAGE, entityListener, Priority.Lowest, this); + pm.registerEvent(Type.ENTITY_COMBUST, entityListener, Priority.Lowest, this); + pm.registerEvent(Type.ENTITY_DEATH, entityListener, Priority.Lowest, this); + + jail = new Jail(this.getDataFolder()); + confList.add(jail); + pm.registerEvent(Type.BLOCK_BREAK, jail, Priority.High, this); + pm.registerEvent(Type.BLOCK_DAMAGE, jail, Priority.High, this); + pm.registerEvent(Type.BLOCK_PLACE, jail, Priority.High, this); + + attachEcoListeners(); + + if (settings.isNetherEnabled() && getServer().getWorlds().size() < 2) + { + getServer().createWorld(settings.getNetherName(), World.Environment.NETHER); + } + + logger.info("Loaded " + this.getDescription().getName() + " build " + this.getDescription().getVersion() + " maintained by " + AUTHORS); + } + + public void onDisable() + { + staticThis = null; + } + + public void reload() + { + loadData(); + loadBanList(); + + for (IConf iConf : confList) + { + iConf.reloadConfig(); + } + + try + { + ItemDb.load(getDataFolder(), "items.csv"); + } + catch (Exception ex) + { + logger.log(Level.WARNING, "Could not load items.csv.", ex); + } + } + + public static Map getData(User player) + { + return getData(player.getName()); + } + + public static Map getData(String player) + { + try + { + Map retval; + synchronized (usersLock) + { + retval = (Map)users.get(player.toLowerCase()); + } + return retval == null ? new HashMap() : retval; + } + catch (Throwable ex) + { + return new HashMap(); + } + } + + public static void flushData() + { + Thread run = new Thread(new Runnable() + { + @Override + public void run() + { + try + { + if (!Essentials.getStatic().getDataFolder().exists()) + Essentials.getStatic().getDataFolder().mkdirs(); + File file = new File(Essentials.getStatic().getDataFolder(), "users.yml"); + if (!file.exists()) + file.createNewFile(); + + FileWriter tx = new FileWriter(file); + synchronized (usersLock) + { + tx.write(yaml.dump(users)); + } + tx.flush(); + tx.close(); + } + catch (Throwable ex) + { + Logger.getLogger(Essentials.class.getName()).log(Level.SEVERE, null, ex); + } + } + }); + run.setDaemon(false); + run.start(); + } + + public static void loadData() + { + try + { + if (!Essentials.getStatic().getDataFolder().exists()) Essentials.getStatic().getDataFolder().mkdirs(); + File file = new File(Essentials.getStatic().getDataFolder(), "users.yml"); + if (!file.exists()) file.createNewFile(); + + FileInputStream rx = new FileInputStream(file); + synchronized (usersLock) + { + users = (Map)yaml.load(new UnicodeReader(rx)); + } + rx.close(); + } + catch (Exception ex) + { + Logger.getLogger(Essentials.class.getName()).log(Level.SEVERE, null, ex); + synchronized (usersLock) + { + users = new HashMap(); + } + } + finally + { + synchronized (usersLock) + { + if (users == null) users = new HashMap(); + } + } + } + + public static void setData(User player, Map data) + { + setData(player.getName(), data); + } + + public static void setData(String player, Map data) + { + synchronized (usersLock) + { + users.put(player.toLowerCase(), data); + } + } + + public static List readMail(User player) + { + return readMail(player.getName()); + } + + public static List readMail(String player) + { + try + { + Map data = getData(player); + List retval = (List)data.get("mail"); + return retval == null ? new ArrayList() : retval; + } + catch (Throwable ex) + { + return new ArrayList(); + } + } + + public static void clearMail(User player) + { + try + { + Map data = getData(player); + data.put("mail", new ArrayList()); + setData(player, data); + flushData(); + } + catch (Throwable ex) + { + } + } + + public static void sendMail(User from, String to, String message) + throws Exception + { + try + { + Map data = getData(ChatColor.stripColor(to)); + List mail = readMail(to); + mail.add(ChatColor.stripColor(from.getDisplayName()) + ": " + message); + data.put("mail", mail); + setData(to, data); + flushData(); + } + catch (Throwable ex) + { + throw new Exception("An error was encountered while sending the mail.", ex); + } + } + + public String readNickname(User player) + { + try + { + Map data = getData(player); + String nick = (String)data.get("nickname"); + if (nick == null) + return player.getName(); + if (nick.equals(player.getName())) + return player.getName(); + return getSettings().getNicknamePrefix() + nick; + } + catch (Exception ex) + { + return player.getName(); + } + } + + public void saveNickname(User player, String nickname) throws Exception + { + try + { + Map data = getData(player); + data.put("nickname", nickname); + setData(player, data); + flushData(); + } + catch (Throwable ex) + { + throw new Exception("An error was encountered while saving the nickname.", ex); + } + } + + public String[] getMotd(CommandSender sender, String def) + { + return getLines(sender, "motd", def); + } + + public String[] getLines(CommandSender sender, String node, String def) + { + List lines = (List)getConfiguration().getProperty(node); + if (lines == null) return new String[0]; + String[] retval = new String[lines.size()]; + + if (lines == null || lines.isEmpty() || lines.get(0) == null) + { + try + { + lines = new ArrayList(); + // "[]" in YaML indicates empty array, so respect that + if (!getConfiguration().getString(node, def).equals("[]")) + { + lines.add(getConfiguration().getString(node, def)); + retval = new String[lines.size()]; + } + } + catch (Throwable ex2) + { + System.out.println(ChatColor.DARK_RED + "Notice: Your configuration file has a corrupt " + node + " node."); + return new String[0]; + } + } + + // if still empty, call it a day + if (lines == null || lines.isEmpty() || lines.get(0) == null) + return new String[0]; + + for (int i = 0; i < lines.size(); i++) + { + String m = lines.get(i); + if (m == null) + continue; + m = m.replace('&', '§').replace("§§", "&"); + + if (sender instanceof User || sender instanceof Player) + { + User user = User.get(sender); + m = m.replace("{PLAYER}", user.getDisplayName()); + m = m.replace("{IP}", user.getAddress().toString()); + m = m.replace("{BALANCE}", Double.toString(user.getMoney())); + } + + m = m.replace("{ONLINE}", Integer.toString(getServer().getOnlinePlayers().length)); + + if (m.matches(".*\\{PLAYERLIST\\}.*")) + { + StringBuilder online = new StringBuilder(); + for (Player p : getServer().getOnlinePlayers()) + { + if (online.length() > 0) + online.append(", "); + online.append(p.getDisplayName()); + } + m = m.replace("{PLAYERLIST}", online.toString()); + } + + if (sender instanceof Player) + { + try + { + Class User = getClassLoader().loadClass("bukkit.Vandolis.User"); + Object vuser = User.getConstructor(User.class).newInstance((Player)sender); + m = m.replace("{RED:BALANCE}", User.getMethod("getMoney").invoke(vuser).toString()); + m = m.replace("{RED:BUYS}", User.getMethod("getNumTransactionsBuy").invoke(vuser).toString()); + m = m.replace("{RED:SELLS}", User.getMethod("getNumTransactionsSell").invoke(vuser).toString()); + } + catch (Throwable ex) + { + m = m.replace("{RED:BALANCE}", "N/A"); + m = m.replace("{RED:BUYS}", "N/A"); + m = m.replace("{RED:SELLS}", "N/A"); + } + } + + retval[i] = m + " "; + } + return retval; + } + + public static String FormatTime(long Milliseconds) + { // format time into a string showing hours, minutes, or seconds + if (Milliseconds > 3600000) + { + double val = Math.round((double)Milliseconds / 360000D) / 10D; + return val + " hour" + (val > 1 ? "s" : ""); + } + else if (Milliseconds > 60000) + { + double val = Math.round((double)Milliseconds / 6000D) / 10D; + return val + " minute" + (val > 1 ? "s" : ""); + } + else if (Milliseconds <= 1000) + return "1 second"; + else + return (Milliseconds / 1000L) + " seconds"; + } + + @SuppressWarnings("LoggerStringConcat") + public static void previewCommand(CommandSender sender, Command command, String commandLabel, String[] args) + { + if (sender instanceof Player) + logger.info(ChatColor.BLUE + "[PLAYER_COMMAND] " + ((Player)sender).getName() + ": /" + commandLabel + " " + EssentialsCommand.getFinalArg(args, 0)); + } + + @Override + @SuppressWarnings( + { + "LoggerStringConcat", "CallToThreadDumpStack" + }) + public boolean onCommand(CommandSender sender, Command command, String commandLabel, String[] args) + { + // Allow plugins to override the command via onCommand + for (Plugin p : getServer().getPluginManager().getPlugins()) + { + if (p == this) + continue; + + PluginDescriptionFile desc = p.getDescription(); + if (desc == null) + continue; + + if (desc.getName() == null) + continue; + + if (!(desc.getCommands() instanceof Map)) + continue; + + Map cmds = (Map)desc.getCommands(); + if (!cmds.containsKey(command.getName())) + continue; + + PluginCommand pcmd = getServer().getPluginCommand(desc.getName() + ":" + commandLabel); + + if (pcmd == null) + continue; + + return getServer().getPluginCommand(p.getDescription().getName() + ":" + commandLabel).execute(sender, commandLabel, args); + } + + try + { + previewCommand(sender, command, commandLabel, args); + User user = sender instanceof Player ? User.get(sender) : null; + + // New mail notification + if (user != null && !Essentials.getSettings().isCommandDisabled("mail") && !commandLabel.equals("mail")) + { + List mail = Essentials.readMail(user); + if (!mail.isEmpty()) user.sendMessage(ChatColor.RED + "You have " + mail.size() + " messages!§f Type §7/mail read§f to view your mail."); + } + + // Check for disabled commands + if (Essentials.getSettings().isCommandDisabled(commandLabel)) return true; + + IEssentialsCommand cmd; + try + { + cmd = (IEssentialsCommand)Essentials.class.getClassLoader().loadClass("com.earth2me.essentials.commands.Command" + command.getName()).newInstance(); + } + catch (Exception ex) + { + sender.sendMessage(ChatColor.RED + "That command is improperly loaded."); + ex.printStackTrace(); + return true; + } + + // Check authorization + if (user != null && !user.isAuthorized(cmd)) + { + logger.warning(user.getName() + " was denied access to command."); + user.sendMessage(ChatColor.RED + "You do not have access to that command."); + return true; + } + + // Run the command + try + { + if (user == null) + cmd.run(getServer(), this, sender, commandLabel, command, args); + else + cmd.run(getServer(), this, user, commandLabel, command, args); + return true; + } + catch (Throwable ex) + { + sender.sendMessage(ChatColor.RED + "Error: " + ex.getMessage()); + return true; + } + } + catch (Throwable ex) + { + ex.printStackTrace(); + return true; + } + } + + public void loadBanList() + { + //I don't like this but it needs to be done until CB fixors + File file = new File("banned-players.txt"); + File ipFile = new File("banned-ips.txt"); + try + { + if (!file.exists()) throw new FileNotFoundException("banned-players.txt not found"); + + BufferedReader rx = new BufferedReader(new FileReader(file)); + bans.clear(); + try + { + for (int i = 0; rx.ready(); i++) + { + + String line = rx.readLine().trim().toLowerCase(); + if (line.startsWith("#")) continue; + bans.add(line); + + } + } + catch (IOException io) + { + logger.log(Level.SEVERE, "Error reading banned-players.txt", io); + } + } + catch (FileNotFoundException ex) + { + logger.log(Level.SEVERE, "Error reading banned-players.txt", ex); + } + + try + { + if (!ipFile.exists()) throw new FileNotFoundException("banned-ips.txt not found"); + + BufferedReader rx = new BufferedReader(new FileReader(ipFile)); + bannedIps.clear(); + try + { + for (int i = 0; rx.ready(); i++) + { + + String line = rx.readLine().trim().toLowerCase(); + if (line.startsWith("#")) continue; + bannedIps.add(line); + + } + } + catch (IOException io) + { + logger.log(Level.SEVERE, "Error reading banned-ips.txt", io); + } + } + catch (FileNotFoundException ex) + { + logger.log(Level.SEVERE, "Error reading banned-ips.txt", ex); + } + } + + private void attachEcoListeners() + { + PluginManager pm = getServer().getPluginManager(); + EssentialsEcoBlockListener blockListener = new EssentialsEcoBlockListener(); + pm.registerEvent(Type.BLOCK_BREAK, blockListener, Priority.High, this); + pm.registerEvent(Type.SIGN_CHANGE, blockListener, Priority.Monitor, this); + } + + public CraftScheduler getScheduler() + { + return (CraftScheduler)this.getServer().getScheduler(); + } + + public static Jail getJail() + { + return getStatic().jail; + } + + public static Warps getWarps() + { + return getStatic().warps; + } +} diff --git a/Essentials/src/com/earth2me/essentials/EssentialsBlockListener.java b/Essentials/src/com/earth2me/essentials/EssentialsBlockListener.java new file mode 100644 index 000000000..a52a6c225 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/EssentialsBlockListener.java @@ -0,0 +1,214 @@ +package com.earth2me.essentials; + +import java.util.ArrayList; +import org.bukkit.*; +import org.bukkit.block.*; +import org.bukkit.craftbukkit.block.CraftSign; +import org.bukkit.event.block.*; + + +public class EssentialsBlockListener extends BlockListener +{ + private final Essentials parent; + public final static ArrayList protectedBlocks = new ArrayList(4); + + static + { + protectedBlocks.add(Material.CHEST); + protectedBlocks.add(Material.BURNING_FURNACE); + protectedBlocks.add(Material.FURNACE); + protectedBlocks.add(Material.DISPENSER); + } + + public EssentialsBlockListener(Essentials parent) + { + this.parent = parent; + } + + @Override + public void onBlockBreak(BlockBreakEvent event) + { + if (event.isCancelled()) return; + if (Essentials.getSettings().areSignsDisabled()) return; + User user = User.get(event.getPlayer()); + if (protectedBlocks.contains(event.getBlock().getType()) && !user.isAuthorized("essentials.signs.protection.override")) + { + if (isBlockProtected(event.getBlock(), user)) + { + event.setCancelled(true); + user.sendMessage("§cYou do not have permission to destroy that chest."); + return; + } + } + + if (checkProtectionSign(event.getBlock(), user) == NOT_ALLOWED) + { + event.setCancelled(true); + user.sendMessage("§cYou do not have permission to destroy that sign."); + } + } + + @Override + public void onSignChange(SignChangeEvent event) + { + if (event.isCancelled()) return; + if (Essentials.getSettings().areSignsDisabled()) return; + User user = User.get(event.getPlayer()); + + try + { + if (event.getLine(0).equalsIgnoreCase("[Protection]")) + { + Block block = event.getBlock(); + if (user.isAuthorized("essentials.signs.protection.create") && hasAdjacentChest(block) && !isBlockProtected(block, user)) + event.setLine(0, "§1[Protection]"); + else + event.setLine(0, "§4[Protection]"); + event.setLine(3, user.getName()); + return; + } + if (event.getLine(0).equalsIgnoreCase("[Disposal]")) + { + if (user.isAuthorized("essentials.signs.disposal.create")) + event.setLine(0, "§1[Disposal]"); + else + event.setLine(0, "§4[Disposal]"); + return; + } + if (event.getLine(0).equalsIgnoreCase("[Heal]")) + { + if (user.isAuthorized("essentials.signs.heal.create")) + event.setLine(0, "§1[Heal]"); + else + event.setLine(0, "§4[Heal]"); + return; + } + if (event.getLine(0).equalsIgnoreCase("[Free]")) + { + event.setLine(0, "§4[Free]"); + ItemDb.get(event.getLine(1)); + if (user.isAuthorized("essentials.signs.free.create")) + event.setLine(0, "§1[Free]"); + return; + } + if (event.getLine(0).equalsIgnoreCase("[Mail]")) + { + if (user.isAuthorized("essentials.signs.mail.create")) + + event.setLine(0, "§1[Mail]"); + else + event.setLine(0, "§4[Mail]"); + return; + } + } + catch (Throwable ex) + { + user.sendMessage("§cError: " + ex.getMessage()); + } + } + + @Override + public void onBlockPlace(BlockPlaceEvent event) { + Block signBlock = event.getBlockAgainst(); + if (signBlock.getType() == Material.WALL_SIGN || signBlock.getType() == Material.SIGN_POST) { + Sign sign = new CraftSign(signBlock); + if (sign.getLine(0).matches("§1\\[[a-zA-Z]+\\]")) { + event.setCancelled(true); + return; + } + } + } + + + + public boolean hasAdjacentChest(Block block) + { + Block[] faces = getAdjacentBlocks(block); + for (Block b : faces) + { + if (protectedBlocks.contains(b.getType())) + { + return true; + } + } + return false; + } + private static final int NOT_ALLOWED = 0; + private static final int ALLOWED = 1; + private static final int NOSIGN = 2; + + private static int checkProtectionSign(Block block, User user) + { + if (block.getType() == Material.SIGN_POST || block.getType() == Material.WALL_SIGN) + { + Sign sign = new CraftSign(block); + if (sign.getLine(0).equalsIgnoreCase("§1[Protection]") && !user.isAuthorized("essentials.signs.protection.override")) + { + if (sign.getLine(1).equalsIgnoreCase(user.getName())) + { + return ALLOWED; + } + if (sign.getLine(2).equalsIgnoreCase(user.getName())) + { + return ALLOWED; + } + if (sign.getLine(3).equalsIgnoreCase(user.getName())) + { + return ALLOWED; + } + return NOT_ALLOWED; + } + } + return NOSIGN; + } + + private static Block[] getAdjacentBlocks(Block block) + { + return new Block[] + { + block.getFace(BlockFace.NORTH), + block.getFace(BlockFace.SOUTH), + block.getFace(BlockFace.EAST), + block.getFace(BlockFace.WEST), + block.getFace(BlockFace.DOWN), + block.getFace(BlockFace.UP) + }; + } + + public static boolean isBlockProtected(Block block, User user) + { + Block[] faces = getAdjacentBlocks(block); + boolean protect = false; + for (Block b : faces) + { + int check = checkProtectionSign(b, user); + if (check == NOT_ALLOWED) + { + protect = true; + } + if (check == ALLOWED) + { + return false; + } + + if (protectedBlocks.contains(b.getType())) + { + Block[] faceChest = getAdjacentBlocks(b); + + for (Block a : faceChest) + { + check = checkProtectionSign(a, user); + if (check == NOT_ALLOWED) + { + protect = true; + } + if (check == ALLOWED) + { + return false; + } + } + } + } + return protect; + } +} diff --git a/Essentials/src/com/earth2me/essentials/EssentialsConf.java b/Essentials/src/com/earth2me/essentials/EssentialsConf.java new file mode 100644 index 000000000..616f39a6c --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/EssentialsConf.java @@ -0,0 +1,120 @@ +package com.earth2me.essentials; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.HashMap; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.bukkit.util.config.Configuration; + + +public class EssentialsConf extends Configuration +{ + private static final Logger logger = Logger.getLogger("Minecraft"); + private File configFile; + private String templateName = null; + private Class resourceClass = EssentialsConf.class; + + public EssentialsConf(File configFile) + { + super(configFile); + this.configFile = configFile; + if (this.root == null) { + this.root = new HashMap(); + } + } + + @Override + public void load() + { + configFile = configFile.getAbsoluteFile(); + if (!configFile.getParentFile().exists()) + { + configFile.getParentFile().mkdirs(); + } + if (!configFile.exists()) + { + if (templateName != null) + { + logger.log(Level.INFO, "Creating config from template: " + configFile.toString()); + createFromTemplate(); + } + else + { + try + { + logger.log(Level.INFO, "Creating empty config: " + configFile.toString()); + configFile.createNewFile(); + } + catch (IOException ex) + { + logger.log(Level.SEVERE, "Failed to create config " + configFile.toString(), ex); + } + } + } + super.load(); + if (this.root == null) { + this.root = new HashMap(); + } + } + + private void createFromTemplate() + { + OutputStream ostr = null; + try + { + InputStream istr = resourceClass.getResourceAsStream(templateName); + if (istr == null) + { + logger.log(Level.SEVERE, "Could not find template " + templateName); + return; + } + ostr = new FileOutputStream(configFile); + byte[] buffer = new byte[1024]; + int length = 0; + length = istr.read(buffer); + while (length > 0) + { + ostr.write(buffer, 0, length); + length = istr.read(buffer); + } + ostr.close(); + istr.close(); + } + catch (IOException ex) + { + logger.log(Level.SEVERE, "Failed to write config " + configFile.toString(), ex); + return; + } + finally + { + try + { + ostr.close(); + } + catch (IOException ex) + { + logger.log(Level.SEVERE, "Failed to close config " + configFile.toString(), ex); + return; + } + } + } + + public void setTemplateName(String templateName) + { + this.templateName = templateName; + } + + public File getFile() + { + return configFile; + } + + public void setTemplateName(String templateName, Class resClass) { + this.templateName = templateName; + this.resourceClass = resClass; + } +} diff --git a/Essentials/src/com/earth2me/essentials/EssentialsEcoBlockListener.java b/Essentials/src/com/earth2me/essentials/EssentialsEcoBlockListener.java new file mode 100644 index 000000000..885985ebc --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/EssentialsEcoBlockListener.java @@ -0,0 +1,159 @@ +package com.earth2me.essentials; + +import org.bukkit.Material; +import org.bukkit.block.Sign; +import org.bukkit.craftbukkit.block.CraftSign; +import org.bukkit.craftbukkit.inventory.CraftInventory; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockListener; +import org.bukkit.event.block.SignChangeEvent; +import org.bukkit.inventory.ItemStack; + + +public class EssentialsEcoBlockListener extends BlockListener +{ + @Override + public void onBlockBreak(BlockBreakEvent event) + { + if (event.isCancelled()) return; + if (Essentials.getSettings().areSignsDisabled()) return; + User user = User.get(event.getPlayer()); + if (event.getBlock().getType() != Material.WALL_SIGN && event.getBlock().getType() != Material.SIGN_POST) + return; + Sign sign = new CraftSign(event.getBlock()); + + if (sign.getLine(0).equals("§1[Trade]")) + { + if (!sign.getLine(3).substring(2).equals(user.getName())) { + if (!user.isOp()) { + event.setCancelled(true); + } + return; + } + try + { + String[] l1 = sign.getLines()[1].split("[ :-]+"); + String[] l2 = sign.getLines()[2].split("[ :-]+"); + boolean m1 = l1[0].matches("\\$[0-9]+"); + boolean m2 = l2[0].matches("\\$[0-9]+"); + int q1 = Integer.parseInt(m1 ? l1[0].substring(1) : l1[0]); + int q2 = Integer.parseInt(m2 ? l2[0].substring(1) : l2[0]); + int r1 = Integer.parseInt(l1[m1 ? 1 : 2]); + int r2 = Integer.parseInt(l2[m2 ? 1 : 2]); + if (q1 < 1 || q2 < 1) throw new Exception("Quantities must be greater than 0."); + + ItemStack i1 = m1 || r1 <= 0 ? null : ItemDb.get(l1[1], r1); + ItemStack i2 = m2 || r2 <= 0 ? null : ItemDb.get(l2[1], r2); + + if (m1) + user.giveMoney(r1); + else if (i1 != null) + user.getWorld().dropItem(user.getLocation(), i1); + + if (m2) + user.giveMoney(r2); + else if (i2 != null) + user.getWorld().dropItem(user.getLocation(), i2); + + sign.setType(Material.AIR); + } + catch (Throwable ex) + { + user.sendMessage("§cError: " + ex.getMessage()); + } + return; + } + } + + @Override + public void onSignChange(SignChangeEvent event) + { + if (Essentials.getSettings().areSignsDisabled()) return; + User user = User.get(event.getPlayer()); + + if (event.getLine(0).equalsIgnoreCase("[Buy]") && user.isAuthorized("essentials.signs.buy.create")) + { + try + { + event.setLine(0, "§1[Buy]"); + event.setLine(1, "" + Math.abs(Integer.parseInt(event.getLine(1)))); + ItemDb.get(event.getLine(2)); + event.setLine(3, "$" + Integer.parseInt(event.getLine(3).replaceAll("[^0-9]", ""))); + } + catch (Throwable ex) + { + user.sendMessage("§cError: " + ex.getMessage()); + event.setLine(0, "§4[Buy]"); + event.setLine(1, "#"); + event.setLine(2, "Item"); + event.setLine(3, "$Price"); + } + return; + } + + if (event.getLine(0).equalsIgnoreCase("[Sell]") && user.isAuthorized("essentials.signs.sell.create")) + { + try + { + event.setLine(0, "§1[Sell]"); + event.setLine(1, "" + Math.abs(Integer.parseInt(event.getLine(1)))); + ItemDb.get(event.getLine(2)); + event.setLine(3, "$" + Integer.parseInt(event.getLine(3).replaceAll("[^0-9]", ""))); + } + catch (Throwable ex) + { + user.sendMessage("§cError: " + ex.getMessage()); + event.setLine(0, "§4[Sell]"); + event.setLine(1, "#"); + event.setLine(2, "Item"); + event.setLine(3, "$Price"); + } + return; + } + + if (event.getLine(0).equalsIgnoreCase("[Trade]") && user.isAuthorized("essentials.signs.trade.create")) + { + try + { + String[] l1 = event.getLines()[1].split("[ :-]+"); + String[] l2 = event.getLines()[2].split("[ :-]+"); + boolean m1 = l1[0].matches("\\$[0-9]+"); + boolean m2 = l2[0].matches("\\$[0-9]+"); + int q1 = Integer.parseInt(m1 ? l1[0].substring(1) : l1[0]); + int q2 = Integer.parseInt(m2 ? l2[0].substring(1) : l2[0]); + int r2 = Integer.parseInt(l2[m2 ? 1 : 2]); + r2 = r2 - r2 % q2; + if (q1 < 1 || q2 < 1 || r2 < 1) throw new Exception("Quantities must be greater than 0."); + if (!m1) ItemDb.get(l1[1]); + + if (m2) + { + if (user.getMoney() < r2) throw new Exception("You do not have sufficient funds."); + user.takeMoney(r2); + user.sendMessage("r2: " + r2 + " q2: " + q2); + } + else + { + ItemStack i2 = ItemDb.get(l2[1], r2); + if (!InventoryWorkaround.containsItem((CraftInventory)user.getInventory(), true, i2)) throw new Exception("You do not have " + r2 + "x " + l2[1] + "."); + InventoryWorkaround.removeItem((CraftInventory)user.getInventory(), true, i2); + user.updateInventory(); + } + + event.setLine(0, "§1[Trade]"); + event.setLine(1, (m1 ? "$" + q1 : q1 + " " + l1[1]) + ":0"); + event.setLine(2, (m2 ? "$" + q2 : q2 + " " + l2[1]) + ":" + r2); + event.setLine(3, "§8" + user.getName()); + } + catch (Throwable ex) + { + user.sendMessage("§cError: " + ex.getMessage()); + event.setLine(0, "§4[Trade]"); + event.setLine(1, "# ItemOr$"); + event.setLine(2, "# ItemOr$:#"); + event.setLine(3, "§8" + user.getName()); + } + return; + } + } +} diff --git a/Essentials/src/com/earth2me/essentials/EssentialsEntityListener.java b/Essentials/src/com/earth2me/essentials/EssentialsEntityListener.java new file mode 100644 index 000000000..15355021a --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/EssentialsEntityListener.java @@ -0,0 +1,65 @@ +package com.earth2me.essentials; + +import org.bukkit.Server; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityCombustEvent; +import org.bukkit.event.entity.EntityDamageByBlockEvent; +import org.bukkit.event.entity.EntityDamageByProjectileEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.entity.EntityListener; + + +public class EssentialsEntityListener extends EntityListener +{ + private final Server server; + private final Essentials parent; + + public EssentialsEntityListener(Essentials parent) + { + this.parent = parent; + this.server = parent.getServer(); + } + + @Override + public void onEntityDamage(EntityDamageEvent event) + { + if (event instanceof EntityDamageEvent || event instanceof EntityDamageByBlockEvent || event instanceof EntityDamageByProjectileEvent) + { + + if (event.getEntity() instanceof Player && User.get(event.getEntity()).isGodModeEnabled()) + { + CraftPlayer player = (CraftPlayer)event.getEntity(); + player.getHandle().fireTicks = 0; + player.setRemainingAir(player.getMaximumAir()); + event.setCancelled(true); + } + } + } + + + @Override + public void onEntityCombust(EntityCombustEvent event) + { + if (event.getEntity() instanceof Player && User.get(event.getEntity()).isGodModeEnabled()) + { + event.setCancelled(true); + } + } + + @Override + public void onEntityDeath(EntityDeathEvent event) + { + if (event.getEntity() instanceof Player) + { + User user = User.get(event.getEntity()); + if(user.isAuthorized("essentials.back.ondeath")) + { + user.lastLocation = user.getLocation(); + user.sendMessage("§7Use the /back command to return to your death point"); + } + } + } + +} diff --git a/Essentials/src/com/earth2me/essentials/EssentialsPlayerListener.java b/Essentials/src/com/earth2me/essentials/EssentialsPlayerListener.java new file mode 100644 index 000000000..58cddcacd --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/EssentialsPlayerListener.java @@ -0,0 +1,452 @@ +package com.earth2me.essentials; + +import java.util.List; +import java.util.logging.Logger; +import net.minecraft.server.InventoryPlayer; +import org.bukkit.*; +import org.bukkit.block.Block; +import org.bukkit.block.Sign; +import org.bukkit.craftbukkit.block.CraftSign; +import org.bukkit.craftbukkit.inventory.CraftInventory; +import org.bukkit.craftbukkit.inventory.CraftInventoryPlayer; +import org.bukkit.event.player.*; +import org.bukkit.event.player.PlayerLoginEvent.Result; +import org.bukkit.inventory.ItemStack; + + +public class EssentialsPlayerListener extends PlayerListener +{ + private static final Logger logger = Logger.getLogger("Minecraft"); + private final Server server; + private final Essentials parent; + + public EssentialsPlayerListener(Essentials parent) + { + this.parent = parent; + this.server = parent.getServer(); + } + + private void onPlayerInteractEco(PlayerInteractEvent event) + { + if (Essentials.getSettings().areSignsDisabled()) return; + User user = User.get(event.getPlayer()); + if (event.getClickedBlock().getType() != Material.WALL_SIGN && event.getClickedBlock().getType() != Material.SIGN_POST) + return; + Sign sign = new CraftSign(event.getClickedBlock()); + + if (sign.getLine(0).equals("§1[Buy]") && user.isAuthorized("essentials.signs.buy.use")) + { + try + { + int amount = Integer.parseInt(sign.getLine(1)); + ItemStack item = ItemDb.get(sign.getLine(2), amount); + int cost = Integer.parseInt(sign.getLine(3).substring(1)); + if (user.getMoney() < cost) throw new Exception("You do not have sufficient funds."); + user.takeMoney(cost); + user.getInventory().addItem(item); + user.updateInventory(); + } + catch (Throwable ex) + { + user.sendMessage("§cError: " + ex.getMessage()); + } + return; + } + + if (sign.getLine(0).equals("§1[Sell]") && user.isAuthorized("essentials.signs.sell.use")) + { + try + { + int amount = Integer.parseInt(sign.getLine(1)); + ItemStack item = ItemDb.get(sign.getLine(2), amount); + int cost = Integer.parseInt(sign.getLine(3).substring(1)); + if (!InventoryWorkaround.containsItem((CraftInventory)user.getInventory(), true, item)) throw new Exception("You do not have enough items to sell."); + user.giveMoney(cost); + InventoryWorkaround.removeItem((CraftInventory)user.getInventory(), true, item); + user.updateInventory(); + } + catch (Throwable ex) + { + user.sendMessage("§cError: " + ex.getMessage()); + } + return; + } + + if (sign.getLine(0).equals("§1[Trade]") && user.isAuthorized("essentials.signs.trade.use")) + { + try + { + String[] l1 = sign.getLines()[1].split("[ :-]+"); + String[] l2 = sign.getLines()[2].split("[ :-]+"); + boolean m1 = l1[0].matches("\\$[0-9]+"); + boolean m2 = l2[0].matches("\\$[0-9]+"); + int q1 = Integer.parseInt(m1 ? l1[0].substring(1) : l1[0]); + int q2 = Integer.parseInt(m2 ? l2[0].substring(1) : l2[0]); + int r1 = Integer.parseInt(l1[m1 ? 1 : 2]); + int r2 = Integer.parseInt(l2[m2 ? 1 : 2]); + r1 = r1 - r1 % q1; + r2 = r2 - r2 % q2; + if (q1 < 1 || q2 < 1) throw new Exception("Quantities must be greater than 0."); + + ItemStack i1 = m1 || r1 <= 0 ? null : ItemDb.get(l1[1], r1); + ItemStack qi1 = m1 ? null : ItemDb.get(l1[1], q1); + ItemStack qi2 = m2 ? null : ItemDb.get(l2[1], q2); + + if (user.getName().equals(sign.getLines()[3].substring(2))) + { + if (m1) + { + user.giveMoney(r1); + } + else if (i1 != null) + { + user.getInventory().addItem(i1); + user.updateInventory(); + } + r1 = 0; + sign.setLine(1, (m1 ? "$" + q1 : q1 + " " + l1[1]) + ":" + r1); + } + else + { + if (m1) + { + if (user.getMoney() < q1) + throw new Exception("You do not have sufficient funds."); + } + else + { + if (!InventoryWorkaround.containsItem((CraftInventory)user.getInventory(), true, qi1)) + throw new Exception("You do not have " + q1 + "x " + l1[1] + "."); + } + + if (r2 < q2) throw new Exception("The trade sign does not have enough supply left."); + + if (m1) + user.takeMoney(q1); + else + InventoryWorkaround.removeItem((CraftInventory)user.getInventory(), true, qi1); + + if (m2) + user.giveMoney(q2); + else + user.getInventory().addItem(qi2); + + user.updateInventory(); + + r1 += q1; + r2 -= q2; + + sign.setLine(0, "§1[Trade]"); + sign.setLine(1, (m1 ? "$" + q1 : q1 + " " + l1[1]) + ":" + r1); + sign.setLine(2, (m2 ? "$" + q2 : q2 + " " + l2[1]) + ":" + r2); + + user.sendMessage("§7Trade completed."); + } + } + catch (Throwable ex) + { + user.sendMessage("§cError: " + ex.getMessage()); + } + return; + } + } + + @Override + public void onPlayerInteract(PlayerInteractEvent event) + { + if (event.isCancelled()) return; + User user = User.get(event.getPlayer()); + if (user.isJailed()) + { + event.setCancelled(true); + return; + } + + onPlayerInteractEco(event); + onPlayerInteractSigns(event); + + if (!Essentials.getSettings().areSignsDisabled() && EssentialsBlockListener.protectedBlocks.contains(event.getClickedBlock().getType())) + { + if (!user.isAuthorized("essentials.signs.protection.override")) + { + if (EssentialsBlockListener.isBlockProtected(event.getClickedBlock(), user)) + { + event.setCancelled(true); + user.sendMessage("§cYou do not have permission to access that chest."); + return; + } + } + } + + if (Essentials.getSettings().getBedSetsHome() && event.getClickedBlock().getType() == Material.BED_BLOCK) + { + try + { + user.setHome(); + user.sendMessage("§7Your home is now set to this bed."); + } + catch (Throwable ex) + { + } + } + } + + private void onPlayerInteractSigns(PlayerInteractEvent event) + { + User user = User.get(event.getPlayer()); + if (user.isJailed()) return; + if (Essentials.getSettings().areSignsDisabled()) return; + if (event.getClickedBlock().getType() != Material.WALL_SIGN && event.getClickedBlock().getType() != Material.SIGN_POST) + return; + Sign sign = new CraftSign(event.getClickedBlock()); + + try + { + if (sign.getLine(0).equals("§1[Free]") && user.isAuthorized("essentials.signs.free.use")) + { + ItemStack item = ItemDb.get(sign.getLine(1)); + CraftInventoryPlayer inv = new CraftInventoryPlayer(new InventoryPlayer(user.getHandle())); + inv.clear(); + item.setAmount(9 * 4 * 64); + inv.addItem(item); + user.showInventory(inv); + return; + } + if (sign.getLine(0).equals("§1[Disposal]") && user.isAuthorized("essentials.signs.disposal.use")) + { + CraftInventoryPlayer inv = new CraftInventoryPlayer(new InventoryPlayer(user.getHandle())); + inv.clear(); + user.showInventory(inv); + return; + } + if (sign.getLine(0).equals("§1[Heal]") && user.isAuthorized("essentials.signs.heal.use")) + { + user.setHealth(20); + user.sendMessage("§7You have been healed."); + return; + } + if (sign.getLine(0).equals("§1[Mail]") && user.isAuthorized("essentials.signs.mail.use") && user.isAuthorized("essentials.mail")) + { + List mail = Essentials.readMail(user); + if (mail.isEmpty()) + { + user.sendMessage("§cYou do not have any mail!"); + return; + } + for (String s : mail) user.sendMessage(s); + user.sendMessage("§cTo mark your mail as read, type §c/mail clear"); + return; + } + } + catch (Throwable ex) + { + user.sendMessage("§cError: " + ex.getMessage()); + } + } + + @Override + public void onPlayerRespawn(PlayerRespawnEvent event) + { + User user = User.get(event.getPlayer()); + user.setDisplayName(user.getNick()); + updateCompass(user); + } + + @Override + public void onPlayerChat(PlayerChatEvent event) + { + User user = User.get(event.getPlayer()); + if (user.isMuted()) + { + event.setCancelled(true); + logger.info(user.getName() + " tried to speak, but is muted."); + } + } + + @Override + public void onPlayerMove(PlayerMoveEvent event) + { + if (event.isCancelled()) return; + final User user = User.get(event.getPlayer()); + + if (!Essentials.getSettings().getNetherPortalsEnabled()) return; + + final Block block = event.getPlayer().getWorld().getBlockAt(event.getTo().getBlockX(), event.getTo().getBlockY(), event.getTo().getBlockZ()); + List worlds = server.getWorlds(); + + if (block.getType() == Material.PORTAL && worlds.size() > 1 && user.isAuthorized("essentials.portal")) + { + if (user.getJustPortaled()) return; + + Location loc = event.getTo(); + final World world = worlds.get(user.getWorld() == worlds.get(0) ? 1 : 0); + + double factor; + if (user.getWorld().getEnvironment() == World.Environment.NETHER && world.getEnvironment() == World.Environment.NORMAL) + factor = 16.0; + else if (user.getWorld().getEnvironment() != world.getEnvironment()) + factor = 1.0 / 16.0; + else + factor = 1.0; + + int x = loc.getBlockX(); + int y = loc.getBlockY(); + int z = loc.getBlockZ(); + + if (user.getWorld().getBlockAt(x, y, z - 1).getType() == Material.PORTAL) + z--; + if (user.getWorld().getBlockAt(x - 1, y, z).getType() == Material.PORTAL) + x--; + + x = (int)(x * factor); + z = (int)(z * factor); + loc = new Location(world, x + .5, y, z + .5); + + Block dest = world.getBlockAt(x, y, z); + NetherPortal portal = NetherPortal.findPortal(dest); + if (portal == null) + { + if (world.getEnvironment() == World.Environment.NETHER || Essentials.getSettings().getGenerateExitPortals()) + { + portal = NetherPortal.createPortal(dest); + logger.info(event.getPlayer().getName() + " used a portal and generated an exit portal."); + user.sendMessage("§7Generating an exit portal."); + loc = portal.getSpawn(); + } + } + else + { + logger.info(event.getPlayer().getName() + " used a portal and used an existing exit portal."); + user.sendMessage("§7Teleporting via portal to an existing portal."); + loc = portal.getSpawn(); + } + + event.setFrom(loc); + event.setTo(loc); + try + { + user.teleportToNow(loc); + } + catch (Exception ex) + { + user.sendMessage(ex.getMessage()); + } + user.setJustPortaled(true); + user.sendMessage("§7Teleporting via portal."); + + event.setCancelled(true); + return; + } + + user.setJustPortaled(false); + } + + @Override + public void onPlayerQuit(PlayerQuitEvent event) + { + if (!Essentials.getSettings().getReclaimSetting()) + return; + + User.get(event.getPlayer()).dispose(); + Thread thread = new Thread(new Runnable() + { + @SuppressWarnings("LoggerStringConcat") + public void run() + { + try + { + Thread.sleep(1000); + Runtime rt = Runtime.getRuntime(); + double mem = rt.freeMemory(); + rt.runFinalization(); + rt.gc(); + mem = rt.freeMemory() - mem; + mem /= 1024 * 1024; + logger.info("Freed " + mem + " MB."); + } + catch (InterruptedException ex) + { + return; + } + } + }); + thread.setPriority(Thread.MIN_PRIORITY); + thread.start(); + } + + @Override + public void onPlayerJoin(PlayerJoinEvent event) + { + Essentials.getStatic().backup.onPlayerJoin(); + User user = User.get(event.getPlayer()); + + //we do not know the ip address on playerlogin so we need to do this here. + if (user.isIpBanned()) + { + user.kickPlayer("The Ban Hammer has spoken!"); + return; + } + + user.setDisplayName(user.getNick()); + + if (!Essentials.getSettings().isCommandDisabled("motd") && user.isAuthorized("essentials.motd")) + { + for (String m : parent.getMotd(user, null)) + { + if (m == null) continue; + user.sendMessage(m); + } + } + + if (!Essentials.getSettings().isCommandDisabled("mail")) + { + List mail = Essentials.readMail(user); + if (mail.isEmpty()) user.sendMessage("§7You have no new mail."); + else user.sendMessage("§cYou have " + mail.size() + " messages!§f Type §7/mail read§f to view your mail."); + } + } + + @Override + public void onPlayerLogin(PlayerLoginEvent event) + { + User user = User.get(event.getPlayer()); + if (event.getResult() != Result.ALLOWED) + return; + + if (user.isBanned()) + { + event.disallow(Result.KICK_BANNED, "The Ban Hammer has spoken!"); + return; + } + + if (server.getOnlinePlayers().length >= server.getMaxPlayers() && !user.isOp()) + { + event.disallow(Result.KICK_FULL, "Server is full"); + return; + } + + updateCompass(user); + } + + private void updateCompass(User user) + { + try + { + if (server.getPluginManager().isPluginEnabled("EssentialsHome")) + user.setCompassTarget(user.getHome()); + } + catch (Throwable ex) + { + } + } + + @Override + public void onPlayerTeleport(PlayerTeleportEvent event) + { + User user = User.get(event.getPlayer()); + if (user.currentJail == null || user.currentJail.isEmpty()) + return; + event.setCancelled(true); + user.sendMessage(ChatColor.RED + "You do the crime, you do the time."); + } +} diff --git a/Essentials/src/com/earth2me/essentials/IConf.java b/Essentials/src/com/earth2me/essentials/IConf.java new file mode 100644 index 000000000..a523f8638 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/IConf.java @@ -0,0 +1,5 @@ +package com.earth2me.essentials; + +public interface IConf { + public void reloadConfig(); +} diff --git a/Essentials/src/com/earth2me/essentials/InventoryWorkaround.java b/Essentials/src/com/earth2me/essentials/InventoryWorkaround.java new file mode 100644 index 000000000..aabd7b02b --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/InventoryWorkaround.java @@ -0,0 +1,136 @@ +package com.earth2me.essentials; + +import java.util.HashMap; +import org.bukkit.craftbukkit.inventory.CraftInventory; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.inventory.ItemStack; + +/* + * This class can be removed when + * https://github.com/Bukkit/CraftBukkit/pull/193 + * is accepted to CraftBukkit + */ +public class InventoryWorkaround { + + public static int first(CraftInventory ci, ItemStack item, boolean forceDurability, boolean forceAmount) { + return next(ci, item, 0, forceDurability, forceAmount); + } + + public static int next(CraftInventory ci, ItemStack item, int start, boolean forceDurability, boolean forceAmount) { + CraftItemStack[] inventory = ci.getContents(); + for (int i = start; i < inventory.length; i++) { + CraftItemStack cItem = inventory[i]; + if (item.getTypeId() == cItem.getTypeId() && (!forceAmount || item.getAmount() == cItem.getAmount()) && (!forceDurability || cItem.getDurability() == item.getDurability())) { + return i; + } + } + return -1; + } + + public static HashMap removeItem(CraftInventory ci, boolean forceDurability, ItemStack... items) { + HashMap leftover = new HashMap(); + + // TODO: optimization + + for (int i = 0; i < items.length; i++) { + ItemStack item = items[i]; + if (item == null) { + continue; + } + int toDelete = item.getAmount(); + + while (true) { + + // Bail when done + if (toDelete <= 0) { + break; + } + + // get first Item, ignore the amount + int first = first(ci, item, forceDurability, false); + + // Drat! we don't have this type in the inventory + if (first == -1) { + item.setAmount(toDelete); + leftover.put(i, item); + break; + } else { + CraftItemStack itemStack = ci.getItem(first); + int amount = itemStack.getAmount(); + + if (amount <= toDelete) { + toDelete -= amount; + // clear the slot, all used up + ci.clear(first); + } else { + // split the stack and store + itemStack.setAmount(amount - toDelete); + ci.setItem(first, itemStack); + toDelete = 0; + } + } + } + } + return leftover; + } + + public static boolean containsItem(CraftInventory ci, boolean forceDurability, ItemStack... items) { + HashMap leftover = new HashMap(); + + // TODO: optimization + + // combine items + + ItemStack[] combined = new ItemStack[items.length]; + for (int i = 0; i < items.length; i++) { + if (items[i] == null) { + continue; + } + for (int j = 0; j < combined.length; j++) { + if (combined[j] == null) { + combined[j] = new ItemStack(items[i].getType(), items[i].getAmount(), items[i].getDurability()); + break; + } + if (combined[j].getTypeId() == items[i].getTypeId() && (!forceDurability || combined[j].getDurability() == items[i].getDurability())) { + combined[j].setAmount(combined[j].getAmount() + items[i].getAmount()); + break; + } + } + } + + for (int i = 0; i < combined.length; i++) { + ItemStack item = combined[i]; + if (item == null) { + continue; + } + int mustHave = item.getAmount(); + int position = 0; + + while (true) { + // Bail when done + if (mustHave <= 0) { + break; + } + + int slot = next(ci, item, position, forceDurability, false); + + // Drat! we don't have this type in the inventory + if (slot == -1) { + leftover.put(i, item); + break; + } else { + CraftItemStack itemStack = ci.getItem(slot); + int amount = itemStack.getAmount(); + + if (amount <= mustHave) { + mustHave -= amount; + } else { + mustHave = 0; + } + position = slot + 1; + } + } + } + return leftover.isEmpty(); + } +} diff --git a/Essentials/src/com/earth2me/essentials/ItemDb.java b/Essentials/src/com/earth2me/essentials/ItemDb.java new file mode 100644 index 000000000..8c3c47bab --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/ItemDb.java @@ -0,0 +1,110 @@ +package com.earth2me.essentials; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.util.*; +import java.util.logging.Logger; +import org.bukkit.inventory.ItemStack; + + +public class ItemDb +{ + private final static Logger logger = Logger.getLogger("Minecraft"); + private static Map items = new HashMap(); + private static Map durabilities = new HashMap(); + + @SuppressWarnings("LoggerStringConcat") + public static void load(File folder, String fname) throws IOException + { + folder.mkdirs(); + File file = new File(folder, fname); + + if (!file.exists()) + { + file.createNewFile(); + InputStream res = ItemDb.class.getResourceAsStream("/items.csv"); + FileWriter tx = new FileWriter(file); + try + { + for (int i = 0; (i = res.read()) > 0;) tx.write(i); + } + finally + { + try + { + tx.flush(); + tx.close(); + res.close(); + } + catch (Exception ex) + { + } + } + } + + BufferedReader rx = new BufferedReader(new FileReader(file)); + try + { + items.clear(); + + for (int i = 0; rx.ready(); i++) + { + try + { + String line = rx.readLine().trim().toLowerCase(); + if (line.startsWith("#")) + continue; + + String[] parts = line.split("[^a-z0-9]"); + if (parts.length < 2) + continue; + + int numeric = Integer.parseInt(parts[1]); + + durabilities.put(parts[0], parts.length > 2 && !parts[2].equals("0") ? Short.parseShort(parts[2]) : 0); + items.put(parts[0], numeric); + } + catch (Exception ex) + { + logger.warning("Error parsing " + fname + " on line " + i); + } + } + } + finally + { + rx.close(); + } + } + + public static ItemStack get(String id, int quantity) throws Exception { + ItemStack retval = get(id); + retval.setAmount(quantity); + return retval; + } + + public static ItemStack get(String id) throws Exception + { + ItemStack retval = new ItemStack(getUnsafe(id)); + retval.setAmount(Essentials.getSettings().getDefaultStackSize()); + retval.setDurability(durabilities.containsKey(id) ? durabilities.get(id) : 0); + if (items.containsValue(retval.getTypeId()) || true) return retval; + throw new Exception("Unknown item numeric: " + retval); + } + + private static int getUnsafe(String id) throws Exception + { + try + { + return Integer.parseInt(id); + } + catch (NumberFormatException ex) + { + if (items.containsKey(id)) return items.get(id); + throw new Exception("Unknown item name: " + id); + } + } +} diff --git a/Essentials/src/com/earth2me/essentials/Jail.java b/Essentials/src/com/earth2me/essentials/Jail.java new file mode 100644 index 000000000..5e0dd87ee --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/Jail.java @@ -0,0 +1,117 @@ +package com.earth2me.essentials; + +import java.io.File; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Logger; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockDamageEvent; +import org.bukkit.event.block.BlockListener; +import org.bukkit.event.block.BlockPlaceEvent; + + +public class Jail extends BlockListener implements IConf +{ + private static final Logger logger = Logger.getLogger("Minecraft"); + private EssentialsConf config; + + public Jail(File dataFolder) + { + config = new EssentialsConf(new File(dataFolder, "jail.yml")); + config.load(); + } + + public void setJail(Location loc, String jailName) throws Exception + { + Map map = new HashMap(); + map.put("world", loc.getWorld().getName()); + map.put("x", loc.getX()); + map.put("y", loc.getY()); + map.put("z", loc.getZ()); + map.put("yaw", loc.getYaw()); + map.put("pitch", loc.getPitch()); + config.setProperty(jailName.toLowerCase(), map); + config.save(); + } + + public Location getJail(String jailName) throws Exception + { + if (config.getProperty(jailName.toLowerCase()) == null) + { + throw new Exception("That jail does not exist"); + } + + World jWorld = null; + String world = config.getString(jailName + ".world", ""); // wh.spawnX + double x = config.getDouble(jailName + ".x", 0); // wh.spawnX + double y = config.getDouble(jailName + ".y", 0); // wh.spawnY + double z = config.getDouble(jailName + ".z", 0); // wh.spawnZ + float yaw = (float)config.getDouble(jailName + ".yaw", 0); + float pitch = (float)config.getDouble(jailName + ".pitch", 0); + for (World w : Essentials.getStatic().getServer().getWorlds()) + { + if (w.getName().equalsIgnoreCase(world)) + { + jWorld = w; + break; + } + + } + return new Location(jWorld, x, y, z, yaw, pitch); + } + + public void sendToJail(User user, String jail) throws Exception + { + user.teleport(getJail(jail)); + user.currentJail = jail; + } + + public void delJail(String jail) throws Exception + { + config.removeProperty(jail.toLowerCase()); + config.save(); + } + + public List getJails() throws Exception + { + return config.getKeys(null); + } + + public void reloadConfig() + { + config.load(); + } + + @Override + public void onBlockBreak(BlockBreakEvent event) + { + User user = User.get(event.getPlayer()); + if (user.isJailed()) + { + event.setCancelled(true); + } + } + + @Override + public void onBlockPlace(BlockPlaceEvent event) + { + User user = User.get(event.getPlayer()); + if (user.isJailed()) + { + event.setCancelled(true); + } + } + + @Override + public void onBlockDamage(BlockDamageEvent event) + { + User user = User.get(event.getPlayer()); + if (user.isJailed()) + { + event.setCancelled(true); + } + } +} diff --git a/Essentials/src/com/earth2me/essentials/Mob.java b/Essentials/src/com/earth2me/essentials/Mob.java new file mode 100644 index 000000000..3c0d9bd1e --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/Mob.java @@ -0,0 +1,122 @@ +package com.earth2me.essentials; + +import java.lang.reflect.Constructor; +import java.util.HashMap; +import java.util.logging.Logger; +import net.minecraft.server.Entity; +import net.minecraft.server.WorldServer; +import org.bukkit.Server; +import org.bukkit.craftbukkit.entity.CraftEntity; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.Player; + + +public enum Mob +{ + CHICKEN("Chicken", Enemies.FRIENDLY), + COW("Cow", Enemies.FRIENDLY), + CREEPER("Creeper", Enemies.ENEMY), + GHAST("Ghast", Enemies.ENEMY), + GIANT("Giant", "GiantZombie", Enemies.ENEMY), + PIG("Pig", Enemies.FRIENDLY), + PIGZOMB("PigZombie", Enemies.NEUTRAL), + SHEEP("Sheep", Enemies.FRIENDLY, ""), + SKELETON("Skeleton", Enemies.ENEMY), + SLIME("Slime", Enemies.ENEMY), + SPIDER("Spider", Enemies.ENEMY), + SQUID("Squid", Enemies.FRIENDLY), + ZOMBIE("Zombie", Enemies.ENEMY), + MONSTER("Monster", Enemies.ENEMY); + + public static final Logger logger = Logger.getLogger("Minecraft"); + + private Mob(String n, Enemies en, String s) + { + this.s = s; + this.name = n; + this.craftClass = n; + this.entityClass = n; + this.type = en; + } + + private Mob(String n, Enemies en) + { + this.name = n; + this.craftClass = n; + this.entityClass = n; + this.type = en; + } + + private Mob(String n, String ec, Enemies en) + { + this.name = n; + this.craftClass = n; + this.entityClass = ec; + this.type = en; + } + + private Mob(String n, String ec, String cc, Enemies en) + { + this.name = n; + this.entityClass = ec; + this.craftClass = cc; + this.type = en; + } + public String s = "s"; + public String name; + public Enemies type; + private String entityClass; + private String craftClass; + private static final HashMap hashMap = new HashMap(); + + static + { + for (Mob mob : Mob.values()) + { + hashMap.put(mob.name, mob); + } + } + + @SuppressWarnings({"unchecked", "CallToThreadDumpStack"}) + public CraftEntity spawn(Player player, Server server) throws MobException + { + try + { + WorldServer world = ((org.bukkit.craftbukkit.CraftWorld)player.getWorld()).getHandle(); + Constructor craft = (Constructor)ClassLoader.getSystemClassLoader().loadClass("org.bukkit.craftbukkit.entity.Craft" + craftClass).getConstructors()[0]; + Constructor entity = (Constructor)ClassLoader.getSystemClassLoader().loadClass("net.minecraft.server.Entity" + entityClass).getConstructors()[0]; + return craft.newInstance((CraftServer)server, entity.newInstance(world)); + } + catch (Exception ex) + { + logger.warning("Unable to spawn mob."); + ex.printStackTrace(); + throw new MobException(); + } + } + + + public enum Enemies + { + FRIENDLY("friendly"), + NEUTRAL("neutral"), + ENEMY("enemy"); + + private Enemies(String t) + { + this.type = t; + } + protected String type; + } + + + public class MobException extends Exception + { + private static final long serialVersionUID = 1L; + } + + public static Mob fromName(String n) + { + return hashMap.get(n); + } +} diff --git a/Essentials/src/com/earth2me/essentials/NetherPortal.java b/Essentials/src/com/earth2me/essentials/NetherPortal.java new file mode 100644 index 000000000..25ebe5e23 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/NetherPortal.java @@ -0,0 +1,167 @@ +/** + * @author SpaceManiac + * @licent MIT + * @origin https://github.com/SpaceManiac/Nether/blob/master/org/innectis/Nether/NetherPortal.java + */ +package com.earth2me.essentials; + +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.Location; +import org.bukkit.Material; +import java.util.ArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; + + +public class NetherPortal +{ + private Block block; + + public NetherPortal(Block b) + { + block = b; + } + + public Block getBlock() + { + return block; + } + + public void setBlock(Block b) + { + block = b; + } + + // Return a random spawnable location + public Location getSpawn() + { + if (block.getWorld().getBlockAt(block.getX() + 1, block.getY(), block.getZ()).getType().equals(Material.PORTAL) + || block.getWorld().getBlockAt(block.getX() - 1, block.getY(), block.getZ()).getType().equals(Material.PORTAL)) + { + // portal is in X direction + return new Location(block.getWorld(), block.getX() + 1, + block.getY(), block.getZ() + 1.5 - 2 * Math.round(Math.random())); + } + else + { + // portal is in Z direction + return new Location(block.getWorld(), block.getX() + 1.5 - 2 * Math.round(Math.random()), + block.getY(), block.getZ() + 1); + } + } + + // ============================== + // Find a nearby portal within 16 blocks of the given block + // Not guaranteed to be the nearest + public static NetherPortal findPortal(Block dest) + { + World world = dest.getWorld(); + + // Get list of columns in a circle around the block + ArrayList columns = new ArrayList(); + for (int x = dest.getX() - 16; x <= dest.getX() + 16; ++x) + { + for (int z = dest.getZ() - 16; z <= dest.getZ() + 16; ++z) + { + int dx = dest.getX() - x, dz = dest.getZ() - z; + if (dx * dx + dz * dz <= 256) + { + columns.add(world.getBlockAt(x, 0, z)); + } + } + } + + // For each column try to find a portal block + for (Block col : columns) + { + for (int y = 127; y >= 0; --y) + { + Block b = world.getBlockAt(col.getX(), y, col.getZ()); + if (b.getType().equals(Material.PORTAL) && Math.abs(dest.getY() - y) <= 16) + { + // Huzzah! + return new NetherPortal(b); + } + } + } + + // Nope! + return null; + } + + // Create a new portal at the specified block, fudging position if needed + // Will occasionally end up making portals in bad places, but let's hope not + public static NetherPortal createPortal(Block dest) + { + World world = dest.getWorld(); + + // Try not to spawn within water or lava + Material m = dest.getType(); + while (((m.equals(Material.LAVA) || m.equals(Material.WATER) || m.equals(Material.STATIONARY_LAVA) + || m.equals(Material.STATIONARY_WATER) || m.equals(Material.SAND) || m.equals(Material.GRAVEL))) && + dest.getY() < 120) + { + dest = world.getBlockAt(dest.getX(), dest.getY() + 4, dest.getZ()); + m = dest.getType(); + } + + // Not too high or too low overall + if (dest.getY() > 120) + { + dest = world.getBlockAt(dest.getX(), 120, dest.getZ()); + } + else if (dest.getY() < 8) + { + dest = world.getBlockAt(dest.getX(), 8, dest.getZ()); + } + + // Create the physical portal + // For now, don't worry about direction + + int x = dest.getX(), y = dest.getY(), z = dest.getZ(); + Logger.getLogger("Minecraft").log(Level.INFO, "Creating portal at "+x+","+y+","+z+"."); + + // Clear area around portal + ArrayList columns = new ArrayList(); + for (int x2 = x - 4; x2 <= x + 4; ++x2) + { + for (int z2 = z - 4; z2 <= z + 4; ++z2) + { + double dx = x + 0.5f - x2, dz = z - z2; + if (dx * dx + dz * dz <= 13) + { + columns.add(world.getBlockAt(x2, 0, z2)); + } + } + } + + // Clear area around portal + for (Block col : columns) + { + // Stone platform + world.getBlockAt(col.getX(), y - 1, col.getZ()).setType(Material.STONE); + for (int yd = 0; yd < 4; ++yd) + { + world.getBlockAt(col.getX(), y + yd, col.getZ()).setType(Material.AIR); + } + } + + // Build obsidian frame + for (int xd = -1; xd < 3; ++xd) + { + for (int yd = -1; yd < 4; ++yd) + { + if (xd == -1 || yd == -1 || xd == 2 || yd == 3) + { + world.getBlockAt(x + xd, y + yd, z).setType(Material.OBSIDIAN); + } + } + } + + // Set it alight! + dest.setType(Material.FIRE); + + return new NetherPortal(dest); + } +} diff --git a/Essentials/src/com/earth2me/essentials/OfflinePlayer.java b/Essentials/src/com/earth2me/essentials/OfflinePlayer.java new file mode 100644 index 000000000..5fffdfa99 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/OfflinePlayer.java @@ -0,0 +1,351 @@ +package com.earth2me.essentials; + +import java.net.InetSocketAddress; +import java.util.HashSet; +import java.util.List; +import org.bukkit.Location; +import org.bukkit.Server; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.Egg; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Snowball; +import org.bukkit.entity.Vehicle; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; +import org.bukkit.util.Vector; + + +public class OfflinePlayer implements Player +{ + private final String name; + private Location location = new Location(null, 0, 0, 0, 0, 0); + + public OfflinePlayer(String name) + { + this.name = name; + } + + public boolean isOnline() + { + return false; + } + + public boolean isOp() + { + return false; + } + + public void sendMessage(String string) + { + } + + public String getDisplayName() + { + return name; + } + + public void setDisplayName(String string) + { + } + + public void setCompassTarget(Location lctn) + { + } + + public InetSocketAddress getAddress() + { + return null; + } + + public void kickPlayer(String string) + { + } + + public String getName() + { + return name; + } + + public PlayerInventory getInventory() + { + return null; + } + + public ItemStack getItemInHand() + { + return null; + } + + public void setItemInHand(ItemStack is) + { + } + + public int getHealth() + { + return 0; + } + + public void setHealth(int i) + { + } + + public Egg throwEgg() + { + return null; + } + + public Snowball throwSnowball() + { + return null; + } + + public Arrow shootArrow() + { + return null; + } + + public boolean isInsideVehicle() + { + return false; + } + + public boolean leaveVehicle() + { + return false; + } + + public Vehicle getVehicle() + { + return null; + } + + public Location getLocation() + { + return location; + } + + public World getWorld() + { + return null; + } + + public void teleportTo(Location lctn) + { + } + + public void teleportTo(Entity entity) + { + } + + public int getEntityId() + { + return -1; + } + + public boolean performCommand(String string) + { + return false; + } + + public boolean isPlayer() + { + return false; + } + + public int getRemainingAir() + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void setRemainingAir(int i) + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public int getMaximumAir() + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void setMaximumAir(int i) + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public boolean isSneaking() + { + return false; + } + + public void setSneaking(boolean bln) + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void updateInventory() + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void chat(String string) + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public double getEyeHeight() + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public double getEyeHeight(boolean bln) + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public List getLineOfSight(HashSet hs, int i) + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public Block getTargetBlock(HashSet hs, int i) + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public List getLastTwoTargetBlocks(HashSet hs, int i) + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public int getFireTicks() + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public int getMaxFireTicks() + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void setFireTicks(int i) + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void remove() + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public Server getServer() + { + return Essentials.getStatic() == null ? null : Essentials.getStatic().getServer(); + } + + public Vector getMomentum() + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void setMomentum(Vector vector) + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void setVelocity(Vector vector) + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public Vector getVelocity() + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void damage(int i) + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void damage(int i, Entity entity) + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public Location getEyeLocation() + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void sendRawMessage(String string) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public Location getCompassTarget() + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public int getMaximumNoDamageTicks() + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void setMaximumNoDamageTicks(int i) + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public int getLastDamage() + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void setLastDamage(int i) + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public int getNoDamageTicks() + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void setNoDamageTicks(int i) + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public boolean teleport(Location lctn) + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public boolean teleport(Entity entity) + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public Entity getPassenger() + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public boolean setPassenger(Entity entity) + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public boolean isEmpty() + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public boolean eject() + { + throw new UnsupportedOperationException("Not supported yet."); + } +} diff --git a/Essentials/src/com/earth2me/essentials/PlayerExtension.java b/Essentials/src/com/earth2me/essentials/PlayerExtension.java new file mode 100644 index 000000000..758f8076d --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/PlayerExtension.java @@ -0,0 +1,141 @@ +package com.earth2me.essentials; + +import org.bukkit.*; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import net.minecraft.server.EntityPlayer; +import net.minecraft.server.IInventory; +import org.bukkit.craftbukkit.inventory.CraftInventoryPlayer; +import org.bukkit.entity.*; + + +public class PlayerExtension extends PlayerWrapper +{ + public PlayerExtension(Player base) + { + super(base); + } + + public boolean isBanned() + { + return Essentials.getStatic().bans.contains(getName()); + } + + public boolean isIpBanned() + { + return Essentials.getStatic().bannedIps.contains(getAddress().getAddress().toString().replace("/", "")); + } + + public float getCorrectedYaw() + { + float angle = (getLocation().getYaw() - 90) % 360; + if (angle < 0) angle += 360.0F; + return angle; + } + + public void showInventory(IInventory inventory) + { + getHandle().a(inventory); + } + + public void showInventory(CraftInventoryPlayer inventory) + { + showInventory((IInventory)inventory.getInventory()); + } + + public Location getSafeDestination(Location loc) throws Exception + { + World world = loc.getWorld(); + double x = loc.getX(); + double y = loc.getY(); + double z = loc.getZ(); + + while (isBlockAboveAir(world, x, y, z)) + { + y -= 1.0D; + if (y < 0) { + throw new Exception("Hole in floor"); + } + } + + while (isBlockUnsafe(world, x, y, z)) + { + y += 1.0D; + if (y >= 110.0D) { + x += 1.0D; + break; + } + } + while (isBlockUnsafe(world, x, y, z)) + { + y -= 1.0D; + if (y <= 1.0D) + { + y = 110.0D; + x += 1.0D; + } + } + return new Location(world, x, y, z, loc.getYaw(), loc.getPitch()); + } + + private boolean isBlockAboveAir(World world, double x, double y, double z) + { + return world.getBlockAt((int)Math.floor(x), (int)Math.floor(y - 1.0D), (int)Math.floor(z)).getType() == Material.AIR; + } + + public boolean isBlockUnsafe(World world, double x, double y, double z) + { + Block below = world.getBlockAt((int)Math.floor(x), (int)Math.floor(y - 1.0D), (int)Math.floor(z)); + if (below.getType() == Material.LAVA || below.getType() == Material.STATIONARY_LAVA) + return true; + + if (below.getType() == Material.FIRE) + return true; + + if ((world.getBlockAt((int)Math.floor(x), (int)Math.floor(y), (int)Math.floor(z)).getType() != Material.AIR) + || (world.getBlockAt((int)Math.floor(x), (int)Math.floor(y + 1.0D), (int)Math.floor(z)).getType() != Material.AIR)) + { + return true; + } + return isBlockAboveAir(world, x, y, z); + } + + public TargetBlock getTarget() + { + return new TargetBlock(getBase()); + } + + public String getGroup() + { + try + { + return com.nijikokun.bukkit.Permissions.Permissions.Security.getGroup(getWorld().getName(), getName()); + } + catch (Throwable ex) + { + return "default"; + } + } + + public boolean canBuild() + { + try + { + return com.nijikokun.bukkit.Permissions.Permissions.Security.canGroupBuild(getWorld().getName(), getGroup()); + } + catch (Throwable ex) + { + return true; + } + } + + public EntityPlayer getHandle() + { + return (EntityPlayer)getCraftPlayer().getHandle(); + } + + public CraftPlayer getCraftPlayer() + { + return (CraftPlayer)base; + } +} diff --git a/Essentials/src/com/earth2me/essentials/PlayerWrapper.java b/Essentials/src/com/earth2me/essentials/PlayerWrapper.java new file mode 100644 index 000000000..0de6f669e --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/PlayerWrapper.java @@ -0,0 +1,416 @@ +package com.earth2me.essentials; + +import java.net.InetSocketAddress; +import java.util.*; +import org.bukkit.*; +import org.bukkit.block.Block; +import org.bukkit.entity.*; +import org.bukkit.inventory.*; +import org.bukkit.util.Vector; + +public class PlayerWrapper implements Player +{ + protected Player base; + + public PlayerWrapper(Player base) + { + this.base = base; + } + + public final Player getBase() + { + return base; + } + + public final Player setBase(Player base) + { + return this.base = base; + } + + @Override + public void setDisplayName(String string) + { + base.setDisplayName(string); + } + + @Override + public void setCompassTarget(Location lctn) + { + base.setCompassTarget(lctn); + } + + @Override + public InetSocketAddress getAddress() + { + return base.getAddress(); + } + + @Override + public void kickPlayer(String string) + { + base.kickPlayer(string); + } + + @Override + public String getName() + { + return base.getName(); + } + + @Override + public PlayerInventory getInventory() + { + return base.getInventory(); + } + + @Override + public ItemStack getItemInHand() + { + return base.getItemInHand(); + } + + @Override + public void setItemInHand(ItemStack is) + { + base.setItemInHand(is); + } + + @Override + public int getHealth() + { + return base.getHealth(); + } + + @Override + public void setHealth(int i) + { + base.setHealth(i); + } + + @Override + public Egg throwEgg() + { + return base.throwEgg(); + } + + @Override + public Snowball throwSnowball() + { + return base.throwSnowball(); + } + + @Override + public Arrow shootArrow() + { + return base.shootArrow(); + } + + @Override + public boolean isInsideVehicle() + { + return base.isInsideVehicle(); + } + + @Override + public boolean leaveVehicle() + { + return base.leaveVehicle(); + } + + @Override + public Vehicle getVehicle() + { + return base.getVehicle(); + } + + @Override + public Location getLocation() + { + return base.getLocation(); + } + + @Override + public World getWorld() + { + return base.getWorld(); + } + + @Override + public Server getServer() + { + return base.getServer(); + } + + @Override + public boolean isOnline() + { + return base.isOnline(); + } + + @Override + public boolean isOp() + { + return base.isOp(); + } + + @Override + public boolean teleport(Location lctn) + { + return base.teleport(lctn); + } + + @Override + public boolean teleport(Entity entity) + { + return base.teleport(entity); + } + + @Override + public void sendMessage(String string) + { + base.sendMessage(string); + } + + @Override + public void setVelocity(Vector vector) + { + base.setVelocity(vector); + } + + @Override + public Vector getVelocity() + { + return base.getVelocity(); + } + + @Override + public double getEyeHeight() + { + return base.getEyeHeight(); + } + + @Override + public double getEyeHeight(boolean bln) + { + return base.getEyeHeight(bln); + } + + @Override + public List getLineOfSight(HashSet hs, int i) + { + return base.getLineOfSight(hs, i); + } + + @Override + public Block getTargetBlock(HashSet hs, int i) + { + return base.getTargetBlock(hs, i); + } + + @Override + public List getLastTwoTargetBlocks(HashSet hs, int i) + { + return base.getLastTwoTargetBlocks(hs, i); + } + + @Override + public int getFireTicks() + { + return base.getFireTicks(); + } + + @Override + public int getMaxFireTicks() + { + return base.getMaxFireTicks(); + } + + @Override + public void setFireTicks(int i) + { + base.setFireTicks(i); + } + + @Override + public void remove() + { + base.remove(); + } + + /** + * This is not deprecated because the underlying method isn't really deprecated; rather, it's just "imperfect". By + * We will continue to use this method even after the underlying CraftBukkit method is changed, so do not deprecate + * it. Chances are Bukkit will also choose to un-deprecate this method at some point. + */ + @Override + public void updateInventory() + { + base.updateInventory(); + } + + @Override + public void chat(String string) + { + base.chat(string); + } + + @Override + public boolean isSneaking() + { + return base.isSneaking(); + } + + @Override + public void setSneaking(boolean bln) + { + base.setSneaking(bln); + } + + @Override + public int getEntityId() + { + return base.getEntityId(); + } + + @Override + public boolean performCommand(String string) + { + return base.performCommand(string); + } + + @Override + public int getRemainingAir() + { + return base.getRemainingAir(); + } + + @Override + public void setRemainingAir(int i) + { + base.setRemainingAir(i); + } + + @Override + public int getMaximumAir() + { + return base.getMaximumAir(); + } + + @Override + public void setMaximumAir(int i) + { + base.setMaximumAir(i); + } + + @Override + public String getDisplayName() + { + if (base.getDisplayName() != null) + return base.getDisplayName(); + else + return base.getName(); + } + + @Override + public void damage(int i) + { + base.damage(i); + } + + @Override + public void damage(int i, Entity entity) + { + base.damage(i, entity); + } + + @Override + public Location getEyeLocation() + { + return base.getEyeLocation(); + } + + @Override + public void sendRawMessage(String string) { + base.sendRawMessage(string); + } + + @Override + public Location getCompassTarget() + { + return base.getCompassTarget(); + } + + @Override + public int getMaximumNoDamageTicks() + { + return base.getMaximumNoDamageTicks(); + } + + @Override + public void setMaximumNoDamageTicks(int i) + { + base.setMaximumNoDamageTicks(i); + } + + @Override + public int getLastDamage() + { + return base.getLastDamage(); + } + + @Override + public void setLastDamage(int i) + { + base.setLastDamage(i); + } + + @Override + public int getNoDamageTicks() + { + return base.getNoDamageTicks(); + } + + @Override + public void setNoDamageTicks(int i) + { + base.setNoDamageTicks(i); + } + + @Override + public Entity getPassenger() + { + return base.getPassenger(); + } + + @Override + public boolean setPassenger(Entity entity) + { + return base.setPassenger(entity); + } + + @Override + public boolean isEmpty() + { + return base.isEmpty(); + } + + @Override + public boolean eject() + { + return base.eject(); + } + + @Override + @Deprecated + public void teleportTo(Location lctn) + { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + @Deprecated + public void teleportTo(Entity entity) + { + throw new UnsupportedOperationException("Not supported yet."); + } +} diff --git a/Essentials/src/com/earth2me/essentials/Settings.java b/Essentials/src/com/earth2me/essentials/Settings.java new file mode 100644 index 000000000..9c774b848 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/Settings.java @@ -0,0 +1,348 @@ +package com.earth2me.essentials; + +import java.util.*; +import org.bukkit.ChatColor; +import com.earth2me.essentials.commands.IEssentialsCommand; +import java.io.File; +import java.util.ArrayList; +import org.bukkit.entity.CreatureType; + + +public class Settings implements IConf +{ + private EssentialsConf config; + + public Settings(File dataFolder) + { + config = new EssentialsConf(new File(dataFolder, "config.yml")); + config.setTemplateName("/config.yml"); + config.load(); + } + + public boolean getRespawnAtHome() + { + return config.getBoolean("respawn-at-home", false); + } + + public boolean getBedSetsHome() + { + return config.getBoolean("bed-sethome", false); + } + + public int getChatRadius() + { + return config.getInt("chat.radius", config.getInt("chat-radius", 0)); + } + + public long getTeleportDelay() + { + return config.getInt("teleport-delay", 0) * 1000L; + } + + public int getDefaultStackSize() + { + return config.getInt("default-stack-size", 64); + } + + public int getStartingBalance() + { + return config.getInt("starting-balance", 0); + } + + public boolean getNetherPortalsEnabled() + { + return isNetherEnabled() && config.getBoolean("nether.portals-enabled", false); + } + + public String getMcslKey() + { + return config.getString("mcsl-key", "").replaceAll("[^a-zA-Z0-9]", ""); + } + + public boolean getWhitelistEnabled() + { + return false; + } + + public boolean isCommandDisabled(IEssentialsCommand cmd) + { + return isCommandDisabled(cmd.getName()); + } + + public boolean isCommandDisabled(String label) + { + for (String c : config.getStringList("disabled-commands", new ArrayList(0))) + { + if (!c.equalsIgnoreCase(label)) continue; + return true; + } + return config.getBoolean("disable-" + label.toLowerCase(), false); + } + + public boolean isCommandRestricted(IEssentialsCommand cmd) + { + return isCommandRestricted(cmd.getName()); + } + + public boolean isCommandRestricted(String label) + { + for (String c : config.getStringList("restricted-commands", new ArrayList(0))) + { + if (!c.equalsIgnoreCase(label)) continue; + return true; + } + return config.getBoolean("restrict-" + label.toLowerCase(), false); + } + + public int getCommandCost(IEssentialsCommand cmd) + { + return getCommandCost(cmd.getName()); + } + + public int getCommandCost(String label) + { + int cost = config.getInt("command-costs." + label, 0); + if (cost == 0) + cost = config.getInt("cost-" + label, 0); + return cost; + } + + public String getCommandPrefix() + { + return config.getString("command-prefix", ""); + } + + public String getNicknamePrefix() + { + return config.getString("nickname-prefix", ""); + } + + public long getTeleportCooldown() + { + return (long)config.getInt("teleport-cooldown", 60) * 1000L; + } + + public long getHealCooldown() + { + return (long)config.getInt("heal-cooldown", 60) * 1000L; + } + + public Object getKit(String name) + { + Map kits = (Map)config.getProperty("kits"); + return kits.get(name.replace('.', '_').replace('/', '_')); + } + + public ChatColor getOperatorColor() + { + String colorName = config.getString("ops-name-color", null); + + if (colorName == null) + return ChatColor.RED; + + try + { + return ChatColor.valueOf(colorName.toUpperCase()); + } + catch (IllegalArgumentException ex) + { + } + + return ChatColor.getByCode(Integer.parseInt(colorName, 16)); + } + + public boolean getReclaimSetting() + { + return config.getBoolean("reclaim-onlogout", true); + } + + public String getNetherName() + { + return config.getString("nether.folder", "nether"); + } + + public boolean isNetherEnabled() + { + return config.getBoolean("nether.enabled", true); + } + + public int getSpawnMobLimit() + { + return config.getInt("spawnmob-limit", 10); + } + + public boolean showNonEssCommandsInHelp() + { + return config.getBoolean("non-ess-in-help", true); + } + + public HashMap getEpSettings() + { + HashMap epSettings = new HashMap(); + + epSettings.put("protect.protect.signs", config.getBoolean("protect.protect.signs", true)); + epSettings.put("protect.protect.rails", config.getBoolean("protect.protect.rails", true)); + epSettings.put("protect.protect.block-below", config.getBoolean("protect.protect.block-below", true)); + epSettings.put("protect.protect.prevent-block-on-rails", config.getBoolean("protect.protect.prevent-block-on-rails", false)); + return epSettings; + } + + public HashMap getEpDBSettings() + { + HashMap epSettings = new HashMap(); + epSettings.put("protect.datatype", config.getString("protect.datatype", "sqlite")); + epSettings.put("protect.username", config.getString("protect.username", "root")); + epSettings.put("protect.password", config.getString("protect.password", "root")); + epSettings.put("protect.mysqlDb", config.getString("protect.mysqlDb", "jdbc:mysql://localhost:3306/minecraft")); + return epSettings; + } + + public ArrayList getEpAlertOnPlacement() + { + ArrayList epAlertPlace = new ArrayList(); + epAlertPlace.addAll(Arrays.asList(config.getString("protect.alert.on-placement", "").split(","))); + return epAlertPlace; + } + + public ArrayList getEpAlertOnUse() + { + ArrayList epAlertUse = new ArrayList(); + epAlertUse.addAll(Arrays.asList(config.getString("protect.alert.on-use", "").split(","))); + return epAlertUse; + } + + public ArrayList getEpAlertOnBreak() + { + ArrayList epAlertPlace = new ArrayList(); + epAlertPlace.addAll(Arrays.asList(config.getString("protect.alert.on-break", "").split(","))); + return epAlertPlace; + } + + public ArrayList epBlackListPlacement() + { + ArrayList epBlack = new ArrayList(); + epBlack.addAll(Arrays.asList(config.getString("protect.blacklist.placement", "").split(","))); + return epBlack; + } + + public ArrayList epBlackListUsage() + { + ArrayList epBlack = new ArrayList(); + epBlack.addAll(Arrays.asList(config.getString("protect.blacklist.usage", "").split(","))); + return epBlack; + } + + public HashMap getEpGuardSettings() + { + HashMap epSettings = new HashMap(); + epSettings.put("protect.prevent.lava-flow", config.getBoolean("protect.prevent.lava-flow", false)); + epSettings.put("protect.prevent.water-flow", config.getBoolean("protect.prevent.water-flow", false)); + epSettings.put("protect.prevent.water-bucket-flow", config.getBoolean("protect.prevent.water-bucket-flow", false)); + epSettings.put("protect.prevent.fire-spread", config.getBoolean("protect.prevent.fire-spread", false)); + epSettings.put("protect.prevent.flint-fire", config.getBoolean("protect.prevent.flint-fire", false)); + epSettings.put("protect.prevent.lava-fire-spread", config.getBoolean("protect.prevent.lava-fire-spread", false)); + epSettings.put("protect.prevent.tnt-explosion", config.getBoolean("protect.prevent.tnt-explosion", false)); + epSettings.put("protect.prevent.creeper-explosion", config.getBoolean("protect.prevent.creeper-explosion", false)); + epSettings.put("protect.prevent.creeper-playerdamage", config.getBoolean("protect.prevent.creeper-playerdamage", false)); + epSettings.put("protect.prevent.creeper-blockdamage", config.getBoolean("protect.prevent.creeper-blockdamage", false)); + for (CreatureType ct : CreatureType.values()) { + String name = ct.toString().toLowerCase(); + epSettings.put("protect.prevent.spawn."+name, config.getBoolean("protect.prevent.spawn."+name, false)); + } + return epSettings; + } + + public HashMap getEpPlayerSettings() + { + HashMap epPlayerSettings = new HashMap(); + epPlayerSettings.put("protect.disable.fall", config.getBoolean("protect.disable.fall", false)); + epPlayerSettings.put("protect.disable.pvp", config.getBoolean("protect.disable.pvp", false)); + epPlayerSettings.put("protect.disable.drown", config.getBoolean("protect.disable.drown", false)); + epPlayerSettings.put("protect.disable.suffocate", config.getBoolean("protect.disable.suffocate", false)); + epPlayerSettings.put("protect.disable.lavadmg", config.getBoolean("protect.disable.lavadmg", false)); + epPlayerSettings.put("protect.disable.projectiles", config.getBoolean("protect.disable.projectiles", false)); + epPlayerSettings.put("protect.disable.contactdmg", config.getBoolean("protect.disable.contactdmg", false)); + epPlayerSettings.put("protect.disable.firedmg", config.getBoolean("protect.disable.firedmg", false)); + epPlayerSettings.put("protect.disable.build", config.getBoolean("protect.disable.build", false)); + return epPlayerSettings; + + } + + public int getEpCreeperMaxHeight() + { + return config.getInt("protect.creeper.max-height", -1); + } + + public boolean areSignsDisabled() + { + return config.getBoolean("signs-disabled", false); + } + + public long getBackupInterval() + { + return config.getInt("backup.interval", 1440); // 1440 = 24 * 60 + } + + public String getBackupCommand() + { + return config.getString("backup.command", null); + } + + public String getChatFormat(String group) + { + return config.getString("chat.group-formats." + (group == null ? "Default" : group), + config.getString("chat.format", "&7[{GROUP}]&f {DISPLAYNAME}&7:&f {MESSAGE}")); + } + + public boolean getGenerateExitPortals() + { + return config.getBoolean("nether.generate-exit-portals", true); + } + + public boolean getAnnounceNewPlayers() + { + return !config.getString("newbies.announce-format", "-").isEmpty(); + } + + public String getAnnounceNewPlayerFormat(User user) + { + return format(config.getString("newbies.announce-format", "&dWelcome {DISPLAYNAME} to the server!"), user); + } + + public String format(String format, User user) + { + return format.replace('&', '§').replace("§§", "&").replace("{PLAYER}", user.getDisplayName()).replace("{DISPLAYNAME}", user.getDisplayName()).replace("{GROUP}", user.getGroup()).replace("{USERNAME}", user.getName()).replace("{ADDRESS}", user.getAddress().toString()); + } + + public String getNewbieSpawn() + { + return config.getString("newbies.spawnpoint", "default"); + } + public boolean getPerWarpPermission() + { + return config.getBoolean("per-warp-permission", false); + } + + public boolean getSortListByGroups() + { + return config.getBoolean("sort-list-by-groups", true); + } + + public void reloadConfig() { + config.load(); + } + + public ArrayList itemSpawnBlacklist() + { + ArrayList epItemSpwn = new ArrayList(); + epItemSpwn.addAll(Arrays.asList(config.getString("item-spawn-blacklist", "").split(","))); + return epItemSpwn; + } + + public ArrayList epBlockBreakingBlacklist() + { + ArrayList epBreakList = new ArrayList(); + epBreakList.addAll(Arrays.asList(config.getString("protect.blacklist.break", "").split(","))); + return epBreakList; + } +} diff --git a/Essentials/src/com/earth2me/essentials/Spawn.java b/Essentials/src/com/earth2me/essentials/Spawn.java new file mode 100644 index 000000000..f3c4de06a --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/Spawn.java @@ -0,0 +1,87 @@ +package com.earth2me.essentials; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Logger; +import org.bukkit.Location; +import org.bukkit.Server; +import org.bukkit.World; +import org.bukkit.World.Environment; + +public class Spawn implements IConf { + + private static final Logger logger = Logger.getLogger("Minecraft"); + private EssentialsConf config; + private Server server; + + public Spawn(Server server, File dataFolder) { + File configFile = new File(dataFolder, "spawn.yml"); + this.server = server; + config = new EssentialsConf(configFile); + config.load(); + } + + public void setSpawn(Location loc, String group) { + Map map = new HashMap(); + map.put("world", loc.getWorld().getName()); + map.put("x", loc.getX()); + map.put("y", loc.getY()); + map.put("z", loc.getZ()); + map.put("yaw", loc.getYaw()); + map.put("pitch", loc.getPitch()); + config.setProperty(group, map); + config.save(); + + if ("default".equals(group)) { + loc.getWorld().setSpawnLocation(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + } + } + + public Location getSpawn(String group) { + if (config.getProperty(group) == null) { + group = "default"; + } + if (config.getProperty(group) == null) { + for (World w : server.getWorlds()) { + if (w.getEnvironment() != Environment.NORMAL) { + continue; + } + return w.getSpawnLocation(); + } + } + String worldId = config.getString(group + ".world", ""); + World world = server.getWorlds().get(server.getWorlds().size() > 1 ? 1 : 0); + for (World w : server.getWorlds()) { + if (w.getEnvironment() != Environment.NORMAL) { + continue; + } + world = w; + break; + } + for (World w : server.getWorlds()) { + if (!w.getName().equals(worldId)) { + continue; + } + world = w; + break; + } + + double x = config.getDouble(group + ".x", config.getDouble("default.x", 0)); + double y = config.getDouble(group + ".y", config.getDouble("default.y", 0)); + double z = config.getDouble(group + ".z", config.getDouble("default.z", 0)); + float yaw = (float) config.getDouble(group + ".yaw", config.getDouble("default.yaw", 0)); + float pitch = (float) config.getDouble(group + ".pitch", config.getDouble("default.pitch", 0)); + Location retval = new Location(world, x, y, z, yaw, pitch); + + if (y < 1) { + retval.setY(world.getHighestBlockYAt(retval)); + } + + return retval; + } + + public void reloadConfig() { + config.load(); + } +} diff --git a/Essentials/src/com/earth2me/essentials/TargetBlock.java b/Essentials/src/com/earth2me/essentials/TargetBlock.java new file mode 100644 index 000000000..d3ac30d2d --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/TargetBlock.java @@ -0,0 +1,599 @@ +package com.earth2me.essentials; + +import java.util.ArrayList; +import org.bukkit.block.Block; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; +/** + * @author toi + * Thanks to Raphfrk for optimization of this class. + */ +public class TargetBlock { + + private Location loc; + private double viewHeight; + private int maxDistance; + private int[] blockToIgnore; + private double checkDistance, curDistance; + private double xRotation, yRotation; + private Vector targetPos = new Vector(); + private Vector targetPosDouble = new Vector(); + private Vector prevPos = new Vector(); + private Vector offset = new Vector(); + + /** + * Constructor requiring a player, uses default values + * + * @param player Player to work with + */ + public TargetBlock(Player player) + { + this.setValues(player.getLocation(), 300, 1.65, 0.2, null); + } + + /** + * Constructor requiring a location, uses default values + * + * @param loc Location to work with + */ + public TargetBlock(Location loc) + { + this.setValues(loc, 300, 0, 0.2, null); + } + + /** + * Constructor requiring a player, max distance and a checking distance + * + * @param player Player to work with + * @param maxDistance How far it checks for blocks + * @param checkDistance How often to check for blocks, the smaller the more precise + */ + public TargetBlock(Player player, int maxDistance, double checkDistance) + { + this.setValues(player.getLocation(), maxDistance, 1.65, checkDistance, null); + } + + /** + * Constructor requiring a location, max distance and a checking distance + * + * @param loc What location to work with + * @param maxDistance How far it checks for blocks + * @param checkDistance How often to check for blocks, the smaller the more precise + */ + public TargetBlock(Location loc, int maxDistance, double checkDistance) { + this.setValues(loc, maxDistance, 0, checkDistance, null); + } + + /** + * Constructor requiring a player, max distance, checking distance and an array of blocks to ignore + * + * @param player What player to work with + * @param maxDistance How far it checks for blocks + * @param checkDistance How often to check for blocks, the smaller the more precise + * @param blocksToIgnore Integer array of what block ids to ignore while checking for viable targets + */ + public TargetBlock (Player player, int maxDistance, double checkDistance, int[] blocksToIgnore) + { + this.setValues(player.getLocation(), maxDistance, 1.65, checkDistance, blocksToIgnore); + } + + /** + * Constructor requiring a location, max distance, checking distance and an array of blocks to ignore + * + * @param loc What location to work with + * @param maxDistance How far it checks for blocks + * @param checkDistance How often to check for blocks, the smaller the more precise + * @param blocksToIgnore Array of what block ids to ignore while checking for viable targets + */ + public TargetBlock (Location loc, int maxDistance, double checkDistance, int[] blocksToIgnore) + { + this.setValues(loc, maxDistance, 0, checkDistance, blocksToIgnore); + } + + /** + * Constructor requiring a player, max distance, checking distance and an array of blocks to ignore + * + * @param player What player to work with + * @param maxDistance How far it checks for blocks + * @param checkDistance How often to check for blocks, the smaller the more precise + * @param blocksToIgnore String ArrayList of what block ids to ignore while checking for viable targets + */ + public TargetBlock (Player player, int maxDistance, double checkDistance, ArrayList blocksToIgnore) + { + int[] bti = this.convertStringArraytoIntArray(blocksToIgnore); + this.setValues(player.getLocation(), maxDistance, 1.65, checkDistance, bti); + } + + /** + * Constructor requiring a location, max distance, checking distance and an array of blocks to ignore + * + * @param loc What location to work with + * @param maxDistance How far it checks for blocks + * @param checkDistance How often to check for blocks, the smaller the more precise + * @param blocksToIgnore String ArrayList of what block ids to ignore while checking for viable targets + */ + public TargetBlock (Location loc, int maxDistance, double checkDistance, ArrayList blocksToIgnore) + { + int[] bti = this.convertStringArraytoIntArray(blocksToIgnore); + this.setValues(loc, maxDistance, 0, checkDistance, bti); + } + + /** + * Set the values, all constructors uses this function + * + * @param loc Location of the view + * @param maxDistance How far it checks for blocks + * @param viewPos Where the view is positioned in y-axis + * @param checkDistance How often to check for blocks, the smaller the more precise + * @param blocksToIgnore Ids of blocks to ignore while checking for viable targets + */ + private void setValues(Location loc, int maxDistance, double viewHeight, double checkDistance, int[] blocksToIgnore) + { + this.loc = loc; + this.maxDistance = maxDistance; + this.viewHeight = viewHeight; + this.checkDistance = checkDistance; + this.blockToIgnore = blocksToIgnore; + this.curDistance = 0; + xRotation = (loc.getYaw() + 90) % 360; + yRotation = loc.getPitch() * -1; + + double h = (checkDistance * Math.cos(Math.toRadians(yRotation))); + offset.setY((checkDistance * Math.sin(Math.toRadians(yRotation)))); + offset.setX((h * Math.cos(Math.toRadians(xRotation)))); + offset.setZ((h * Math.sin(Math.toRadians(xRotation)))); + + targetPosDouble = new Vector(loc.getX(), loc.getY() + viewHeight, loc.getZ()); + targetPos = new Vector( targetPosDouble.getBlockX(), targetPosDouble.getBlockY(), targetPosDouble.getBlockZ()); + prevPos = targetPos.clone(); + } + + /** + * Call this to reset checking position to allow you to check for a new target with the same TargetBlock instance. + */ + public void reset() + { + targetPosDouble = new Vector(loc.getX(), loc.getY() + viewHeight, loc.getZ()); + targetPos = new Vector( targetPosDouble.getBlockX(), targetPosDouble.getBlockY(), targetPosDouble.getBlockZ()); + prevPos = targetPos.clone(); + this.curDistance = 0; + } + + /** + * Gets the distance to a block. Measures from the block underneath the player to the targetblock + * Should only be used when passing player as an constructor parameter + * + * @return double + */ + public double getDistanceToBlock() + { + Vector blockUnderPlayer = new Vector( + (int) Math.floor(loc.getX() + 0.5), + (int) Math.floor(loc.getY() - 0.5), + (int) Math.floor(loc.getZ() + 0.5)); + + Block blk = getTargetBlock(); + double x = blk.getX() - blockUnderPlayer.getBlockX(); + double y = blk.getY() - blockUnderPlayer.getBlockY(); + double z = blk.getZ() - blockUnderPlayer.getBlockZ(); + + return Math.sqrt((Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2))); + } + + /** + * Gets the rounded distance to a block. Measures from the block underneath the player to the targetblock + * Should only be used when passing player as an constructor parameter + * + * @return int + */ + public int getDistanceToBlockRounded() + { + Vector blockUnderPlayer = new Vector( + (int) Math.floor(loc.getX() + 0.5), + (int) Math.floor(loc.getY() - 0.5), + (int) Math.floor(loc.getZ() + 0.5)); + + Block blk = getTargetBlock(); + double x = blk.getX() - blockUnderPlayer.getBlockX(); + double y = blk.getY() - blockUnderPlayer.getBlockY(); + double z = blk.getZ() - blockUnderPlayer.getBlockZ(); + + return (int) Math.round((Math.sqrt((Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2))))); + } + + /** + * Gets the floored x distance to a block. + * + * @return int + */ + public int getXDistanceToBlock() + { + this.reset(); + return (int) Math.floor(getTargetBlock().getX() - loc.getBlockX() + 0.5); + } + + /** + * Gets the floored y distance to a block + * + * @return int + */ + public int getYDistanceToBlock() + { + this.reset(); + return (int) Math.floor(getTargetBlock().getY() - loc.getBlockY() + viewHeight); + } + + /** + * Gets the floored z distance to a block + * + * @return int + */ + public int getZDistanceToBlock() + { + this.reset(); + return (int) Math.floor(getTargetBlock().getZ() - loc.getBlockZ() + 0.5); + } + + /** + * Returns the block at the sight. Returns null if out of range or if no viable target was found + * + * @return Block + */ + @SuppressWarnings("empty-statement") + public Block getTargetBlock() + { + this.reset(); + while ((getNextBlock() != null) && ((getCurrentBlock().getTypeId() == 0) || this.blockToIgnoreHasValue(getCurrentBlock().getTypeId()))); + return getCurrentBlock(); + } + + /** + * Sets the type of the block at the sight. Returns false if the block wasn't set. + * + * @param typeID ID of type to set the block to + * @return boolean + */ + @SuppressWarnings("empty-statement") + public boolean setTargetBlock(int typeID) + { + if (Material.getMaterial(typeID) != null) + { + this.reset(); + while (getNextBlock() != null && getCurrentBlock().getTypeId() == 0); + if (getCurrentBlock() != null) + { + Block blk = loc.getWorld().getBlockAt(targetPos.getBlockX(), targetPos.getBlockY(), targetPos.getBlockZ()); + blk.setTypeId(typeID); + return true; + } + } + return false; + } + + /** + * Sets the type of the block at the sight. Returns false if the block wasn't set. + * + * @param type Material to set the block to + * @return boolean + */ + @SuppressWarnings("empty-statement") + public boolean setTargetBlock(Material type) + { + this.reset(); + while ((getNextBlock() != null) && ((getCurrentBlock().getTypeId() == 0) || this.blockToIgnoreHasValue(getCurrentBlock().getTypeId()))); + if (getCurrentBlock() != null) + { + Block blk = loc.getWorld().getBlockAt(targetPos.getBlockX(), targetPos.getBlockY(), targetPos.getBlockZ()); + blk.setType(type); + return true; + } + return false; + } + + /** + * Sets the type of the block at the sight. Returns false if the block wasn't set. + * Observe! At the moment this function is using the built-in enumerator function .valueOf(String) but would preferably be changed to smarter function, when implemented + * + * @param type Name of type to set the block to + * @return boolean + */ + @SuppressWarnings("empty-statement") + public boolean setTargetBlock(String type) + { + Material mat = Material.valueOf(type); + if (mat != null) + { + this.reset(); + while ((getNextBlock() != null) && ((getCurrentBlock().getTypeId() == 0) || this.blockToIgnoreHasValue(getCurrentBlock().getTypeId()))); + if (getCurrentBlock() != null) + { + Block blk = loc.getWorld().getBlockAt(targetPos.getBlockX(), targetPos.getBlockY(), targetPos.getBlockZ()); + blk.setType(mat); + return true; + } + } + return false; + } + + /** + * Returns the block attached to the face at the sight. Returns null if out of range or if no viable target was found + * + * @return Block + */ + @SuppressWarnings("empty-statement") + public Block getFaceBlock() + { + while ((getNextBlock() != null) && ((getCurrentBlock().getTypeId() == 0) || this.blockToIgnoreHasValue(getCurrentBlock().getTypeId()))); + if (getCurrentBlock() != null) + { + return getPreviousBlock(); + } + else + { + return null; + } + } + + /** + * Sets the type of the block attached to the face at the sight. Returns false if the block wasn't set. + * + * @param typeID + * @return boolean + */ + public boolean setFaceBlock(int typeID) + { + if (Material.getMaterial(typeID) != null) + { + if (getCurrentBlock() != null) + { + Block blk = loc.getWorld().getBlockAt(prevPos.getBlockX(), prevPos.getBlockY(), prevPos.getBlockZ()); + blk.setTypeId(typeID); + return true; + } + } + return false; + } + + /** + * Sets the type of the block attached to the face at the sight. Returns false if the block wasn't set. + * + * @param type + * @return boolean + */ + public boolean setFaceBlock(Material type) + { + if (getCurrentBlock() != null) + { + Block blk = loc.getWorld().getBlockAt(prevPos.getBlockX(), prevPos.getBlockY(), prevPos.getBlockZ()); + blk.setType(type); + return true; + } + return false; + } + + /** + * Sets the type of the block attached to the face at the sight. Returns false if the block wasn't set. + * Observe! At the moment this function is using the built-in enumerator function .valueOf(String) but would preferably be changed to smarter function, when implemented + * + * @param type + * @return boolean + */ + public boolean setFaceBlock(String type) + { + Material mat = Material.valueOf(type); + if (mat != null) + { + if (getCurrentBlock() != null) + { + Block blk = loc.getWorld().getBlockAt(prevPos.getBlockX(), prevPos.getBlockY(), prevPos.getBlockZ()); + blk.setType(mat); + return true; + } + } + return false; + } + + /** + * Get next block + * + * @return Block + */ + public Block getNextBlock() + { + prevPos = targetPos.clone(); + do + { + curDistance += checkDistance; + + targetPosDouble.setX(offset.getX() + targetPosDouble.getX()); + targetPosDouble.setY(offset.getY() + targetPosDouble.getY()); + targetPosDouble.setZ(offset.getZ() + targetPosDouble.getZ()); + targetPos = new Vector( targetPosDouble.getBlockX(), targetPosDouble.getBlockY(), targetPosDouble.getBlockZ()); + } + while (curDistance <= maxDistance && targetPos.getBlockX() == prevPos.getBlockX() && targetPos.getBlockY() == prevPos.getBlockY() && targetPos.getBlockZ() == prevPos.getBlockZ()); + if (curDistance > maxDistance) + { + return null; + } + + return this.loc.getWorld().getBlockAt(this.targetPos.getBlockX(), this.targetPos.getBlockY(), this.targetPos.getBlockZ()); + } + + /** + * Returns the current block along the line of vision + * + * @return Block + */ + public Block getCurrentBlock() + { + if (curDistance > maxDistance) + { + return null; + } + else + { + return this.loc.getWorld().getBlockAt(this.targetPos.getBlockX(), this.targetPos.getBlockY(), this.targetPos.getBlockZ()); + } + } + + /** + * Sets current block type. Returns false if the block wasn't set. + * + * @param typeID + */ + public boolean setCurrentBlock(int typeID) + { + if (Material.getMaterial(typeID) != null) + { + Block blk = getCurrentBlock(); + if (blk != null) + { + blk.setTypeId(typeID); + return true; + } + } + return false; + } + + /** + * Sets current block type. Returns false if the block wasn't set. + * + * @param type + */ + public boolean setCurrentBlock(Material type) + { + Block blk = getCurrentBlock(); + if (blk != null) + { + blk.setType(type); + return true; + } + return false; + } + + /** + * Sets current block type. Returns false if the block wasn't set. + * Observe! At the moment this function is using the built-in enumerator function .valueOf(String) but would preferably be changed to smarter function, when implemented + * + * @param type + */ + public boolean setCurrentBlock(String type) + { + Material mat = Material.valueOf(type); + if (mat != null) + { + Block blk = getCurrentBlock(); + if (blk != null) + { + blk.setType(mat); + return true; + } + } + return false; + } + + /** + * Returns the previous block in the aimed path + * + * @return Block + */ + public Block getPreviousBlock() + { + return this.loc.getWorld().getBlockAt(prevPos.getBlockX(), prevPos.getBlockY(), prevPos.getBlockZ()); + } + + /** + * Sets previous block type id. Returns false if the block wasn't set. + * + * @param typeID + */ + public boolean setPreviousBlock(int typeID) + { + if (Material.getMaterial(typeID) != null) + { + Block blk = getPreviousBlock(); + if (blk != null) + { + blk.setTypeId(typeID); + return true; + } + } + return false; + } + + /** + * Sets previous block type id. Returns false if the block wasn't set. + * + * @param type + */ + public boolean setPreviousBlock(Material type) + { + Block blk = getPreviousBlock(); + if (blk != null) + { + blk.setType(type); + return true; + } + return false; + } + + /** + * Sets previous block type id. Returns false if the block wasn't set. + * Observe! At the moment this function is using the built-in enumerator function .valueOf(String) but would preferably be changed to smarter function, when implemented + * + * @param type + */ + public boolean setPreviousBlock(String type) + { + Material mat = Material.valueOf(type); + if (mat != null) + { + Block blk = getPreviousBlock(); + if (blk != null) + { + blk.setType(mat); + return true; + } + } + return false; + } + + private int[] convertStringArraytoIntArray(ArrayList array) + { + if (array != null) + { + int intarray[] = new int[array.size()]; + for (int i = 0; i < array.size(); i++) + { + try + { + intarray[i] = Integer.parseInt(array.get(i)); + } + catch (NumberFormatException nfe) + { + intarray[i] = 0; + } + } + return intarray; + } + return null; + } + + private boolean blockToIgnoreHasValue(int value) + { + if (this.blockToIgnore != null) + { + if (this.blockToIgnore.length > 0) + { + for (int i : this.blockToIgnore) + { + if (i == value) + return true; + } + } + } + return false; + } +} \ No newline at end of file diff --git a/Essentials/src/com/earth2me/essentials/TeleportTimer.java b/Essentials/src/com/earth2me/essentials/TeleportTimer.java new file mode 100644 index 000000000..11d65170f --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/TeleportTimer.java @@ -0,0 +1,73 @@ +package com.earth2me.essentials; + +import java.util.TimerTask; +import java.util.Calendar; + + +public abstract class TeleportTimer implements Runnable +{ + private long started; // time this task was initiated + private long delay; // how long to delay the teleport + public User user; // the person doing the teleport + private int health; + // note that I initially stored a clone of the location for reference, but... + // when comparing locations, I got incorrect mismatches (rounding errors, looked like) + // so, the X/Y/Z values are stored instead and rounded off + private long initX; + private long initY; + private long initZ; + + public TeleportTimer(User tUser, long tDelay) + { + this.started = Calendar.getInstance().getTimeInMillis(); + this.delay = tDelay; + this.user = tUser; + this.health = user.getHealth(); + this.initX = Math.round(user.getLocation().getX() * 10000); + this.initY = Math.round(user.getLocation().getY() * 10000); + this.initZ = Math.round(user.getLocation().getZ() * 10000); + } + + // This function needs to be defined when creating a new TeleportTimer + // The actual teleport command by itself should be stuck in there, such as teleportToNow(loc) + public abstract void DoTeleport(); + + public abstract void DoCancel(); + + public void run() + { + if (user == null || !user.isOnline() || user.getLocation() == null) + { + DoCancel(); + return; + } + if (Math.round(user.getLocation().getX() * 10000) != initX + || Math.round(user.getLocation().getY() * 10000) != initY + || Math.round(user.getLocation().getZ() * 10000) != initZ + || user.getHealth() < health) + { // user moved, cancel teleport + user.cancelTeleport(true); + return; + } + + health = user.getHealth(); // in case user healed, then later gets injured + + long now = Calendar.getInstance().getTimeInMillis(); + if (now > started + delay) + { + try + { + user.teleportCooldown(false); + user.sendMessage("§7Teleportation commencing..."); + this.DoTeleport(); + return; + } + catch (Exception ex) + { + user.sendMessage("§cCooldown: " + ex.getMessage()); + } + } + //else // uncomment for timing debug + // user.sendMessage("§7" + (started + delay - now)); + } +} diff --git a/Essentials/src/com/earth2me/essentials/User.java b/Essentials/src/com/earth2me/essentials/User.java new file mode 100644 index 000000000..472015997 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/User.java @@ -0,0 +1,695 @@ +package com.earth2me.essentials; + +import java.util.*; +import java.util.logging.*; +import java.io.*; +import org.bukkit.*; +import com.earth2me.essentials.commands.IEssentialsCommand; +import net.minecraft.server.EntityHuman; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.entity.*; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.SafeConstructor; +import org.yaml.snakeyaml.reader.UnicodeReader; + + +public class User extends PlayerExtension implements Comparable +{ + private static final Logger logger = Logger.getLogger("Minecraft"); + private final Yaml yaml = new Yaml(new SafeConstructor()); + private boolean isLoaded = false; + private final File folder; + private Map data = new HashMap(); + private static Map users = new HashMap(); + private boolean teleEnabled = true; + private long lastTeleport = 0; + private long lastHeal = 0; + private boolean justPortaled = false; + //private TimerTask teleTimer = null; + private int teleTimer = -1; + public Location lastLocation = null; + private User replyTo = null; + private boolean isNew = false; + public String currentJail; + public CraftItemStack[] savedInventory; + + private User(Player base) + { + super(base); + this.folder = new File((Essentials.getStatic() == null ? new File(".") : Essentials.getStatic().getDataFolder()), "userdata"); + + if (base instanceof EntityHuman) + { + this.lastLocation = getBase().getLocation(); + } + load(); + } + + public static int size() + { + return users.size(); + } + + public static User get(T base) + { + if (base instanceof Player) + return get((Player)base); + return null; + } + + public static User get(T base) + { + if (base == null) + return null; + + if (base instanceof User) + return (User)base; + + if (users.containsKey(base.getName())) + return users.get(base.getName()).update(base); + + User u = new User(base); + users.put(u.getName(), u); + return u; + } + + public static void charge(T base, IEssentialsCommand cmd) throws Exception + { + if (base instanceof Player) + User.get(base).charge(cmd); + } + + public boolean isNew() + { + return isNew; + } + + public void respawn(Spawn spawn) throws Exception + { + respawn(spawn, null); + } + + public void respawn(Spawn spawn, final String chargeFor) throws Exception + { + teleport(getSafeDestination(spawn.getSpawn(getGroup())), chargeFor); + } + + private User update(Player base) + { + setBase(base); + return this; + } + + public boolean isAuthorized(IEssentialsCommand cmd) + { + return isAuthorized("essentials." + (cmd.getName().equals("r") ? "msg" : cmd.getName())); + } + + public boolean isAuthorized(String node) + { + if (isOp()) + return true; + + if (isJailed()) + return false; + + try + { + return com.nijikokun.bukkit.Permissions.Permissions.Security.permission(base, node); + } + catch (Throwable ex) + { + String[] cmds = node.split("\\.", 2); + return !Essentials.getSettings().isCommandRestricted(cmds[cmds.length - 1]); + } + } + + public boolean isTeleEnabled() + { + return teleEnabled; + } + + public boolean toggleTeleEnabled() + { + return teleEnabled = !teleEnabled; + } + + public void teleportCooldown(boolean justCheck) throws Exception + { + long now = Calendar.getInstance().getTimeInMillis(); + long cooldown = Essentials.getSettings().getTeleportCooldown(); + long left = lastTeleport + cooldown - now; + if (left > 0 && !isOp() && !isAuthorized("essentials.teleport.cooldown.bypass")) + throw new Exception("Time before next teleport: " + Essentials.FormatTime(left)); + // if justCheck is set, don't update lastTeleport; we're just checking + if (!justCheck) lastTeleport = now; + } + + public void teleportCooldown() throws Exception + { + teleportCooldown(true); + } + + public void healCooldown() throws Exception + { + long now = Calendar.getInstance().getTimeInMillis(); + long cooldown = Essentials.getSettings().getHealCooldown(); + long left = lastHeal + cooldown - now; + if (left > 0 && !isOp() && !isAuthorized("essentials.heal.cooldown.bypass")) + throw new Exception("Time before next heal: " + Essentials.FormatTime(left)); + lastHeal = now; + } + + private void load() + { + if (isLoaded) return; + isLoaded = true; + + data = Essentials.getData(this); + + try + { + if (!folder.exists()) folder.mkdirs(); + File file = new File(folder, getName() + ".yml"); + if (!file.exists()) + { + isNew = true; + file.createNewFile(); + logger.info(getName() + " has logged in for the first time."); + } + + FileInputStream rx = new FileInputStream(file); + Map userData = (Map)yaml.load(new UnicodeReader(rx)); + if (userData != null) data.putAll(userData); + rx.close(); + } + catch (Throwable ex) + { + logger.log(Level.SEVERE, null, ex); + } + finally + { + if (data == null) data = new HashMap(); + } + } + + private void flush() + { + try + { + if (!folder.exists()) folder.mkdirs(); + File file = new File(folder, getName() + ".yml"); + if (!file.exists()) file.createNewFile(); + + FileWriter tx = new FileWriter(file); + tx.write(yaml.dump(data)); + tx.flush(); + tx.close(); + } + catch (Throwable ex) + { + logger.log(Level.SEVERE, null, ex); + } + } + + public boolean isGodModeEnabled() + { + load(); + return data.containsKey("godmode") && (Boolean)data.get("godmode"); + } + + public boolean toggleGodMode() + { + boolean retval = !isGodModeEnabled(); + data.put("godmode", retval); + flush(); + return retval; + } + + public boolean isMuted() + { + load(); + return data.containsKey("muted") && (Boolean)data.get("muted"); + } + + public boolean toggleMuted() + { + boolean retval = !isMuted(); + data.put("muted", retval); + flush(); + return retval; + } + + public boolean isJailed() + { + //load(); Do not load config everytime time! + return data.containsKey("jailed") && (Boolean)data.get("jailed"); + } + + public boolean toggleJailed() + { + boolean retval = !isJailed(); + data.put("jailed", retval); + flush(); + load(); + return retval; + } + + public double getMoney() + { + load(); + if (data.containsKey("money")) + { + if (data.get("money") instanceof Integer) + return (double)((Integer)data.get("money")); + return (Double)data.get("money"); + } + + try + { + return com.nijiko.coelho.iConomy.iConomy.getBank().getAccount(getName()).getBalance(); + } + catch (Throwable ex) + { + try + { + Map idata = Essentials.getData(this); + return (Integer)idata.get("money"); + } + catch (Throwable ex2) + { + return Essentials.getSettings().getStartingBalance(); + } + } + } + + public void setMoney(double value) + { + try + { + com.nijiko.coelho.iConomy.iConomy.getBank().getAccount(getName()).setBalance(value); + } + catch (Throwable ex) + { + data.put("money", value); + flush(); + } + } + + public void giveMoney(double value) + { + if (value == 0) return; + setMoney(getMoney() + value); + sendMessage("§a$" + value + " has been added to your account."); + } + + public void payUser(User reciever, int value) throws Exception + { + if (value == 0) return; + if (!canAfford(value)) + { + throw new Exception("You do not have sufficient funds."); + } + else + { + setMoney(getMoney() - value); + reciever.setMoney(reciever.getMoney() + value); + sendMessage("§a$" + value + " has been sent to " + reciever.getDisplayName()); + reciever.sendMessage("§a$" + value + " has been recieved from " + getDisplayName()); + } + } + + public void takeMoney(double value) + { + if (value == 0) return; + setMoney(getMoney() - value); + sendMessage("§c$" + value + " has been taken from your account."); + } + + public void charge(String cmd) throws Exception + { + double mon = getMoney(); + double cost = Essentials.getSettings().getCommandCost(cmd.startsWith("/") ? cmd.substring(1) : cmd); + if (mon < cost && !isOp()) + throw new Exception("You do not have sufficient funds."); + takeMoney(cost); + } + + public void canAfford(String cmd) throws Exception + { + double mon = getMoney(); + double cost = Essentials.getSettings().getCommandCost(cmd.startsWith("/") ? cmd.substring(1) : cmd); + if (mon < cost && !isOp()) + throw new Exception("You do not have sufficient funds."); + } + + public boolean canAfford(double cost) + { + double mon = getMoney(); + if (mon < cost && !isOp()) + { + return false; + } + else + { + return true; + } + } + + public void canAfford(IEssentialsCommand cmd) throws Exception + { + canAfford(cmd.getName()); + } + + public void cancelTeleport(boolean notifyUser) + { + if (teleTimer == -1) return; + try + { + getServer().getScheduler().cancelTask(teleTimer); + if (notifyUser) sendMessage("§cPending teleportation request cancelled."); + } + catch (Throwable ex) + { + } + finally + { + teleTimer = -1; + } + } + + public void cancelTeleport() + { + cancelTeleport(false); + } + + public boolean teleport(final Location loc, final String chargeFor) + { + final long delay = Essentials.getSettings().getTeleportDelay(); + + if (delay <= 0 || isOp() || isAuthorized("essentials.teleport.timer.bypass")) + { + try + { + if (chargeFor != null) charge(chargeFor); + teleportCooldown(false); + return teleportToNow(loc); + } + catch (Throwable ex) + { + sendMessage("§cError: " + ex.getMessage()); + return false; + } + } + + cancelTeleport(); + sendMessage("§7Teleportation will commence in " + Essentials.FormatTime(delay) + ". Don't move."); + teleTimer = getServer().getScheduler().scheduleSyncRepeatingTask(Essentials.getStatic(), new TeleportTimer(this, delay) + { + public void DoTeleport() + { + try + { + if (chargeFor != null) charge(chargeFor); + teleportToNow(loc); + } + catch (Throwable ex) + { + sendMessage("§cError: " + ex.getMessage()); + } + } + + public void DoCancel() + { + cancelTeleport(); + } + }, 10, 10); + return true; + } + + @Override + public boolean teleport(final Location loc) + { + return teleport(loc, null); + } + + public boolean teleport(final Entity entity, final String chargeFor) + { + final long delay = Essentials.getSettings().getTeleportDelay(); + + if (delay <= 0 || isOp() || isAuthorized("essentials.teleport.timer.bypass")) + { + try + { + if (chargeFor != null) charge(chargeFor); + teleportCooldown(false); + return teleportToNow(entity); + } + catch (Throwable ex) + { + sendMessage("§cError: " + ex.getMessage()); + return false; + } + } + + cancelTeleport(); + sendMessage("§7Teleportation will commence in " + Essentials.FormatTime(delay) + ". Don't move."); + teleTimer = getServer().getScheduler().scheduleSyncRepeatingTask(Essentials.getStatic(), new TeleportTimer(this, delay) + { + public void DoTeleport() + { + try + { + if (chargeFor != null) charge(chargeFor); + teleportToNow(entity); + } + catch (Throwable ex) + { + sendMessage("§cError: " + ex.getMessage()); + } + } + + public void DoCancel() + { + cancelTeleport(); + } + }, 10, 10); + return true; + } + + @Override + public boolean teleport(final Entity entity) + { + return teleport(entity, null); + } + + public Location getHome() throws Exception + { + if (data.containsKey("home")) + { + List vals = (List)data.get("home"); + World world = getServer() == null ? null : getServer().getWorlds().get(0); + if (vals.size() > 5 && getServer() != null) + getServer().getWorld((String)vals.get(5)); + return new Location( + world, + (Double)vals.get(0), + (Double)vals.get(1), + (Double)vals.get(2), + ((Double)vals.get(3)).floatValue(), + ((Double)vals.get(4)).floatValue()); + } + + try + { + Map gdata = Essentials.getData(this); + List vals = (List)gdata.get("home"); + World world = getServer().getWorlds().get(0); + if (vals.size() > 5) + getServer().getWorld((String)vals.get(5)); + return new Location(world, + (Double)vals.get(0), + (Double)vals.get(1), + (Double)vals.get(2), + ((Double)vals.get(3)).floatValue(), + ((Double)vals.get(4)).floatValue()); + } + catch (Throwable ex) + { + throw new Exception("You have not set a home."); + } + } + + public void teleportToHome(final String chargeFor) + { + final long delay = Essentials.getSettings().getTeleportDelay(); + + Location loc = null; + try + { + // check this first in case user hasn't set a home yet + loc = getHome(); + } + catch (Throwable ex) + { + sendMessage("§cTeleport: " + ex.getMessage()); + return; + } + + if (delay <= 0 || isOp() || isAuthorized("essentials.teleport.timer.bypass")) + { + try + { + if (chargeFor != null) charge(chargeFor); + teleportCooldown(false); + teleportToNow(loc); + sendMessage("§7Teleporting home..."); + } + catch (Throwable ex) + { + sendMessage("§cError: " + ex.getMessage()); + } + return; + } + + cancelTeleport(); + sendMessage("§7Teleportation will commence in " + Essentials.FormatTime(delay) + ". Don't move."); + teleTimer = getServer().getScheduler().scheduleSyncRepeatingTask(Essentials.getStatic(), new TeleportTimer(this, delay) + { + public void DoTeleport() + { + try + { + if (chargeFor != null) charge(chargeFor); + teleportToNow(getHome()); + } + catch (Throwable ex) + { + sendMessage("§cError: " + ex.getMessage()); + } + } + + public void DoCancel() + { + cancelTeleport(); + } + }, 10, 10); + } + + public void teleportToHome() + { + teleportToHome(null); + } + + public boolean teleportToNow(Location loc) throws Exception + { + cancelTeleport(); + lastLocation = getLocation(); + return getBase().teleport(getSafeDestination(loc)); + } + + public boolean teleportToNow(Entity entity) + { + cancelTeleport(); + lastLocation = getLocation(); + return getBase().teleport(entity); + } + + public void teleportBack(final String chargeFor) + { + teleport(lastLocation, chargeFor); + } + + public void teleportBack() + { + teleportBack(null); + } + + public void dispose() + { + this.base = new OfflinePlayer(getName()); + } + + public void charge(IEssentialsCommand cmd) throws Exception + { + charge(cmd.getName()); + } + + public boolean getJustPortaled() + { + return justPortaled; + } + + public void setJustPortaled(boolean value) + { + justPortaled = value; + } + + public void setReplyTo(User user) + { + replyTo = user; + } + + public User getReplyTo() + { + return replyTo; + } + + public void setHome() + { + setHome(getLocation()); + } + + public void setHome(Location home) + { + List vals = new ArrayList(6); + vals.add(new Double(home.getX())); + vals.add(new Double(home.getY())); + vals.add(new Double(home.getZ())); + vals.add(new Double(home.getYaw())); + vals.add(new Double(home.getPitch())); + vals.add(home.getWorld() == null ? "world" : home.getWorld().getName()); + data.put("home", vals); + flush(); + + setCompassTarget(home); + } + + public String getNick() + { + Essentials ess = Essentials.getStatic(); + String name = ess.getConfiguration().getBoolean("disable-nick", false) ? getName() : ess.readNickname(this); + if (isOp() && ess.getConfiguration().getString("ops-name-color", "c").matches("^[0-9a-f]$")) { + name = "§" + ess.getConfiguration().getString("ops-name-color", "c") + name + "§f"; + } + return name; + } + + public void warpTo(String warp, final String chargeFor) throws Exception + { + lastLocation = getLocation(); + Location loc = Essentials.getWarps().getWarp(warp); + teleport(loc, chargeFor); + sendMessage("§7Warping to " + warp + "."); + } + + public void warpTo(String string) throws Exception + { + warpTo(string, null); + } + + public void clearNewFlag() + { + isNew = false; + } + + public int compareTo(User t) { + return ChatColor.stripColor(this.getDisplayName()).compareToIgnoreCase(ChatColor.stripColor(t.getDisplayName())); + } + + public Boolean canSpawnItem(int itemId) + { + if(Essentials.getSettings().itemSpawnBlacklist().contains(itemId))return false; + return true; + } +} diff --git a/Essentials/src/com/earth2me/essentials/Warps.java b/Essentials/src/com/earth2me/essentials/Warps.java new file mode 100644 index 000000000..beaeddf29 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/Warps.java @@ -0,0 +1,244 @@ +package com.earth2me.essentials; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.bukkit.Location; +import org.bukkit.Server; +import org.bukkit.World; + +public class Warps implements IConf { + + private static final Logger logger = Logger.getLogger("Minecraft"); + Map warpPoints = new HashMap(); + File warpsFolder; + Server server; + + public Warps(Server server, File dataFolder) { + this.server = server; + warpsFolder = new File(dataFolder, "warps"); + if (!warpsFolder.exists()) { + warpsFolder.mkdirs(); + } else { + convertWarps(dataFolder); + } + reloadConfig(); + } + + private String convertToFileName(String name) { + return name.toLowerCase().replaceAll("[^a-z0-9]", "_"); + } + + public boolean isEmpty() { + return warpPoints.isEmpty(); + } + + public Iterable getWarpNames() { + List keys = new ArrayList(); + for (StringIgnoreCase stringIgnoreCase : warpPoints.keySet()) { + keys.add(stringIgnoreCase.string); + } + Collections.sort(keys, String.CASE_INSENSITIVE_ORDER); + return keys; + } + + public Location getWarp(String warp) throws Exception { + EssentialsConf conf = warpPoints.get(new StringIgnoreCase(warp)); + if (conf == null) { + throw new Exception("That warp does not exist."); + } + double x = conf.getDouble("x", 0); + double y = conf.getDouble("y", 0); + double z = conf.getDouble("z", 0); + float yaw = (float) conf.getDouble("yaw", 0); + float pitch = (float) conf.getDouble("pitch", 0); + String world = conf.getString("world"); + World w = server.getWorld(world); + if (w == null) { + throw new Exception("World of warp does not exist."); + } + return new Location(w, x, y, z, yaw, pitch); + } + + public void setWarp(String name, Location loc) throws Exception { + setWarp(name, loc, null); + } + + private void setWarp(String name, Location loc, String worldName) throws Exception { + String filename = convertToFileName(name); + EssentialsConf conf = warpPoints.get(new StringIgnoreCase(name)); + if (conf == null) { + File confFile = new File(warpsFolder, filename + ".yml"); + if (confFile.exists()) { + throw new Exception("A warp with a similar name already exists."); + } + conf = new EssentialsConf(confFile); + conf.setProperty("name", name); + warpPoints.put(new StringIgnoreCase(name), conf); + } + conf.setProperty("x", loc.getBlockX()); + conf.setProperty("y", loc.getBlockY()); + conf.setProperty("z", loc.getBlockZ()); + conf.setProperty("yaw", loc.getYaw()); + conf.setProperty("pitch", loc.getPitch()); + if (worldName != null) { + conf.setProperty("world", worldName); + } else { + conf.setProperty("world", loc.getWorld().getName()); + } + conf.save(); + } + + public void delWarp(String name) throws Exception { + EssentialsConf conf = warpPoints.get(new StringIgnoreCase(name)); + if (conf == null) { + throw new Exception("Warp does not exist."); + } + if (!conf.getFile().delete()) { + throw new Exception("Problem deleting the warp file."); + } + warpPoints.remove(new StringIgnoreCase(name)); + } + + private void convertWarps(File dataFolder) { + File[] listOfFiles = warpsFolder.listFiles(); + if (listOfFiles.length >= 1) { + for (int i = 0; i < listOfFiles.length; i++) { + String filename = listOfFiles[i].getName(); + if (listOfFiles[i].isFile() && filename.endsWith(".dat")) { + try { + BufferedReader rx = new BufferedReader(new FileReader(listOfFiles[i])); + double x = Double.parseDouble(rx.readLine().trim()); + double y = Double.parseDouble(rx.readLine().trim()); + double z = Double.parseDouble(rx.readLine().trim()); + float yaw = Float.parseFloat(rx.readLine().trim()); + float pitch = Float.parseFloat(rx.readLine().trim()); + String worldName = rx.readLine(); + rx.close(); + World w = null; + for (World world : server.getWorlds()) { + if (world.getEnvironment() != World.Environment.NETHER) { + w = world; + break; + } + } + boolean forceWorldName = false; + if (worldName != null) { + worldName.trim(); + World w1 = null; + for (World world : server.getWorlds()) { + if (world.getName().equalsIgnoreCase(worldName)) { + w1 = world; + break; + } + } + if (w1 != null) { + w = w1; + } else { + File worldFolder = new File(dataFolder.getAbsoluteFile().getParentFile().getParentFile(), worldName); + if (worldFolder.exists() && worldFolder.isDirectory()) { + logger.log(Level.WARNING, "World " + worldName + " not loaded, but directory found. Converting warp anyway."); + forceWorldName = true; + } + } + } + Location loc = new Location(w, x, y, z, yaw, pitch); + setWarp(filename.substring(0, filename.length() - 4), loc, forceWorldName ? worldName : null); + if(!listOfFiles[i].renameTo(new File(warpsFolder, filename + ".old"))) + { + throw new Exception("Renaming file " + filename + " failed"); + } + } catch (Exception ex) { + logger.log(Level.SEVERE, null, ex); + } + } + } + + } + File warpFile = new File(dataFolder, "warps.txt"); + if (warpFile.exists()) { + try { + BufferedReader rx = new BufferedReader(new FileReader(warpFile)); + for (String[] parts = new String[0]; rx.ready(); parts = rx.readLine().split(":")) { + if (parts.length < 6) { + continue; + } + String name = parts[0]; + double x = Double.parseDouble(parts[1].trim()); + double y = Double.parseDouble(parts[2].trim()); + double z = Double.parseDouble(parts[3].trim()); + float yaw = Float.parseFloat(parts[4].trim()); + float pitch = Float.parseFloat(parts[5].trim()); + if (name.isEmpty()) { + continue; + } + World w = null; + for (World world : server.getWorlds()) { + if (world.getEnvironment() != World.Environment.NETHER) { + w = world; + break; + } + } + Location loc = new Location(w, x, y, z, yaw, pitch); + setWarp(name, loc); + if(!warpFile.renameTo(new File(dataFolder, "warps.txt.old"))); + { + throw new Exception("Renaming warps.txt failed"); + } + } + } catch (Exception ex) { + logger.log(Level.SEVERE, null, ex); + } + } + } + + public final void reloadConfig() { + warpPoints.clear(); + File[] listOfFiles = warpsFolder.listFiles(); + if (listOfFiles.length >= 1) { + for (int i = 0; i < listOfFiles.length; i++) { + String filename = listOfFiles[i].getName(); + if (listOfFiles[i].isFile() && filename.endsWith(".yml")) { + EssentialsConf conf = new EssentialsConf(listOfFiles[i]); + conf.load(); + String name = conf.getString("name"); + if (name != null) { + warpPoints.put(new StringIgnoreCase(name), conf); + } + } + } + } + } + + private class StringIgnoreCase { + + String string; + + public StringIgnoreCase(String string) { + this.string = string; + } + + @Override + public int hashCode() { + return string.toLowerCase().hashCode(); + } + + @Override + public boolean equals(Object o) { + if (o instanceof String) { + return string.equalsIgnoreCase((String) o); + } + if (o instanceof StringIgnoreCase) { + return string.equalsIgnoreCase(((StringIgnoreCase) o).string); + } + return false; + } + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandafk.java b/Essentials/src/com/earth2me/essentials/commands/Commandafk.java new file mode 100644 index 000000000..eb1ade4cd --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandafk.java @@ -0,0 +1,32 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commandafk extends EssentialsCommand +{ + public Commandafk() + { + super("afk"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + user.charge(this); + + if (parent.away.contains(user)) + { + user.sendMessage("§7You are no longer marked as away."); + server.broadcastMessage("§7" + user.getDisplayName() + " is no longer AFK"); + parent.away.remove(user); + return; + } + + user.sendMessage("§7You are now marked as away."); + server.broadcastMessage("§7" + user.getDisplayName() + " is now AFK"); + parent.away.add(user); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandantioch.java b/Essentials/src/com/earth2me/essentials/commands/Commandantioch.java new file mode 100644 index 000000000..9e234ea15 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandantioch.java @@ -0,0 +1,39 @@ +package com.earth2me.essentials.commands; + +import net.minecraft.server.EntityTNTPrimed; +import net.minecraft.server.World; +import org.bukkit.Location; +import org.bukkit.Server; +import org.bukkit.craftbukkit.CraftWorld; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import com.earth2me.essentials.TargetBlock; + + +public class Commandantioch extends EssentialsCommand +{ + public Commandantioch() + { + super("antioch"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + if (!user.isOp()) + { + user.sendMessage("§cNone shall pass."); + return; + } + + server.broadcastMessage("...lobbest thou thy Holy Hand Grenade of Antioch towards thy foe,"); + server.broadcastMessage("who being naughty in My sight, shall snuff it."); + + Location loc = user.getLocation(); + World world = ((CraftWorld)user.getWorld()).getHandle(); + loc = new TargetBlock(user).getTargetBlock().getLocation(); + EntityTNTPrimed tnt = new EntityTNTPrimed(world, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + world.a(tnt); + world.a(tnt, "random.fuse", 1.0F, 1.0F); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandback.java b/Essentials/src/com/earth2me/essentials/commands/Commandback.java new file mode 100644 index 000000000..03ceba9b6 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandback.java @@ -0,0 +1,22 @@ +package com.earth2me.essentials.commands; + +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import org.bukkit.Server; + + +public class Commandback extends EssentialsCommand +{ + public Commandback() + { + super("back"); + } + + @Override + protected void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + user.canAfford(this); + user.sendMessage("§7Returning to previous location."); + user.teleportBack(this.getName()); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandbackup.java b/Essentials/src/com/earth2me/essentials/commands/Commandbackup.java new file mode 100644 index 000000000..7682cd141 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandbackup.java @@ -0,0 +1,43 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.earth2me.essentials.commands; + +import com.earth2me.essentials.Backup; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import org.bukkit.Server; +import org.bukkit.command.CommandSender; + +/** + * + * @author schlex + */ +public class Commandbackup extends EssentialsCommand { + + public Commandbackup() { + super("backup"); + } + + @Override + protected void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception { + Backup backup = Essentials.getStatic().backup; + if (backup == null) return; + backup.run(); + } + + @Override + protected void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception { + Backup backup = Essentials.getStatic().backup; + if (backup == null) return; + user.charge(this); + backup.run(); + user.sendMessage("Backup started"); + } + + + + +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandbalance.java b/Essentials/src/com/earth2me/essentials/commands/Commandbalance.java new file mode 100644 index 000000000..6789af570 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandbalance.java @@ -0,0 +1,23 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import com.earth2me.essentials.commands.EssentialsCommand; + + +public class Commandbalance extends EssentialsCommand +{ + public Commandbalance() + { + super("balance"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + user.sendMessage("§7Balance: $" + (args.length < 1 || !user.isAuthorized("essentials.balance.other") + ? user + : getPlayer(server, args, 0)).getMoney()); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandban.java b/Essentials/src/com/earth2me/essentials/commands/Commandban.java new file mode 100644 index 000000000..c341d4645 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandban.java @@ -0,0 +1,42 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import org.bukkit.craftbukkit.CraftServer; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commandban extends EssentialsCommand +{ + public Commandban() + { + super("ban"); + } + + @Override + public void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + sender.sendMessage("§cUsage: /" + commandLabel + " [player] "); + return; + } + + + User p = null; + if (server.matchPlayer(args[0]).isEmpty()) + { + ((CraftServer)server).getHandle().c.f.a(args[0]); + sender.sendMessage("§cPlayer" + args[0] + " banned"); + } + else + { + p = User.get(server.matchPlayer(args[0]).get(0)); + p.kickPlayer(args.length > 1 ? getFinalArg(args, 1) : "Banned from server"); + ((CraftServer)server).getHandle().c.f.a(p.getName()); + sender.sendMessage("§cPlayer" + p.getName() + " banned"); + } + Essentials.getStatic().loadBanList(); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandbanip.java b/Essentials/src/com/earth2me/essentials/commands/Commandbanip.java new file mode 100644 index 000000000..080bfa663 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandbanip.java @@ -0,0 +1,30 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import org.bukkit.craftbukkit.CraftServer; +import com.earth2me.essentials.Essentials; + + +public class Commandbanip extends EssentialsCommand +{ + public Commandbanip() + { + super("banip"); + } + + @Override + public void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + sender.sendMessage("Usage: /" + commandLabel + " [address]"); + return; + } + + ((CraftServer)server).getHandle().c.f.c(args[0]); + sender.sendMessage("§7Banned IP address."); + Essentials.getStatic().loadBanList(); + + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandbigtree.java b/Essentials/src/com/earth2me/essentials/commands/Commandbigtree.java new file mode 100644 index 000000000..a7546bb35 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandbigtree.java @@ -0,0 +1,56 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import org.bukkit.TreeType; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import org.bukkit.Location; + + +public class Commandbigtree extends EssentialsCommand +{ + public Commandbigtree() + { + super("bigtree"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + Object tree = new Object(); + if (args.length > 0 && args[0].equalsIgnoreCase("redwood")) + { + tree = TreeType.TALL_REDWOOD; + } + else if (args.length > 0 && args[0].equalsIgnoreCase("tree")) + { + tree = TreeType.BIG_TREE; + } + else + { + user.sendMessage("§cUsage: /" + commandLabel + " [tree|redwood]"); + return; + } + + double x = user.getLocation().getX(); + double y = user.getLocation().getY(); + double z = user.getLocation().getZ(); + + // offset tree in direction player is facing + int r = (int)user.getCorrectedYaw(); + if (r < 68 || r > 292) x -= 3.0D; // north + else if (r > 112 && r < 248) x += 3.0D; // south + if (r > 22 && r < 158) z -= 3.0D; // east + else if (r > 202 && r < 338) z += 3.0D; // west + + Location safeLocation = user.getSafeDestination(new Location(user.getWorld(), x, y, z)); + boolean success = user.getWorld().generateTree(safeLocation, (TreeType)tree); + if (success) + { + user.charge(this); + user.sendMessage("Big tree spawned."); + } + else + user.sendMessage("§cBig tree generation failure. Try again on grass or dirt."); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandbroadcast.java b/Essentials/src/com/earth2me/essentials/commands/Commandbroadcast.java new file mode 100644 index 000000000..2069e61b9 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandbroadcast.java @@ -0,0 +1,32 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commandbroadcast extends EssentialsCommand +{ + public Commandbroadcast() + { + super("broadcast"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + user.sendMessage("Usage: /" + commandLabel + " [msg]"); + } + + StringBuilder message = new StringBuilder(); + for (int i = 0; i < args.length; i++) + { + message.append(args[i]); + message.append(' '); + } + + server.broadcastMessage("[§cBroadcast§f]§a " + message.toString()); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandburn.java b/Essentials/src/com/earth2me/essentials/commands/Commandburn.java new file mode 100644 index 000000000..0c190a0f2 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandburn.java @@ -0,0 +1,32 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import org.bukkit.entity.Player; + +public class Commandburn extends EssentialsCommand +{ + + public Commandburn() + { + super("burn"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + if (args.length < 2) + { + user.sendMessage("§cUsage: /burn [player] [seconds]"); + return; + } + + User.charge(user, this); + for (Player p : server.matchPlayer(args[0])) + { + p.setFireTicks(Integer.parseInt(args[1]) * 20); + user.sendMessage("§cYou set " + p.getDisplayName() + " on fire for " + Integer.parseInt(args[1]) + "seconds."); + } + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandclearinventory.java b/Essentials/src/com/earth2me/essentials/commands/Commandclearinventory.java new file mode 100644 index 000000000..de5c11376 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandclearinventory.java @@ -0,0 +1,99 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import com.earth2me.essentials.User; +import java.util.List; +import org.bukkit.ChatColor; + + +public class Commandclearinventory extends EssentialsCommand +{ + public Commandclearinventory() + { + super("clearinventory"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + if (args.length > 0 && user.isAuthorized("essentials.clearinventory.others")) + { + if (args[0].length() >= 3) + { + List online = server.matchPlayer(args[0]); + + if (!online.isEmpty()) + { + for (Player p : online) + { + p.getInventory().clear(); + user.sendMessage("§7Inventory of §c" + p.getDisplayName() + "§7 cleared."); + user.charge(this); + } + } + throw new Exception("Player not found"); + } + else + { + Player u = server.getPlayer(args[0]); + if (u != null) + { + u.getInventory().clear(); + user.sendMessage("§7Inventory of §c" + u.getDisplayName() + "§7 cleared."); + user.charge(this); + } + else + { + throw new Exception("Player not found"); + } + } + } + else + { + user.getInventory().clear(); + user.sendMessage("§7Inventory cleared."); + user.charge(this); + } + } + + @Override + protected void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + sender.sendMessage(ChatColor.RED + "Usage: " + commandLabel + " [player]"); + return; + } + + if (args[0].length() >= 3) + { + List online = server.matchPlayer(args[0]); + + if (!online.isEmpty()) + { + for (Player p : online) + { + p.getInventory().clear(); + sender.sendMessage("§7Inventory of §c" + p.getDisplayName() + "§7 cleared."); + } + } + throw new Exception("Player not found"); + } + else + { + Player u = server.getPlayer(args[0]); + if (u != null) + { + u.getInventory().clear(); + sender.sendMessage("§7Inventory of §c" + u.getDisplayName() + "§7 cleared."); + } + else + { + throw new Exception("Player not found"); + } + } + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandcompass.java b/Essentials/src/com/earth2me/essentials/commands/Commandcompass.java new file mode 100644 index 000000000..f891f0bab --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandcompass.java @@ -0,0 +1,32 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commandcompass extends EssentialsCommand +{ + public Commandcompass() + { + super("compass"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + user.charge(this); + int r = (int)user.getCorrectedYaw(); + String dir; + if (r < 23) dir = "N"; + else if (r < 68) dir = "NE"; + else if (r < 113) dir = "E"; + else if (r < 158) dir = "SE"; + else if (r < 203) dir = "S"; + else if (r < 248) dir = "SW"; + else if (r < 293) dir = "W"; + else if (r < 338) dir = "NW"; + else dir = "N"; + user.sendMessage("§7Bearing: " + dir + " (" + r + " degrees)"); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commanddeljail.java b/Essentials/src/com/earth2me/essentials/commands/Commanddeljail.java new file mode 100644 index 000000000..620db000c --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commanddeljail.java @@ -0,0 +1,33 @@ +package com.earth2me.essentials.commands; + +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import org.bukkit.Server; +import org.bukkit.command.CommandSender; + +public class Commanddeljail extends EssentialsCommand { + + public Commanddeljail() { + super("deljail"); + } + + @Override + protected void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception { + if (args.length < 1) + { + user.sendMessage("§cUsage: /" + commandLabel + " [jailname]"); + return; + } + user.charge(this); + Essentials.getJail().delJail(args[0]); + user.sendMessage("§7Jail " + args[0] + " has been removed"); + } + + @Override + protected void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception { + super.run(server, parent, sender, commandLabel, args); + } + + + +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commanddelwarp.java b/Essentials/src/com/earth2me/essentials/commands/Commanddelwarp.java new file mode 100644 index 000000000..a9811fb8e --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commanddelwarp.java @@ -0,0 +1,41 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commanddelwarp extends EssentialsCommand +{ + public Commanddelwarp() + { + super("delwarp"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + user.sendMessage("§cUsage: /" + commandLabel + " [warp name]"); + return; + } + user.charge(this); + Essentials.getWarps().delWarp(args[0]); + user.sendMessage("§7Warp removed."); + } + + @Override + public void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + sender.sendMessage("§cUsage: /" + commandLabel + " [warp name]"); + return; + } + + Essentials.getWarps().delWarp(args[0]); + sender.sendMessage("§7Warp removed."); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commanddepth.java b/Essentials/src/com/earth2me/essentials/commands/Commanddepth.java new file mode 100644 index 000000000..d01594809 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commanddepth.java @@ -0,0 +1,24 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commanddepth extends EssentialsCommand +{ + public Commanddepth() + { + super("depth"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + user.charge(this); + int y = user.getLocation().getBlockY() - 63; + if (y > 0) user.sendMessage("§7You are " + y + " block(s) above sea level."); + else if (y < 0) user.sendMessage("§7You are " + (-y) + " block(s) below sea level."); + else user.sendMessage("§7You are at sea level."); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandeco.java b/Essentials/src/com/earth2me/essentials/commands/Commandeco.java new file mode 100644 index 000000000..79a55f986 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandeco.java @@ -0,0 +1,82 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import com.earth2me.essentials.Essentials; +import org.bukkit.entity.Player; +import com.earth2me.essentials.User; + + +public class Commandeco extends EssentialsCommand +{ + public Commandeco() + { + super("eco"); + } + + @Override + public void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception + { + EcoCommands cmd; + int amount; + try + { + cmd = EcoCommands.valueOf(args[0].toUpperCase()); + amount = Integer.parseInt(args[2].replaceAll("[^0-9]", "")); + } + catch (Exception ex) + { + sender.sendMessage("§cUsage: /eco [give|take|reset] [player] [money]"); + return; + } + + if (args[1].contentEquals("*")) + { + for (Player p : server.getOnlinePlayers()) + { + User u = User.get(p); + switch (cmd) + { + case GIVE: + u.giveMoney(amount); + break; + + case TAKE: + u.takeMoney(amount); + break; + + case RESET: + u.setMoney(amount == 0 ? Essentials.getSettings().getStartingBalance() : amount); + break; + } + } + } + else + { + for (Player p : server.matchPlayer(args[1])) + { + User u = User.get(p); + switch (cmd) + { + case GIVE: + u.giveMoney(amount); + break; + + case TAKE: + u.takeMoney(amount); + break; + + case RESET: + u.setMoney(amount == 0 ? Essentials.getSettings().getStartingBalance() : amount); + break; + } + } + } + } + + + private enum EcoCommands + { + GIVE, TAKE, RESET + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandessentials.java b/Essentials/src/com/earth2me/essentials/commands/Commandessentials.java new file mode 100644 index 000000000..d4cc4038d --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandessentials.java @@ -0,0 +1,30 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commandessentials extends EssentialsCommand +{ + public Commandessentials() + { + super("essentials"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + parent.reload(); + user.charge(this); + user.sendMessage("§7Essentials Reloaded " + parent.getDescription().getVersion()); + } + + @Override + public void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception + { + parent.reload(); + sender.sendMessage("Essentials Reloaded " + parent.getDescription().getVersion()); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandext.java b/Essentials/src/com/earth2me/essentials/commands/Commandext.java new file mode 100644 index 000000000..1313ba5b9 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandext.java @@ -0,0 +1,29 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import org.bukkit.entity.Player; + +public class Commandext extends EssentialsCommand { + + public Commandext() { + super("ext"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception { + if (args.length < 1) { + User.charge(user, this); + user.setFireTicks(0); + user.sendMessage("§7You extinguished yourself."); + return; + } + + for (Player p : server.matchPlayer(args[0])) { + User.charge(user, this); + p.setFireTicks(0); + user.sendMessage("§7You extinguished " + p.getDisplayName() + "."); + } + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandgc.java b/Essentials/src/com/earth2me/essentials/commands/Commandgc.java new file mode 100644 index 000000000..08640e15b --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandgc.java @@ -0,0 +1,29 @@ +package com.earth2me.essentials.commands; + +import com.earth2me.essentials.Essentials; +import org.bukkit.Server; +import org.bukkit.World; +import org.bukkit.command.CommandSender; + + +public class Commandgc extends EssentialsCommand +{ + public Commandgc() + { + super("gc"); + } + + @Override + protected void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception + { + sender.sendMessage("Maximum memory: " + (Runtime.getRuntime().maxMemory() / 1024 / 1024) + " MB"); + sender.sendMessage("Free memory: " + (Runtime.getRuntime().freeMemory() / 1024 / 1024) + " MB"); + for (World w : parent.getServer().getWorlds()) + { + sender.sendMessage( + (w.getEnvironment() == World.Environment.NETHER ? "Nether" : "World") + " \"" + w.getName() + "\": " + + w.getLoadedChunks().length + " chunks, " + + w.getEntities().size() + " entities"); + } + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandgetpos.java b/Essentials/src/com/earth2me/essentials/commands/Commandgetpos.java new file mode 100644 index 000000000..39be2c524 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandgetpos.java @@ -0,0 +1,33 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Location; +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commandgetpos extends EssentialsCommand +{ + public Commandgetpos() + { + super("getpos"); + } + + @Override + public String[] getTriggers() + { + return new String[] { getName(), "coords" }; + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + user.charge(this); + Location coords = user.getLocation(); + user.sendMessage("§7X: " + coords.getBlockX() + " (-North <-> +South)"); + user.sendMessage("§7Y: " + coords.getBlockY() + " (+Up <-> -Down)"); + user.sendMessage("§7Z: " + coords.getBlockZ() + " (+East <-> -West)"); + user.sendMessage("§7Yaw: " + user.getCorrectedYaw() + " (Rotation)"); + user.sendMessage("§7Pitch: " + coords.getPitch() + " (Head angle)"); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandgive.java b/Essentials/src/com/earth2me/essentials/commands/Commandgive.java new file mode 100644 index 000000000..559fc5c32 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandgive.java @@ -0,0 +1,49 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.ItemDb; +import com.earth2me.essentials.User; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + + +public class Commandgive extends EssentialsCommand +{ + public Commandgive() + { + super("give"); + } + + @Override + public void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception + { + if (args.length < 2) + { + sender.sendMessage(ChatColor.RED + "Usage: /" + commandLabel + " [player] [item]<:data> "); + return; + } + + String[] itemArgs = args[1].split("[^a-zA-Z0-9]"); + ItemStack stack = ItemDb.get(itemArgs[0]); + + if(sender instanceof Player && !User.get(sender).isAuthorized("essentials.itemspawn.exempt") && !User.get(sender).canSpawnItem(stack.getTypeId())) + { + sender.sendMessage(ChatColor.RED + "You are not allowed to spawn that item"); + return; + } + if (itemArgs.length > 1) + stack.setDurability(Short.parseShort(itemArgs[1])); + if (args.length > 2) + stack.setAmount(Integer.parseInt(args[2])); + + User giveTo = getPlayer(server, args, 0); + String itemName = stack.getType().name().toLowerCase().replace('_', ' '); + if (sender instanceof Player) + User.get(sender).charge(this); + sender.sendMessage(ChatColor.BLUE + "Giving " + stack.getAmount() + " of " + itemName + " to " + giveTo.getDisplayName() + "."); + giveTo.getInventory().addItem(stack); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandgod.java b/Essentials/src/com/earth2me/essentials/commands/Commandgod.java new file mode 100644 index 000000000..700be8c88 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandgod.java @@ -0,0 +1,32 @@ +package com.earth2me.essentials.commands; + +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import org.bukkit.Server; +import org.bukkit.entity.Player; + + +public class Commandgod extends EssentialsCommand +{ + public Commandgod() + { + super("god"); + } + + @Override + protected void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + if (args.length > 0 && (user.isAuthorized("essentials.god.others") || user.isOp())) + { + for (Player p : server.matchPlayer(args[0])) + { + User u = User.get(p); + boolean enabled = u.toggleGodMode(); + u.sendMessage("§7God mode " + (enabled ? "enabled." : "disabled.")); + user.sendMessage("§7God mode " + (enabled ? "enabled for " : "disabled for ") + p.getDisplayName() + "."); + } + return; + } + user.sendMessage("§7God mode " + (user.toggleGodMode() ? "enabled." : "disabled.")); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandheal.java b/Essentials/src/com/earth2me/essentials/commands/Commandheal.java new file mode 100644 index 000000000..ddadda860 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandheal.java @@ -0,0 +1,53 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import com.earth2me.essentials.Essentials; +import org.bukkit.entity.Player; +import com.earth2me.essentials.User; + + +public class Commandheal extends EssentialsCommand +{ + public Commandheal() + { + super("heal"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + if (args.length > 0 && user.isAuthorized("essentials.heal.others")) + { + if (!user.isAuthorized("essentials.heal.cooldown.bypass")) user.healCooldown(); + user.charge(this); + for (Player p : server.matchPlayer(args[0])) + { + p.setHealth(20); + user.sendMessage("§7Healed " + p.getDisplayName() + "."); + } + return; + } + + if (!user.isAuthorized("essentials.heal.cooldown.bypass")) user.healCooldown(); + user.charge(this); + user.setHealth(20); + user.sendMessage("§7You have been healed."); + } + + @Override + public void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + sender.sendMessage("Usage: /" + commandLabel + " [player]"); + return; + } + + for (Player p : server.matchPlayer(args[0])) + { + p.setHealth(20); + sender.sendMessage("Healed " + p.getDisplayName() + "."); + } + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandhelp.java b/Essentials/src/com/earth2me/essentials/commands/Commandhelp.java new file mode 100644 index 000000000..1468cced5 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandhelp.java @@ -0,0 +1,129 @@ +package com.earth2me.essentials.commands; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginDescriptionFile; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.SafeConstructor; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commandhelp extends EssentialsCommand +{ + public final Yaml yaml = new Yaml(new SafeConstructor()); + + public Commandhelp() + { + super("help"); + } + + @Override + protected void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + int page; + try + { + page = args.length > 0 ? Integer.parseInt(args[0]) : 1; + } + catch (Exception ex) + { + page = 1; + } + + List lines = getHelpLines(parent, user); + int start = (page - 1) * 9; + int pages = lines.size() / 9 + (lines.size() % 9 > 0 ? 1 : 0); + + user.sendMessage("Page §c" + page + "§f of §c" + pages + "§f:"); + for (int i = start; i < lines.size() && i < start + 9; i++) + { + user.sendMessage(lines.get(i)); + } + } + + @Override + protected void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception + { + sender.sendMessage("To view help from the console, type \"?\"."); + } + + @SuppressWarnings("CallToThreadDumpStack") + private List getHelpLines(Essentials parent, User user) throws Exception + { + List retval = new ArrayList(); + File file = new File(parent.getDataFolder(), "help.txt"); + if (file.exists()) + { + BufferedReader rx = new BufferedReader(new FileReader(file)); + for (String l = null; rx.ready() && (l = rx.readLine()) != null;) + { + retval.add(l.replace('&', '§')); + } + return retval; + } + + boolean reported = false; + for (Plugin p : parent.getServer().getPluginManager().getPlugins()) + { + try + { + PluginDescriptionFile desc = p.getDescription(); + HashMap> cmds = (HashMap>)desc.getCommands(); + for (String k : cmds.keySet()) + { + if (p.getDescription().getName().toLowerCase().contains("essentials")) + { + String node = "essentials." + k; + if (!Essentials.getSettings().isCommandDisabled(k) && user.isAuthorized(node)) + { + HashMap v = cmds.get(k); + retval.add("§c" + k + "§7: " + v.get("description")); + } + } + else + { + if (Essentials.getSettings().showNonEssCommandsInHelp()) + { + HashMap v = cmds.get(k); + if (v.containsKey("permission") && v.get("permission") != null && !(v.get("permission").equals(""))) + { + if (user.isAuthorized(v.get("permission"))) + { + retval.add("§c" + k + "§7: " + v.get("description")); + } + } + else + { + retval.add("§c" + k + "§7: " + v.get("description")); + } + } + + } + } + } + catch (NullPointerException ex) + { + + continue; + } + catch (Exception ex) + { + if (!reported) + { + ex.printStackTrace(); + } + reported = true; + continue; + } + } + return retval; + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandhelpop.java b/Essentials/src/com/earth2me/essentials/commands/Commandhelpop.java new file mode 100644 index 000000000..03dbad50e --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandhelpop.java @@ -0,0 +1,33 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import org.bukkit.entity.Player; +import com.earth2me.essentials.User; + + +public class Commandhelpop extends EssentialsCommand +{ + public Commandhelpop() + { + super("helpop"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + user.sendMessage("§cTo request help from an op, type §f/" + commandLabel+ "§c, followed by your question."); + return; + } + + user.charge(this); + for (Player p : server.getOnlinePlayers()) + { + User u = User.get(p); + if (!u.isOp() && !u.isAuthorized("essentials.helpop.receive")) continue; + u.sendMessage("§c[HelpOp]§f §7" + user.getDisplayName() + ":§f " + getFinalArg(args, 0)); + } + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandhome.java b/Essentials/src/com/earth2me/essentials/commands/Commandhome.java new file mode 100644 index 000000000..0dc92d25a --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandhome.java @@ -0,0 +1,21 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + +public class Commandhome extends EssentialsCommand +{ + public Commandhome() + { + super("home"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + user.canAfford(this); + user.teleportCooldown(); + user.teleportToHome(this.getName()); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandinvsee.java b/Essentials/src/com/earth2me/essentials/commands/Commandinvsee.java new file mode 100644 index 000000000..2e7ec407a --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandinvsee.java @@ -0,0 +1,39 @@ +package com.earth2me.essentials.commands; + +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import org.bukkit.Server; +import org.bukkit.craftbukkit.inventory.CraftInventory; + +public class Commandinvsee extends EssentialsCommand { + + public Commandinvsee() { + super("invsee"); + } + + @Override + protected void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception { + + if (args.length == 0 && user.savedInventory == null) { + user.sendMessage("§cUsage: /" + commandLabel + " "); + } + User invUser = user; + if (args.length == 1) { + invUser = getPlayer(server, args, 0); + } + if (invUser == user && user.savedInventory != null) { + ((CraftInventory)invUser.getInventory()).setContents(user.savedInventory); + user.savedInventory = null; + user.sendMessage("Your inventory has been restored."); + return; + } + + user.charge(this); + if (user.savedInventory == null) { + user.savedInventory = ((CraftInventory)user.getInventory()).getContents(); + } + ((CraftInventory)user.getInventory()).setContents(((CraftInventory)invUser.getInventory()).getContents()); + user.sendMessage("You see the inventory of "+invUser.getDisplayName()+"."); + user.sendMessage("Use /invsee to restore your inventory."); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commanditem.java b/Essentials/src/com/earth2me/essentials/commands/Commanditem.java new file mode 100644 index 000000000..97d1d2218 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commanditem.java @@ -0,0 +1,45 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.ItemDb; +import com.earth2me.essentials.User; +import org.bukkit.ChatColor; +import org.bukkit.inventory.ItemStack; + + +public class Commanditem extends EssentialsCommand +{ + public Commanditem() + { + super("item"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + user.sendMessage("§cUsage: /" + commandLabel + " [item] "); + return; + } + String[] itemArgs = args[0].split("[^a-zA-Z0-9]"); + ItemStack stack = ItemDb.get(itemArgs[0]); + + if(!user.isAuthorized("essentials.itemspawn.exempt") && !user.canSpawnItem(stack.getTypeId())) + { + user.sendMessage(ChatColor.RED + "You are not allowed to spawn that item"); + return; + } + if (itemArgs.length > 1) + stack.setDurability(Short.parseShort(itemArgs[1])); + + if (args.length > 1) + stack.setAmount(Integer.parseInt(args[1])); + + String itemName = stack.getType().name().toLowerCase().replace('_', ' '); + user.charge(this); + user.sendMessage("§7Giving " + stack.getAmount() + " of " + itemName + " to " + user.getDisplayName() + "."); + user.getInventory().addItem(stack); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandjails.java b/Essentials/src/com/earth2me/essentials/commands/Commandjails.java new file mode 100644 index 000000000..75018eb19 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandjails.java @@ -0,0 +1,37 @@ +package com.earth2me.essentials.commands; + +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import org.bukkit.Server; +import org.bukkit.command.CommandSender; + +public class Commandjails extends EssentialsCommand { + + public Commandjails() { + super("jails"); + } + + @Override + protected void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception { + StringBuilder jailList = new StringBuilder(); + for (String j : Essentials.getJail().getJails()) + { + jailList.append(j); + jailList.append(' '); + } + sender.sendMessage("§7" + jailList); + } + + @Override + protected void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception { + StringBuilder jailList = new StringBuilder(); + for (String j : Essentials.getJail().getJails()) + { + jailList.append(j); + jailList.append(' '); + } + user.sendMessage("§7" + jailList); + } + + +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandjump.java b/Essentials/src/com/earth2me/essentials/commands/Commandjump.java new file mode 100644 index 000000000..b753fc4b3 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandjump.java @@ -0,0 +1,50 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Location; +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.TargetBlock; +import com.earth2me.essentials.User; + + +public class Commandjump extends EssentialsCommand +{ + public Commandjump() + { + super("jump"); + } + + @Override + public String[] getTriggers() + { + return new String[] + { + getName(), "j" + }; + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + Location loc; + Location cloc = user.getLocation(); + + try + { + loc = new TargetBlock(user, 100, 2.65).getTargetBlock().getLocation(); + loc.setYaw(cloc.getYaw()); + loc.setPitch(cloc.getPitch()); + loc = new TargetBlock(loc).getPreviousBlock().getLocation(); + loc.setYaw(cloc.getYaw()); + loc.setPitch(cloc.getPitch()); + loc.setY(loc.getY() + 1); + } + catch (NullPointerException ex) + { + throw new Exception("That would hurt your computer's brain.", ex); + } + + user.canAfford(this); + user.teleport(loc, this.getName()); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandkick.java b/Essentials/src/com/earth2me/essentials/commands/Commandkick.java new file mode 100644 index 000000000..ddf5de5f5 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandkick.java @@ -0,0 +1,41 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import org.bukkit.ChatColor; + + +public class Commandkick extends EssentialsCommand +{ + public Commandkick() + { + super("kick"); + } + + @Override + public void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + sender.sendMessage(ChatColor.RED + "Usage: /" + commandLabel + " [player] "); + return; + } + + User p; + try + { + p = User.get(server.matchPlayer(args[0]).get(0)); + } + catch (Throwable ex) + { + sender.sendMessage(ChatColor.RED + "That player does not exist!"); + return; + } + + charge(sender); + p.kickPlayer(args.length > 1 ? getFinalArg(args, 1) : "Kicked from server"); + + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandkickall.java b/Essentials/src/com/earth2me/essentials/commands/Commandkickall.java new file mode 100644 index 000000000..e73f57a00 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandkickall.java @@ -0,0 +1,55 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + +public class Commandkickall extends EssentialsCommand +{ + public Commandkickall() + { + super("kickall"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + user.sendMessage("§7Usage: /" + commandLabel + ""); + return; + } + + + for (Player p : server.getOnlinePlayers()) + { + if (server.getOnlinePlayers().length == 1 && p.getName().equalsIgnoreCase(user.getName())) + { + user.sendMessage("§7Only you online..."); + return; + } + else + { + if (!p.getName().equalsIgnoreCase(user.getName())) + { + p.kickPlayer(args.length < 1 ? args[0] : "Kicked from server"); + } + } + } + } + + @Override + public void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + sender.sendMessage("Usage: /" + commandLabel + ""); + return; + } + + for (Player p : server.getOnlinePlayers()) + p.kickPlayer(args.length < 1 ? args[0] : "Kicked from server"); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandkill.java b/Essentials/src/com/earth2me/essentials/commands/Commandkill.java new file mode 100644 index 000000000..ef5315c85 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandkill.java @@ -0,0 +1,33 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import com.earth2me.essentials.Essentials; +import org.bukkit.entity.Player; +import com.earth2me.essentials.User; + + +public class Commandkill extends EssentialsCommand +{ + public Commandkill() + { + super("kill"); + } + + @Override + public void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + sender.sendMessage("§cUsage: /kill [player]"); + return; + } + + User.charge(sender, this); + for (Player p : server.matchPlayer(args[0])) + { + p.setHealth(0); + sender.sendMessage("§cKilled " + p.getDisplayName() + "."); + } + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandkit.java b/Essentials/src/com/earth2me/essentials/commands/Commandkit.java new file mode 100644 index 000000000..eb251b06b --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandkit.java @@ -0,0 +1,150 @@ +package com.earth2me.essentials.commands; + +import java.util.Calendar; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import org.bukkit.inventory.ItemStack; + + +public class Commandkit extends EssentialsCommand +{ + static private final Map> kitPlayers = new HashMap>(); + + public Commandkit() + { + super("kit"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + try + { + Map kits = (Map)parent.getConfiguration().getProperty("kits"); + StringBuilder list = new StringBuilder(); + for (String k : kits.keySet()) + { + if (user.isAuthorized("essentials.kit." + k)) + { + list.append(" ").append(k); + } + } + if (list.length() > 0) + { + user.sendMessage("§7Kits:" + list.toString()); + } + else + { + user.sendMessage("§7There are no kits available yet"); + } + } + catch (Exception ex) + { + user.sendMessage("§cThere are no valid kits."); + } + } + else + { + try + { + String kitName = args[0].toLowerCase(); + Object kit = Essentials.getSettings().getKit(kitName); + List items; + + if (!user.isAuthorized("essentials.kit." + kitName)) + { + user.sendMessage("§cYou need the §fessentials.kit." + kitName + "§c permission to use that kit."); + return; + } + + try + { + + System.out.println("Kit is timed"); + Map els = (Map)kit; + items = (List)els.get("items"); + long delay = els.containsKey("delay") ? (Integer)els.get("delay") * 1000L : 0L; + long time = Calendar.getInstance().getTimeInMillis(); + + Map kitTimes; + if (!kitPlayers.containsKey(user)) + { + kitTimes = new HashMap(); + kitTimes.put(kitName, time); + kitPlayers.put(user, kitTimes); + } + else + { + kitTimes = kitPlayers.get(user); + if (!kitTimes.containsKey(kitName)) + { + kitTimes.put(kitName, time); + } + else if (kitTimes.get(kitName) + delay <= time) + { + kitTimes.put(kitName, time); + } + else + { + long left = kitTimes.get(kitName) + delay - time; + user.sendMessage("§cYou can't use that kit again for another " + Essentials.FormatTime(left) + "."); + + return; + } + } + } + catch (Exception ex) + { + items = (List)kit; + } + + try { + user.canAfford("kit-" + kitName); + } catch (Exception ex) { + user.sendMessage(ex.getMessage()); + return; + } + + boolean spew = false; + for (String d : items) + { + String[] parts = d.split("[^0-9]+", 3); + int id = Integer.parseInt(parts[0]); + int amount = parts.length > 1 ? Integer.parseInt(parts[parts.length > 2 ? 2 : 1]) : 1; + short data = parts.length > 2 ? Short.parseShort(parts[1]) : 0; + if(user.getInventory().firstEmpty() != -1) + { + user.getInventory().addItem(new ItemStack(id, amount, data)); + } + else + { + spew = true; + user.getWorld().dropItemNaturally(user.getLocation(), new ItemStack(id, amount, data)); + } + } + if(spew) + { + user.sendMessage("§7Your inventory was full, placing kit on the floor"); + } + try { + user.charge(this); + user.charge("kit-" + kitName); + } catch (Exception ex) { + user.sendMessage(ex.getMessage()); + } + user.sendMessage("§7Giving kit " + args[0].toLowerCase() + "."); + } + catch (Exception ex) + { + user.sendMessage("§cThat kit does not exist or is improperly defined."); + user.sendMessage("§cPerhaps an item is missing a quantity in the configuration?"); + } + } + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandlist.java b/Essentials/src/com/earth2me/essentials/commands/Commandlist.java new file mode 100644 index 000000000..aeef26ac7 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandlist.java @@ -0,0 +1,93 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import com.earth2me.essentials.Essentials; +import org.bukkit.entity.Player; +import com.earth2me.essentials.User; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.bukkit.ChatColor; + + +public class Commandlist extends EssentialsCommand +{ + public Commandlist() + { + super("list"); + } + + @Override + public void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception + { + User.charge(sender, this); + StringBuilder online = new StringBuilder(); + online.append(ChatColor.BLUE).append("There are ").append(ChatColor.RED).append(server.getOnlinePlayers().length); + online.append(ChatColor.BLUE).append(" out of a maximum ").append(ChatColor.RED).append(server.getMaxPlayers()); + online.append(ChatColor.BLUE).append(" players online."); + sender.sendMessage(online.toString()); + + if (Essentials.getSettings().getSortListByGroups()) { + Map> sort = new HashMap>(); + for (Player p : server.getOnlinePlayers()) + { + User u = User.get(p); + String group = u.getGroup(); + List list = sort.get(group); + if (list == null) { + list = new ArrayList(); + sort.put(group, list); + } + list.add(u); + } + String[] groups = sort.keySet().toArray(new String[0]); + Arrays.sort(groups, String.CASE_INSENSITIVE_ORDER); + for (String group : groups) { + StringBuilder groupString = new StringBuilder(); + groupString.append(group).append(": "); + List users = sort.get(group); + Collections.sort(users); + boolean first = true; + for (User user : users) { + if (!first) { + groupString.append(", "); + } else { + first = false; + } + if (parent.away.contains(user)) { + groupString.append("§7[AFK]"); + } + groupString.append(user.getDisplayName()); + } + sender.sendMessage(groupString.toString()); + } + } else { + List users = new ArrayList(); + for (Player p : server.getOnlinePlayers()) + { + users.add(User.get(p)); + } + Collections.sort(users); + + StringBuilder onlineUsers = new StringBuilder(); + onlineUsers.append("Connected players: "); + boolean first = true; + for (User user : users) { + if (!first) { + onlineUsers.append(", "); + } else { + first = false; + } + if (parent.away.contains(user)) { + onlineUsers.append("§7[AFK]"); + } + onlineUsers.append(user.getDisplayName()); + } + sender.sendMessage(onlineUsers.toString()); + } + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandmail.java b/Essentials/src/com/earth2me/essentials/commands/Commandmail.java new file mode 100644 index 000000000..3e55c982d --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandmail.java @@ -0,0 +1,52 @@ +package com.earth2me.essentials.commands; + +import java.util.List; +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commandmail extends EssentialsCommand +{ + public Commandmail() + { + super("mail"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + if (args.length >= 1 && "read".equalsIgnoreCase(args[0])) + { + List mail = Essentials.readMail(user); + if (mail.isEmpty()) + { + user.sendMessage("§cYou do not have any mail!"); + return; + } + for (String s : mail) user.sendMessage(s); + user.sendMessage("§cTo mark your mail as read, type §c/mail clear"); + return; + } + if(args.length >= 3 && "send".equalsIgnoreCase(args[0])) + { + if (!user.isAuthorized("essentials.mail.send")) + { + user.sendMessage("§cYou do not have the §fessentials.mail.send§c permission."); + return; + } + + user.charge(this); + Essentials.sendMail(user, args[1], getFinalArg(args, 2)); + user.sendMessage("§7Mail sent!"); + return; + } + if (args.length >= 1 && "clear".equalsIgnoreCase(args[0])) + { + Essentials.clearMail(user); + user.sendMessage("§7Mail cleared!"); + return; + } + user.sendMessage("§7Usage: /mail [read|clear|send [to] [message]]"); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandme.java b/Essentials/src/com/earth2me/essentials/commands/Commandme.java new file mode 100644 index 000000000..6b3deaf1d --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandme.java @@ -0,0 +1,43 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commandme extends EssentialsCommand +{ + public Commandme() + { + super("me"); + } + + @Override + public String[] getTriggers() + { + return new String[] { getName(), "describe", "action" }; + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + if (user.isMuted()) + { user.sendMessage("§7Your voice has been silenced"); + return; + } + + if (args.length < 1) + { + user.sendMessage("§cUsage: /me [description]"); + return; + } + StringBuilder message = new StringBuilder(); + for (int i = 0; i < args.length; i++) + { + message.append(args[i]); + message.append(' '); + } + user.charge(this); + server.broadcastMessage("* " + user.getDisplayName() + " " + message); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandmotd.java b/Essentials/src/com/earth2me/essentials/commands/Commandmotd.java new file mode 100644 index 000000000..652310e36 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandmotd.java @@ -0,0 +1,25 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import org.bukkit.command.CommandSender; + + +public class Commandmotd extends EssentialsCommand +{ + public Commandmotd() + { + super("motd"); + } + + @Override + public void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception + { + User.charge(sender, this); + for (String m : parent.getMotd(sender, "§cThere is no message of the day.")) + { + sender.sendMessage(m); + } + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandmsg.java b/Essentials/src/com/earth2me/essentials/commands/Commandmsg.java new file mode 100644 index 000000000..8b02bbf19 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandmsg.java @@ -0,0 +1,85 @@ +package com.earth2me.essentials.commands; + +import java.util.List; +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import org.bukkit.entity.Player; +import com.earth2me.essentials.User; +import org.bukkit.command.CommandSender; + +public class Commandmsg extends EssentialsCommand +{ + public Commandmsg() + { + super("msg"); + } + + @Override + public String[] getTriggers() + { + return new String[] { getName(), "m", "tell", "whisper" }; + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + if (args.length < 2 || args[0].trim().length() == 0 || args[1].trim().length() == 0) + { + user.sendMessage("§cUsage: /" + commandLabel + " [player] [message]"); + return; + } + + StringBuilder message = new StringBuilder(); + for (int i = 1; i < args.length; i++) + { + message.append(args[i]); + message.append(' '); + } + + List matches = server.matchPlayer(args[0]); + + if (matches.isEmpty()) + { + user.sendMessage("§cThere are no players matching that name."); + return; + } + + user.charge(this); + for (Player p : matches) + { + user.sendMessage("[Me -> " + p.getDisplayName() + "§f] " + message); + p.sendMessage("[" + user.getDisplayName() + " -> Me§f] " + message); + user.setReplyTo(User.get(p)); + User.get(p).setReplyTo(user); + } + } + + @Override + public void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception + { + if (args.length < 2 || args[0].trim().length() == 0 || args[1].trim().length() == 0) + { + sender.sendMessage("§cUsage: /" + commandLabel + " [player] [message]"); + return; + } + + StringBuilder message = new StringBuilder(); + for (int i = 1; i < args.length; i++) + { + message.append(args[i]); + message.append(' '); + } + List matches = server.matchPlayer(args[0]); + + if (matches.isEmpty()) + { + sender.sendMessage("§cThere are no players matching that name."); + } + + for (Player p : matches) + { + sender.sendMessage("[§2Me -> " + p.getDisplayName() + "§f] " + message); + p.sendMessage("[§2{Console} -> Me§f] " + message); + } + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandmute.java b/Essentials/src/com/earth2me/essentials/commands/Commandmute.java new file mode 100644 index 000000000..30164e25d --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandmute.java @@ -0,0 +1,64 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commandmute extends EssentialsCommand +{ + public Commandmute() + { + super("kick"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + user.sendMessage("§7Usage: /" + commandLabel + " [player] "); + return; + } + + String[] sects2 = args[0].split(" +"); + User p; + try + { + p = User.get(server.matchPlayer(args[0]).get(0)); + } + catch (Exception ex) + { + user.sendMessage("§cThat player does not exist!"); + return; + } + + user.sendMessage("§7Player " + p.getName() + " " + (p.toggleMuted() ? "muted." : "unmuted.")); + } + + @Override + public void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + sender.sendMessage("Usage: /" + commandLabel + " [player] "); + return; + } + + String[] sects2 = args[0].split(" +"); + User p; + try + { + p = User.get(server.matchPlayer(args[0]).get(0)); + } + catch (Exception ex) + { + sender.sendMessage("§cThat player does not exist!"); + return; + } + + sender.sendMessage("Player " + p.getName() + " " + (p.toggleMuted() ? "muted." : "unmuted.")); + + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandnick.java b/Essentials/src/com/earth2me/essentials/commands/Commandnick.java new file mode 100644 index 000000000..fb65539b6 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandnick.java @@ -0,0 +1,129 @@ +package com.earth2me.essentials.commands; + +import java.util.List; +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import com.earth2me.essentials.Essentials; +import org.bukkit.entity.Player; +import com.earth2me.essentials.User; + + +public class Commandnick extends EssentialsCommand +{ + public Commandnick() + { + super("nick"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + user.sendMessage("§cUsage: /" + commandLabel + " [nickname]"); + return; + } + + if (args.length > 1) + { + if (!user.isOp()) + { + user.sendMessage("§cOnly operators can change the nicknames of other users."); + return; + } + + List matches = server.matchPlayer(args[0]); + if (matches.isEmpty()) + { + user.sendMessage("§cThat player does not exist."); + return; + } + + User target = User.get(matches.get(0)); + String nick = args[1]; + if ("off".equalsIgnoreCase(nick) || target.getName().equalsIgnoreCase(nick)) + { + target.setDisplayName(target.getName()); + parent.saveNickname(target, target.getName()); + target.sendMessage("§7You no longer have a nickname."); + } + else + { + user.charge(this); + target.setDisplayName(parent.getConfiguration().getString("nickname-prefix", "~") + nick); + parent.saveNickname(target, nick); + target.sendMessage("§7Your nickname is now §c" + target.getDisplayName() + "§7."); + } + user.sendMessage("§7Nickname changed."); + } + else + { + String nick = args[0]; + if ("off".equalsIgnoreCase(nick) || user.getName().equalsIgnoreCase(nick)) + { + user.setDisplayName(user.getName()); + parent.saveNickname(user, user.getName()); + user.sendMessage("§7You no longer have a nickname."); + } + else + { + if (nick.matches("[^a-zA-Z_0-9]")) + { + user.sendMessage("§cNicknames must be alphanumeric."); + return; + } + + for (Player p : server.getOnlinePlayers()) + { + if (user == p) continue; + String dn = p.getDisplayName().toLowerCase(); + String n = p.getName().toLowerCase(); + String nk = nick.toLowerCase(); + if (nk.equals(dn) || nk.equals(n)) + { + user.sendMessage("§cThat name is already in use."); + return; + } + } + + user.charge(this); + user.setDisplayName(parent.getConfiguration().getString("nickname-prefix", "~") + nick); + parent.saveNickname(user, nick); + user.sendMessage("§7Your nickname is now §c" + user.getDisplayName() + "§7."); + } + } + } + + @Override + public void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception + { + if (args.length < 2) + { + sender.sendMessage("Usage: /" + commandLabel + " [target] [nickname]"); + return; + } + + List matches = server.matchPlayer(args[0]); + if (matches.isEmpty()) + { + sender.sendMessage("That player does not exist."); + return; + } + + User target = User.get(matches.get(0)); + String nick = args[1]; + if ("off".equalsIgnoreCase(nick) || target.getName().equalsIgnoreCase(nick)) + { + target.setDisplayName(target.getName()); + parent.saveNickname(target, target.getName()); + target.sendMessage("§7You no longer have a nickname."); + } + else + { + target.setDisplayName(parent.getConfiguration().getString("nickname-prefix", "~") + nick); + parent.saveNickname(target, nick); + target.sendMessage("§7Your nickname is now §c" + target.getDisplayName() + "§7."); + } + sender.sendMessage("Nickname changed."); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandnuble.java b/Essentials/src/com/earth2me/essentials/commands/Commandnuble.java new file mode 100644 index 000000000..dc6ab3ac3 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandnuble.java @@ -0,0 +1,21 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commandnuble extends EssentialsCommand +{ + public Commandnuble() + { + super("nuble"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + user.charge(this); + user.sendMessage("§7Flight is allowed on this server."); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandpay.java b/Essentials/src/com/earth2me/essentials/commands/Commandpay.java new file mode 100644 index 000000000..085f8febe --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandpay.java @@ -0,0 +1,42 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import com.earth2me.essentials.Essentials; +import org.bukkit.entity.Player; +import com.earth2me.essentials.User; +import com.earth2me.essentials.commands.EssentialsCommand; + + +public class Commandpay extends EssentialsCommand +{ + public Commandpay() + { + super("pay"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + + int amount; + try + { + amount = Integer.parseInt(args[1].replaceAll("[^0-9]", "")); + } + catch (Exception ex) + { + user.sendMessage("§cUsage: /" + commandLabel + " [player] [money]"); + return; + } + + for (Player p : server.matchPlayer(args[0])) + { + User u = User.get(p); + user.payUser(u, amount); + } + } + + + +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandping.java b/Essentials/src/com/earth2me/essentials/commands/Commandping.java new file mode 100644 index 000000000..36d8e33c3 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandping.java @@ -0,0 +1,26 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commandping extends EssentialsCommand +{ + public Commandping() + { + super("ping"); + } + + @Override + public String[] getTriggers() + { + return new String[] { getName(), "pong" }; + } + + @Override + public void run(Server server, Essentials parent, User player, String commandLabel, String[] args) throws Exception + { + player.sendMessage("Pong!"); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandplugin.java b/Essentials/src/com/earth2me/essentials/commands/Commandplugin.java new file mode 100644 index 000000000..df1ecdaad --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandplugin.java @@ -0,0 +1,161 @@ +package com.earth2me.essentials.commands; + +import java.io.File; +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import org.bukkit.command.CommandSender; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginManager; + + +public class Commandplugin extends EssentialsCommand +{ + private Server server; + + public Commandplugin() + { + super("plugin"); + } + + @Override + public void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception + { + this.server = server; + + PluginCommands sub = null; + try + { + sub = PluginCommands.valueOf(args[0].toUpperCase()); + } + catch (Exception ex) + { + sender.sendMessage("§cUsage: /plugin [load|reload|enable|disable|list] [PluginName]"); + return; + } + + switch (sub) + { + case LOAD: + if (args.length < 2) return; + User.charge(sender, this); + loadPlugin(args[1], sender); + return; + + case RELOAD: + if (args.length < 2) return; + User.charge(sender, this); + reloadPlugin(args[1], sender); + return; + + case ENABLE: + if (args.length < 2) return; + User.charge(sender, this); + enablePlugin(args[1], sender); + return; + + case DISABLE: + if (args.length < 2) return; + User.charge(sender, this); + disablePlugin(args[1], sender); + return; + + case LIST: + User.charge(sender, this); + listPlugins(sender); + return; + } + } + + private void listPlugins(CommandSender player) + { + StringBuilder plugins = new StringBuilder(); + for (Plugin p : server.getPluginManager().getPlugins()) + { + plugins.append(p.isEnabled() ? " §a" : " §c"); + plugins.append(p.getDescription().getName()); + } + + plugins.insert(0, "§7Plugins:§f"); + player.sendMessage(plugins.toString()); + } + + private boolean reloadPlugin(String name, CommandSender player) + { + return disablePlugin(name, player) && enablePlugin(name, player); + } + + private boolean loadPlugin(String name, CommandSender sender) + { + try + { + PluginManager pm = server.getPluginManager(); + pm.loadPlugin(new File("plugins", name + ".jar")); + sender.sendMessage("§7Plugin loaded."); + return enablePlugin(name, sender); + } + catch (Throwable ex) + { + sender.sendMessage("§cCould not load plugin. Is the file named properly?"); + return false; + } + } + + private boolean enablePlugin(String name, CommandSender sender) + { + try + { + final PluginManager pm = server.getPluginManager(); + final Plugin plugin = pm.getPlugin(name); + if (!plugin.isEnabled()) new Thread(new Runnable() + { + public void run() + { + synchronized (pm) + { + pm.enablePlugin(plugin); + } + } + }).start(); + sender.sendMessage("§7Plugin enabled."); + return true; + } + catch (Throwable ex) + { + listPlugins(sender); + return false; + } + } + + private boolean disablePlugin(String name, CommandSender sender) + { + try + { + final PluginManager pm = server.getPluginManager(); + final Plugin plugin = pm.getPlugin(name); + if (plugin.isEnabled()) new Thread(new Runnable() + { + public void run() + { + synchronized (pm) + { + pm.disablePlugin(plugin); + } + } + }).start(); + sender.sendMessage("§7Plugin disabled."); + return true; + } + catch (Throwable ex) + { + listPlugins(sender); + return false; + } + } + + + private enum PluginCommands + { + LOAD, RELOAD, LIST, ENABLE, DISABLE + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandr.java b/Essentials/src/com/earth2me/essentials/commands/Commandr.java new file mode 100644 index 000000000..9bc7f2f97 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandr.java @@ -0,0 +1,37 @@ +package com.earth2me.essentials.commands; + +import com.earth2me.essentials.*; +import org.bukkit.*; + + +public class Commandr extends EssentialsCommand +{ + public Commandr() + { + super("r"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + user.sendMessage("§cUsage: /" + commandLabel + " [message]"); + return; + } + + String message = getFinalArg(args, 0); + User target = user.getReplyTo(); + + if (target == null) + { + user.sendMessage("§cYou have nobody to whom you can reply."); + } + + user.charge(this); + user.sendMessage("[Me -> " + target.getDisplayName() + "] " + message); + target.sendMessage("[" + user.getDisplayName() + " -> Me] " + message); + user.setReplyTo(target); + target.setReplyTo(user); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandrealname.java b/Essentials/src/com/earth2me/essentials/commands/Commandrealname.java new file mode 100644 index 000000000..6bec3f633 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandrealname.java @@ -0,0 +1,40 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import org.bukkit.entity.Player; +import com.earth2me.essentials.User; + + +public class Commandrealname extends EssentialsCommand +{ + public Commandrealname() + { + super("realname"); + } + + @Override + public String[] getTriggers() + { + return new String[] { getName(), "realnick" }; + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + user.sendMessage("§cUsage: /whois [nickname]"); + return; + } + String whois = args[0].toLowerCase(); + user.charge(this); + for (Player p : server.getOnlinePlayers()) + { + User u = User.get(p); + String dn = u.getDisplayName().toLowerCase(); + if (!whois.equals(dn) && !whois.equals(parent.getSettings().getNicknamePrefix() + dn) && !whois.equals(u.getName().toLowerCase())) continue; + user.sendMessage(u.getDisplayName() + " is " + u.getName()); + } + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandreloadall.java b/Essentials/src/com/earth2me/essentials/commands/Commandreloadall.java new file mode 100644 index 000000000..c677bc1c6 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandreloadall.java @@ -0,0 +1,37 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commandreloadall extends EssentialsCommand +{ + + public Commandreloadall() + { + super("reloadall"); + } + + @Override + public String[] getTriggers() + { + return new String[] { getName(), "rel", "pr" }; + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + user.charge(this); + server.reload(); + user.sendMessage("§7Reloaded all plugins."); + } + + @Override + public void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception + { + server.reload(); + sender.sendMessage("Reloaded all plugins."); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandrules.java b/Essentials/src/com/earth2me/essentials/commands/Commandrules.java new file mode 100644 index 000000000..e94b98755 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandrules.java @@ -0,0 +1,23 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.*; + + +public class Commandrules extends EssentialsCommand +{ + public Commandrules() + { + super("rules"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + user.charge(this); + for (String m : parent.getLines(user, "rules", "§cThere are no rules specified yet.")) + { + user.sendMessage(m); + } + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandsell.java b/Essentials/src/com/earth2me/essentials/commands/Commandsell.java new file mode 100644 index 000000000..11ce4ba6d --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandsell.java @@ -0,0 +1,63 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import com.earth2me.essentials.commands.EssentialsCommand; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + + +public class Commandsell extends EssentialsCommand +{ + public Commandsell() + { + super("sell"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + ItemStack is = user.getInventory().getItemInHand(); + if(is.getType() == Material.AIR) + throw new Exception("You really tried to sell Air? Put an item in your hand."); + + int id = is.getTypeId(); + int amount = 0; + if (args.length > 0) amount = Integer.parseInt(args[0].replaceAll("[^0-9]", "")); + int worth = parent.getConfiguration().getInt("worth-" + id, 0); + boolean stack = args.length > 0 && args[0].endsWith("s"); + boolean requireStack = parent.getConfiguration().getBoolean("trade-in-stacks-" + id, false); + + if (worth < 1) throw new Exception("That item cannot be sold to the server."); + if (requireStack && !stack) throw new Exception("Item must be traded in stacks. A quantity of 2s would be two stacks, etc."); + + int max = 0; + for (ItemStack s : user.getInventory().all(is).values()) + { + max += s.getAmount(); + } + + if (stack) amount *= 64; + if (amount < 1) amount += max; + + if (requireStack) + { + amount -= amount % 64; + } + + if (amount > max || amount < 1) + { + user.sendMessage("§cYou do not have enough of that item to sell."); + user.sendMessage("§7If you meant to sell all of your items of that type, use /sell without parameters."); + user.sendMessage("§7/sell -1 will sell all but one item, etc."); + return; + } + + user.charge(this); + user.getInventory().removeItem(new ItemStack(id, amount)); + user.updateInventory(); + user.giveMoney(worth * amount); + user.sendMessage("§7Sold for §c$" + (worth * amount) + "§7 (" + amount + " items at $" + worth + " each)"); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandsethome.java b/Essentials/src/com/earth2me/essentials/commands/Commandsethome.java new file mode 100644 index 000000000..f4729ead8 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandsethome.java @@ -0,0 +1,22 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commandsethome extends EssentialsCommand +{ + public Commandsethome() + { + super("sethome"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + user.setHome(); + user.charge(this); + user.sendMessage("§7Home set."); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandsetjail.java b/Essentials/src/com/earth2me/essentials/commands/Commandsetjail.java new file mode 100644 index 000000000..f5c330188 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandsetjail.java @@ -0,0 +1,28 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commandsetjail extends EssentialsCommand +{ + public Commandsetjail() + { + super("setjail"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + user.sendMessage("§cUsage: /" + commandLabel + " [jailname]"); + return; + } + user.charge(this); + Essentials.getJail().setJail(user.getLocation(), args[0]); + user.sendMessage("§7Jail " + args[0] + " has been set"); + + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandsetwarp.java b/Essentials/src/com/earth2me/essentials/commands/Commandsetwarp.java new file mode 100644 index 000000000..e510a8f73 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandsetwarp.java @@ -0,0 +1,30 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Location; +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commandsetwarp extends EssentialsCommand +{ + public Commandsetwarp() + { + super("setwarp"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + user.sendMessage("§cUsage: /setwarp [warp name]"); + return; + } + + user.charge(this); + Location loc = user.getLocation(); + Essentials.getWarps().setWarp(args[0], loc); + user.sendMessage("§7Warp set."); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandspawner.java b/Essentials/src/com/earth2me/essentials/commands/Commandspawner.java new file mode 100644 index 000000000..d73c0b843 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandspawner.java @@ -0,0 +1,41 @@ +package com.earth2me.essentials.commands; + +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.Server; +import org.bukkit.block.Block; +import org.bukkit.block.CreatureSpawner; +import org.bukkit.entity.CreatureType; + +public class Commandspawner extends EssentialsCommand +{ + public Commandspawner() + { + super("spawner"); + } + + @Override + protected void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + user.sendMessage(ChatColor.RED + "Usage: /" + commandLabel + " [mob]"); + return; + } + + Block target = user.getTarget().getTargetBlock(); + if (target.getType() != Material.MOB_SPAWNER) + throw new Exception("Target block must be a mob spawner."); + + try + { + ((CreatureSpawner)target).setCreatureType(CreatureType.fromName(args[0])); + } + catch (Throwable ex) + { + + } + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandspawnmob.java b/Essentials/src/com/earth2me/essentials/commands/Commandspawnmob.java new file mode 100644 index 000000000..c1c883a75 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandspawnmob.java @@ -0,0 +1,188 @@ +package com.earth2me.essentials.commands; + +import net.minecraft.server.WorldServer; +import org.bukkit.Location; +import org.bukkit.Server; +import org.bukkit.craftbukkit.entity.CraftEntity; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import com.earth2me.essentials.Mob; +import com.earth2me.essentials.Mob.MobException; +import com.earth2me.essentials.TargetBlock; + + +public class Commandspawnmob extends EssentialsCommand +{ + public Commandspawnmob() + { + super("spawnmob"); + } + + @Override + public String[] getTriggers() + { + return new String[] + { + getName(), "mob" + }; + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + user.sendMessage("§cUsage: /spawnmob [mob]<,mount><:size> "); + user.sendMessage("§7Mobs: Zombie PigZombie Skeleton Slime Chicken Pig Monster Spider Creeper Ghast Squid Giant Cow Sheep"); + return; + } + + String[] split1 = args[0].split(":"); + String[] split0 = null; + CraftEntity spawned1 = null; + Mob mob2 = null; + if (split1.length == 1 && !split1[0].equalsIgnoreCase("Slime")) + { + split0 = args[0].split(","); + split1[0] = split0[0]; + } + if (split1.length == 2) + { + args[0] = split1[0] + ""; + } + Mob mob = Mob.fromName(split1[0].equalsIgnoreCase("PigZombie") ? "PigZombie" : capitalCase(split1[0])); + if (mob == null) + { + user.sendMessage("Invalid mob type."); + return; + } + WorldServer world = ((org.bukkit.craftbukkit.CraftWorld)user.getWorld()).getHandle(); + CraftEntity spawned = null; + try + { + spawned = mob.spawn(user, server); + } + catch (MobException e) + { + user.sendMessage("Unable to spawn mob."); + return; + } + int[] ignore = {8, 9}; + Location loc = (new TargetBlock(user, 300, 0.2, ignore)).getTargetBlock().getLocation(); + int blkId = user.getWorld().getBlockTypeIdAt(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + while (!(blkId == 0 || blkId == 8 || blkId == 9)) + { + loc.setY(loc.getY() + 1); + blkId = user.getWorld().getBlockTypeIdAt(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + } + spawned.teleportTo(loc); + world.a(spawned.getHandle()); + if (split0 != null && split0.length == 2) + { + mob2 = Mob.fromName(split0[1].equalsIgnoreCase("PigZombie") ? "PigZombie" : capitalCase(split0[1])); + if (mob2 == null) + { + user.sendMessage("Invalid mob type."); + return; + } + try + { + spawned1 = mob2.spawn(user, server); + } + catch (MobException e) + { + user.sendMessage("Unable to spawn mob."); + return; + } + spawned1.teleportTo(spawned); + spawned1.getHandle().setPassengerOf(spawned.getHandle()); + world.a(spawned1.getHandle()); + } + if (split1.length == 2 && "Slime".equals(mob.name)) + { + try + { + //((EntitySlime)spawned.getHandle()).a(Integer.parseInt(split1[1])); + } + catch (Exception e) + { + user.sendMessage("Malformed size."); + return; + } + } + if (args.length == 2) + { + int mobCount = Integer.parseInt(args[1]); + int serverLimit = Essentials.getSettings().getSpawnMobLimit(); + if(mobCount > serverLimit) + { + mobCount = serverLimit; + user.sendMessage("Mob quantity limited to server limit"); + } + user.charge(this); + try + { + for (int i = 1; i < mobCount; i++) + { + spawned = mob.spawn(user, server); + spawned.teleportTo(loc); + if (split1.length > 1 && "Slime".equals("Slime")) + { + try + { + //((EntitySlime)spawned.getHandle()).a(Integer.parseInt(split1[1])); + } + catch (Exception e) + { + user.sendMessage("Malformed size."); + return; + } + } + world.a(spawned.getHandle()); + if (split0.length == 2) + { + if (mob2 == null) + { + user.sendMessage("Invalid mob mount."); + return; + } + try + { + spawned1 = mob2.spawn(user, server); + } + catch (MobException e) + { + user.sendMessage("Unable to spawn mob."); + return; + } + spawned1.teleportTo(spawned); + spawned1.getHandle().setPassengerOf(spawned.getHandle()); + world.a(spawned1.getHandle()); + } + } + user.sendMessage(args[1] + " " + mob.name.toLowerCase() + mob.s + " spawned."); + } + catch (MobException e1) + { + throw new Exception("Unable to spawn mobs. Insert bad excuse here."); + } + catch (NumberFormatException e2) + { + throw new Exception("A number goes there, silly."); + } + catch (NullPointerException np) + { + throw new Exception("That mob likes to be alone"); + } + } + else + { + user.sendMessage(mob.name + " spawned."); + } + } + + private String capitalCase(String s) + { + return s.toUpperCase().charAt(0) + s.toLowerCase().substring(1); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandsuicide.java b/Essentials/src/com/earth2me/essentials/commands/Commandsuicide.java new file mode 100644 index 000000000..07ac23e94 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandsuicide.java @@ -0,0 +1,23 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commandsuicide extends EssentialsCommand +{ + public Commandsuicide() + { + super("suicide"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + user.charge(this); + user.setHealth(0); + user.sendMessage("§cGoodbye Cruel World..."); + server.broadcastMessage("§7" + user.getDisplayName() + " took their own life" ); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandtime.java b/Essentials/src/com/earth2me/essentials/commands/Commandtime.java new file mode 100644 index 000000000..63e565de8 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandtime.java @@ -0,0 +1,63 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import org.bukkit.World; +import org.bukkit.command.CommandSender; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commandtime extends EssentialsCommand +{ + public Commandtime() + { + super("time"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + World world = user.getWorld(); + long time = world.getTime(); + time = time - time % 24000; + if (args.length < 1) + { + user.sendMessage("§cUsage: /time [day|night]"); + return; + } + if ("day".equalsIgnoreCase(args[0])) + { + user.charge(this); + world.setTime(time + 24000); + return; + } + if ("night".equalsIgnoreCase(args[0])) + { + user.charge(this); + world.setTime(time + 37700); + return; + } + throw new Exception("/time only supports day/night."); + } + + @Override + public void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception + { + for (World world : server.getWorlds()) + { + long time = world.getTime(); + time = time - time % 24000; + if (args.length < 1) + { + sender.sendMessage("Usage: /time [day|night]"); + return; + } + + if ("day".equalsIgnoreCase(args[0])) world.setTime(time + 24000); + else if ("night".equalsIgnoreCase(args[0])) world.setTime(time + 37700); + else throw new Exception("/time only supports day/night."); + } + + sender.sendMessage("Time set in all worlds."); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandtogglejail.java b/Essentials/src/com/earth2me/essentials/commands/Commandtogglejail.java new file mode 100644 index 000000000..f6d399a0d --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandtogglejail.java @@ -0,0 +1,67 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commandtogglejail extends EssentialsCommand +{ + public Commandtogglejail() + { + super("togglejail"); + } + + @Override + public void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception + { + if (args.length < 1 || args.length > 2) + { + sender.sendMessage("Usage: /" + commandLabel + " [player] [jailname]"); + return; + } + + User p; + try + { + p = User.get(server.matchPlayer(args[0]).get(0)); + } + catch (Exception ex) + { + sender.sendMessage("§cThat player does not exist."); + return; + } + + if (p.isOp() || p.isAuthorized("essentials.jail.exempt")) + { + sender.sendMessage("§cYou may not jail that person"); + return; + } + + if (args.length == 2 && !p.isJailed()) { + User.charge(sender, this); + sender.sendMessage("§7Player " + p.getName() + " " + (p.toggleJailed() ? "jailed." : "unjailed.")); + p.sendMessage("§7You have been jailed"); + Essentials.getJail().sendToJail(p, args[1]); + p.currentJail = (args[1]); + return; + } + + if (args.length == 2 && p.isJailed() && !args[1].equalsIgnoreCase(p.currentJail)) { + sender.sendMessage("§cPerson is already in jail "+ p.currentJail); + return; + } + + if (args.length == 1 || (args.length == 2 && args[1].equalsIgnoreCase(p.currentJail))) { + if (!p.isJailed()) { + sender.sendMessage("Usage: /" + commandLabel + " [player] [jailname]"); + return; + } + sender.sendMessage("§7Player " + p.getName() + " " + (p.toggleJailed() ? "jailed." : "unjailed.")); + p.sendMessage("§7You have been released"); + p.teleportBack(); + p.currentJail = ""; + } + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandtop.java b/Essentials/src/com/earth2me/essentials/commands/Commandtop.java new file mode 100644 index 000000000..a928701a2 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandtop.java @@ -0,0 +1,26 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Location; +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commandtop extends EssentialsCommand +{ + public Commandtop() + { + super("top"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + int topX = user.getLocation().getBlockX(); + int topZ = user.getLocation().getBlockZ(); + int topY = user.getWorld().getHighestBlockYAt(topX, topZ); + user.charge(this); + user.teleport(new Location(user.getWorld(), user.getLocation().getX(), topY + 1, user.getLocation().getZ()), this.getName()); + user.sendMessage("§7Teleporting to top."); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandtp.java b/Essentials/src/com/earth2me/essentials/commands/Commandtp.java new file mode 100644 index 000000000..a36a7e415 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandtp.java @@ -0,0 +1,61 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import org.bukkit.command.CommandSender; + + +public class Commandtp extends EssentialsCommand +{ + public Commandtp() + { + super("tp"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + switch (args.length) + { + case 0: + user.sendMessage("§cUsage: /" + commandLabel + " [to-player]"); + return; + + case 1: + User p = getPlayer(server, args, 0); + user.teleportCooldown(); + if (!p.isTeleEnabled()) throw new Exception(p.getDisplayName() + " has teleportation disabled."); + user.sendMessage("§7Teleporting..."); + user.canAfford(this); + user.teleport(p, this.getName()); + break; + + case 2: + if (!user.isAuthorized("essentials.tpohere")) throw new Exception("You need access to /tpohere to teleport other players."); + user.sendMessage("§7Teleporting..."); + user.charge(this); + User target = getPlayer(server, args, 0); + User toPlayer = getPlayer(server, args, 1); + target.teleportToNow(toPlayer); + target.sendMessage("§7" + user.getDisplayName() + "§7 teleported you to " + toPlayer.getDisplayName() + "§7."); + break; + } + } + + @Override + public void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception + { + if (args.length < 2) + { + sender.sendMessage("Usage: /" + commandLabel + " [target] [to-player]"); + return; + } + + sender.sendMessage("§7Teleporting..."); + User target = getPlayer(server, args, 0); + User toPlayer = getPlayer(server, args, 1); + target.teleportToNow(toPlayer); + target.sendMessage("§7{Console}§7 teleported you to " + toPlayer.getDisplayName() + "§7."); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandtpa.java b/Essentials/src/com/earth2me/essentials/commands/Commandtpa.java new file mode 100644 index 000000000..491c4363e --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandtpa.java @@ -0,0 +1,34 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commandtpa extends EssentialsCommand +{ + public Commandtpa() + { + super("tpa"); + } + + @Override + public void run(Server server, Essentials parent, User player, String commandLabel, String[] args) throws Exception + { + if(args.length < 1) + { + player.sendMessage("§cUsage: /tpa [playername]"); + return; + } + + User p = getPlayer(server, args, 0); + if (!p.isTeleEnabled()) throw new Exception(p.getDisplayName() + " has teleportation disabled."); + player.charge(this); + parent.tpcRequests.put(p, player); + parent.tpcHere.put(p, false); + p.sendMessage("§c" + player.getDisplayName() + "§c has requested to teleport to you."); + p.sendMessage("§7To teleport, type §c/tpaccept§7."); + p.sendMessage("§7To deny this request, type §c/tpdeny§7."); + player.sendMessage("§7Request sent to " + p.getDisplayName() + "§7."); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandtpaccept.java b/Essentials/src/com/earth2me/essentials/commands/Commandtpaccept.java new file mode 100644 index 000000000..84acdf82c --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandtpaccept.java @@ -0,0 +1,40 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import com.earth2me.essentials.commands.EssentialsCommand; + + +public class Commandtpaccept extends EssentialsCommand +{ + public Commandtpaccept() + { + super("tpaccept"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + + User p = parent.tpcRequests.get(user); + if (p == null) throw new Exception("You do not have a pending request."); + parent.tpcRequests.remove(user); + + if (parent.tpcHere.get(user)) + { + user.teleportCooldown(); + user.canAfford(this); + user.sendMessage("§7Teleport request accepted."); + p.sendMessage("§7Teleport request accepted."); + user.teleport(p, this.getName()); + } + else + { + user.canAfford(this); + user.sendMessage("§7Teleport request accepted."); + p.sendMessage("§7Teleport request accepted."); + p.teleport(user, this.getName()); + } + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandtpahere.java b/Essentials/src/com/earth2me/essentials/commands/Commandtpahere.java new file mode 100644 index 000000000..bf179cc59 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandtpahere.java @@ -0,0 +1,33 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commandtpahere extends EssentialsCommand +{ + public Commandtpahere() + { + super("tpahere"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + user.sendMessage("§cUsage: /tpahere [playername]"); + return; + } + + User p = getPlayer(server, args, 0); + if (!p.isTeleEnabled()) throw new Exception(p.getDisplayName() + " has teleportation disabled."); + user.charge(this); + parent.tpcRequests.put(p, user); + parent.tpcHere.put(p, true); + p.sendMessage("§c" + user.getDisplayName() + "§c has requested that you teleport to him/her."); + p.sendMessage("§7To teleport, type §c/tpaccept§7."); + user.sendMessage("§7Request sent to " + p.getDisplayName() + "§c."); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandtpdeny.java b/Essentials/src/com/earth2me/essentials/commands/Commandtpdeny.java new file mode 100644 index 000000000..6ed5fc8dc --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandtpdeny.java @@ -0,0 +1,37 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commandtpdeny extends EssentialsCommand +{ + public Commandtpdeny() + { + super("tpdeny"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + User p = parent.tpcRequests.get(user); + if (p == null) throw new Exception("You do not have a pending request."); + parent.tpcRequests.remove(user); + + if (parent.tpcHere.get(user)) + { + user.charge(this); + user.sendMessage("§7Teleport request denied."); + p.sendMessage("§7Teleport request denied."); + parent.tpcHere.remove(user); + } + else + { + user.charge(this); + user.sendMessage("§7Teleport request denied."); + p.sendMessage("§7Teleport request denied."); + parent.tpcRequests.remove(user); + } + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandtphere.java b/Essentials/src/com/earth2me/essentials/commands/Commandtphere.java new file mode 100644 index 000000000..3a003b257 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandtphere.java @@ -0,0 +1,34 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commandtphere extends EssentialsCommand +{ + public Commandtphere() + { + super("tphere"); + } + + @Override + public String[] getTriggers() + { + return new String[] + { + getName(), "telehere", "s" + }; + } + + @Override + public void run(Server server, Essentials parent, User player, String commandLabel, String[] args) throws Exception + { + User p = getPlayer(server, args, 0); + if (!p.isTeleEnabled()) throw new Exception(p.getDisplayName() + " has teleportation disabled."); + player.charge(this); + p.teleportTo(player); + player.sendMessage("§7Teleporting..."); + p.sendMessage("§7Teleporting..."); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandtpo.java b/Essentials/src/com/earth2me/essentials/commands/Commandtpo.java new file mode 100644 index 000000000..f3fa6900c --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandtpo.java @@ -0,0 +1,34 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import com.earth2me.essentials.commands.EssentialsCommand; + + +public class Commandtpo extends EssentialsCommand +{ + public Commandtpo() + { + super("tpo"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + user.sendMessage("§c Usage: /tpo [playername]"); + } + else + { + //Just basically the old tp command + User p = getPlayer(server, args, 0); + user.teleportCooldown(); + user.charge(this); + user.teleportToNow(p); + user.sendMessage("§7Teleporting..."); + } + + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandtpohere.java b/Essentials/src/com/earth2me/essentials/commands/Commandtpohere.java new file mode 100644 index 000000000..082f49452 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandtpohere.java @@ -0,0 +1,31 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commandtpohere extends EssentialsCommand +{ + public Commandtpohere() + { + super("tpohere"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + user.sendMessage("§c Usage: /tpohere [playername]"); + } + else + { + //Just basically the old tphere command + User p = getPlayer(server, args, 0); + user.charge(this); + p.teleportToNow(user); + user.sendMessage("§7Teleporting..."); + } + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandtppos.java b/Essentials/src/com/earth2me/essentials/commands/Commandtppos.java new file mode 100644 index 000000000..031735e9a --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandtppos.java @@ -0,0 +1,42 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Location; +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commandtppos extends EssentialsCommand +{ + public Commandtppos() + { + super("tppos"); + } + + @Override + public String[] getTriggers() + { + return new String[] + { + getName(), "tpp" + }; + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + if (args.length < 3) + { + user.sendMessage("§cUsage: /tppos [x] [y] [z]"); + return; + } + int x = Integer.parseInt(args[0]); + int y = Integer.parseInt(args[1]); + int z = Integer.parseInt(args[2]); + Location l = new Location(user.getWorld(),x,y,z); + user.canAfford(this); + user.teleportCooldown(); + user.sendMessage("§7Teleporting..."); + user.teleport(user.getSafeDestination(l), this.getName()); + } +} \ No newline at end of file diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandtptoggle.java b/Essentials/src/com/earth2me/essentials/commands/Commandtptoggle.java new file mode 100644 index 000000000..7e93cc4cf --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandtptoggle.java @@ -0,0 +1,21 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commandtptoggle extends EssentialsCommand +{ + public Commandtptoggle() + { + super("tptoggle"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + user.charge(this); + user.sendMessage("§7Teleportation " + (user.toggleTeleEnabled() ? "enabled." : "disabled.")); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandtree.java b/Essentials/src/com/earth2me/essentials/commands/Commandtree.java new file mode 100644 index 000000000..27ce617c9 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandtree.java @@ -0,0 +1,64 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Location; +import org.bukkit.Server; +import org.bukkit.TreeType; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + +public class Commandtree extends EssentialsCommand +{ + public Commandtree() + { + super("tree"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + Object tree = new Object(); + if (args.length < 1) + { + user.sendMessage("§cUsage: /tree [tree|birch|redwood]"); + return; + } + else if (args[0].equalsIgnoreCase("birch")) + { + tree = TreeType.BIRCH; + } + else if (args[0].equalsIgnoreCase("redwood")) + { + tree = TreeType.REDWOOD; + } + else if (args[0].equalsIgnoreCase("tree")) + { + tree = TreeType.TREE; + } + else + { + user.sendMessage("§cUsage: /tree [tree|birch|redwood]"); + return; + } + + double x = user.getLocation().getX(); + double y = user.getLocation().getY(); + double z = user.getLocation().getZ(); + + // offset tree in direction player is facing + int r = (int)user.getCorrectedYaw(); + if (r < 68 || r > 292) x -= 3.0D; // north + else if (r > 112 && r < 248) x += 3.0D; // south + if (r > 22 && r < 158) z -= 3.0D; // east + else if (r > 202 && r < 338) z += 3.0D; // west + + Location safeLocation = user.getSafeDestination(new Location(user.getWorld(), x, y, z)); + boolean success = user.getWorld().generateTree(safeLocation, (TreeType)tree); + if (success) + { + user.charge(this); + user.sendMessage("§7Tree spawned."); + } + else + user.sendMessage("§cTree generation failure. Try again on grass or dirt."); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandunban.java b/Essentials/src/com/earth2me/essentials/commands/Commandunban.java new file mode 100644 index 000000000..55fd54fad --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandunban.java @@ -0,0 +1,35 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import org.bukkit.craftbukkit.CraftServer; +import com.earth2me.essentials.Essentials; + + +public class Commandunban extends EssentialsCommand +{ + public Commandunban() + { + super("unban"); + } + + @Override + public String[] getTriggers() + { + return new String[] { getName(), "pardon" }; + } + + @Override + public void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + sender.sendMessage("Usage: /" + commandLabel + " [player]"); + return; + } + + ((CraftServer)server).getHandle().c.f.b(args[0]); + sender.sendMessage("Unbanned player."); + Essentials.getStatic().loadBanList(); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandunbanip.java b/Essentials/src/com/earth2me/essentials/commands/Commandunbanip.java new file mode 100644 index 000000000..df152c23f --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandunbanip.java @@ -0,0 +1,35 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import org.bukkit.craftbukkit.CraftServer; +import com.earth2me.essentials.Essentials; + + +public class Commandunbanip extends EssentialsCommand +{ + public Commandunbanip() + { + super("unbanip"); + } + + @Override + public String[] getTriggers() + { + return new String[] { getName(), "pardonip" }; + } + + @Override + public void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + sender.sendMessage("Usage: /" + commandLabel + " [address]"); + return; + } + + ((CraftServer)server).getHandle().c.f.d(args[0]); + sender.sendMessage("Unbanned IP address."); + Essentials.getStatic().loadBanList(); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandwarp.java b/Essentials/src/com/earth2me/essentials/commands/Commandwarp.java new file mode 100644 index 000000000..c5471f831 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandwarp.java @@ -0,0 +1,74 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import com.earth2me.essentials.Warps; + + +public class Commandwarp extends EssentialsCommand +{ + public Commandwarp() + { + super("warp"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + boolean perWarpPermission = Essentials.getSettings().getPerWarpPermission(); + if (args.length == 0) { + if (!user.isAuthorized("essentials.warp.list")) + { + user.sendMessage("§cYou do not have Permission to list that warps."); + return; + } + + Warps warps = Essentials.getWarps(); + if (warps.isEmpty()) { + throw new Exception("No warps defined"); + } + StringBuilder sb = new StringBuilder(); + int i = 0; + for (String warpName : warps.getWarpNames()) + { + if (perWarpPermission) + { + if (user.isAuthorized("essentials.warp." + warpName)) + { + if (i++ > 0) sb.append(", "); + sb.append(warpName); + } + } + else + { + if (i++ > 0) sb.append(", "); + sb.append(warpName); + } + + } + user.sendMessage(sb.toString()); + return; + } + + try { + if (perWarpPermission) + { + if (user.isAuthorized("essentials.warp." + args[0])) + { + user.canAfford(this); + user.teleportCooldown(); + user.warpTo(args[0], this.getName()); + return; + } + user.sendMessage("§cYou do not have Permission to use that warp."); + return; + } + user.canAfford(this); + user.teleportCooldown(); + user.warpTo(args[0], this.getName()); + } catch (Exception ex) { + user.sendMessage(ex.getMessage()); + } + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandwhois.java b/Essentials/src/com/earth2me/essentials/commands/Commandwhois.java new file mode 100644 index 000000000..508e69a58 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandwhois.java @@ -0,0 +1,44 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import com.earth2me.essentials.Essentials; +import org.bukkit.entity.Player; +import com.earth2me.essentials.User; +import org.bukkit.ChatColor; + + +public class Commandwhois extends EssentialsCommand +{ + public Commandwhois() + { + super("whois"); + } + + @Override + public void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception + { + if (args.length < 1) + { + sender.sendMessage("§cUsage: /whois [nickname]"); + return; + } + String whois = args[0].toLowerCase(); + User.charge(sender, this); + int prefixLength = ChatColor.stripColor(Essentials.getSettings().getNicknamePrefix()).length(); + for (Player p : server.getOnlinePlayers()) + { + User u = User.get(p); + String dn = ChatColor.stripColor(u.getNick()); + if (!whois.equalsIgnoreCase(dn) && !whois.equalsIgnoreCase(dn.substring(prefixLength)) && !whois.equalsIgnoreCase(u.getName())) continue; + sender.sendMessage(""); + sender.sendMessage(u.getDisplayName() + " is " + u.getName()); + sender.sendMessage(ChatColor.BLUE + " - Health: " + u.getHealth() + "/20"); + sender.sendMessage(ChatColor.BLUE + " - Location: (" + u.getLocation().getBlockX() + ", " + u.getLocation().getBlockY() + ", " + u.getLocation().getBlockZ() + ")"); + if (!parent.getConfiguration().getBoolean("disable-eco", false)) sender.sendMessage(ChatColor.BLUE + " - Money: $" + u.getMoney()); + sender.sendMessage(ChatColor.BLUE + " - Status: " + (parent.away.contains(u) ? "§cAway" : "Available")); + sender.sendMessage(ChatColor.BLUE + " - IP Address: " + u.getAddress().getAddress().toString()); + + } + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandworld.java b/Essentials/src/com/earth2me/essentials/commands/Commandworld.java new file mode 100644 index 000000000..8f3ad45e7 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandworld.java @@ -0,0 +1,67 @@ +package com.earth2me.essentials.commands; + +import java.util.List; +import org.bukkit.Location; +import org.bukkit.Server; +import org.bukkit.World; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; + + +public class Commandworld extends EssentialsCommand +{ + public Commandworld() + { + super("world"); + } + + @Override + protected void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + World world; + List worlds = server.getWorlds(); + + if (args.length < 1) + { + world = worlds.get(user.getWorld() == worlds.get(0) && worlds.size() > 1 ? 1 : 0); + } + else + { + try + { + int wid = Integer.parseInt(args[0]); + world = server.getWorlds().get(wid); + } + catch (Throwable ex) + { + try + { + world = server.getWorld(getFinalArg(args, 0)); + if (world == null) throw new Exception(); + } + catch (Throwable ex2) + { + user.sendMessage("§cInvalid world."); + user.sendMessage("§7Possible worlds are the numbers 0 through " + (server.getWorlds().size() - 1) + "."); + user.sendMessage("§7You can also type the name of a specific world."); + return; + } + } + } + + double factor; + if (user.getWorld().getEnvironment() == World.Environment.NETHER && world.getEnvironment() == World.Environment.NORMAL) + factor = 16; + else if (user.getWorld().getEnvironment() != world.getEnvironment()) + factor = 1 / 16; + else + factor = 1; + + Location loc = user.getLocation(); + loc = new Location(world, loc.getBlockX() * factor + .5, loc.getBlockY(), loc.getBlockZ() * factor + .5); + + user.canAfford(this); + user.teleportCooldown(); + user.teleport(loc, this.getName()); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandworth.java b/Essentials/src/com/earth2me/essentials/commands/Commandworth.java new file mode 100644 index 000000000..0933ef4a2 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandworth.java @@ -0,0 +1,48 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.ItemDb; +import com.earth2me.essentials.User; +import com.earth2me.essentials.commands.EssentialsCommand; +import org.bukkit.inventory.ItemStack; + + +public class Commandworth extends EssentialsCommand +{ + public Commandworth() + { + super("worth"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + ItemStack is = user.getInventory().getItemInHand(); + int id = is.getTypeId(); + int amount = is.getAmount(); + + try + { + if (args.length > 0) id = Integer.parseInt(args[0]); + } + catch (NumberFormatException ex) + { + id = ItemDb.get(args[0]).getTypeId(); + } + + try + { + if (args.length > 1) amount = Integer.parseInt(args[1]); + } + catch (NumberFormatException ex) + { + amount = 64; + } + + int worth = parent.getConfiguration().getInt("worth-" + id, 0); + + user.charge(this); + user.sendMessage("§7Stack of " + id + " worth §c$" + (worth * amount) + "§7 (" + amount + " item(s) at $" + worth + " each)"); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/EssentialsCommand.java b/Essentials/src/com/earth2me/essentials/commands/EssentialsCommand.java new file mode 100644 index 000000000..782f48287 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/EssentialsCommand.java @@ -0,0 +1,80 @@ +package com.earth2me.essentials.commands; + +import java.util.List; +import org.bukkit.Server; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import com.earth2me.essentials.Essentials; +import org.bukkit.entity.Player; +import com.earth2me.essentials.User; + + +public abstract class EssentialsCommand implements IEssentialsCommand +{ + private final String name; + + protected EssentialsCommand(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + + public String[] getTriggers() + { + return new String[] + { + getName() + }; + } + + protected User getPlayer(Server server, String[] args, int pos) throws IndexOutOfBoundsException, NoSuchFieldException + { + if (args.length <= pos) throw new IndexOutOfBoundsException("§cInvalid command syntax. Did you forget an argument?"); + List matches = server.matchPlayer(args[pos]); + if (matches.size() < 1) throw new NoSuchFieldException("§cNo matching players could be found."); + return User.get(matches.get(0)); + } + + @Override + public final void run(Server server, Essentials parent, User user, String commandLabel, Command cmd, String[] args) throws Exception + { + run(server, parent, user, commandLabel, args); + } + + protected void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + run(server, parent, (CommandSender)user.getBase(), commandLabel, args); + } + + @Override + public final void run(Server server, Essentials parent, CommandSender sender, String commandLabel, Command cmd, String[] args) throws Exception + { + run(server, parent, sender, commandLabel, args); + } + + protected void run(Server server, Essentials parent, CommandSender sender, String commandLabel, String[] args) throws Exception + { + throw new Exception("Only in-game players can use " + commandLabel + "."); + } + + public static String getFinalArg(String[] args, int start) + { + StringBuilder bldr = new StringBuilder(); + for (int i = start; i < args.length; i++) + { + if (i != start) bldr.append(" "); + bldr.append(args[i]); + } + return bldr.toString(); + } + + protected void charge(CommandSender sender) throws Exception + { + if (sender instanceof Player) + User.get((Player)sender).charge(this); + } +} diff --git a/Essentials/src/com/earth2me/essentials/commands/IEssentialsCommand.java b/Essentials/src/com/earth2me/essentials/commands/IEssentialsCommand.java new file mode 100644 index 000000000..d1debd29d --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/IEssentialsCommand.java @@ -0,0 +1,20 @@ +package com.earth2me.essentials.commands; + +import org.bukkit.*; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import com.earth2me.essentials.*; + + +public interface IEssentialsCommand +{ + String getName(); + + String[] getTriggers(); + + void run(Server server, Essentials parent, User user, String commandLabel, Command cmd, String[] args) + throws Exception; + + void run(Server server, Essentials parent, CommandSender sender, String commandLabel, Command cmd, String[] args) + throws Exception; +} diff --git a/Essentials/src/config.yml b/Essentials/src/config.yml new file mode 100644 index 000000000..7da7426f6 --- /dev/null +++ b/Essentials/src/config.yml @@ -0,0 +1,385 @@ +############################################################ +# +------------------------------------------------------+ # +# | Notes | # +# +------------------------------------------------------+ # +############################################################ + +# If you want to use special characters in this document, such as accented letters, you MUST save the file as UTF-8, not ANSI. +# If you receive an error when Essentials loads, ensure that: +# - No tabs are present: YAML only allows spaces +# - Indents are correct: YAML heirarchy is based entirely on indentation +# - You have "escaped" all apostrophes in your text: If you want to write "don't", for example, write "don''t" instead (note the doubled apostrphe) +# - List items are prefixed with a hyphen and indented: +# lists: +# - look like this +# not: +# - like this +# - Text with symbols is enclosed in single or double quotation marks +# - CraftBukkit and Permissions have been updated: CraftBukkit and Essentials almost always line up, but sometimes other plugins fall behind CraftBukkit's multiple daily updates +# - You have saved the document as UTF-8, NOT the default, ANSI + + + + + +############################################################ +# +------------------------------------------------------+ # +# | Essentials (Global) | # +# +------------------------------------------------------+ # +############################################################ + +# A color code between 0-9 or a-f. Set to 'none' to disable. +ops-name-color: 'c' + +# The character(s) to prefix all nicknames, so that you know they are not true usernames. +nickname-prefix: '~' + +# The delay, in seconds, required between /home, /tp, etc. +teleport-cooldown: 0 + +# The delay, in seconds, before a user actually teleports. If the user moves or gets attacked in this timeframe, the teleport never occurs. +teleport-delay: 0 + +# The delay, in seconds, required between /heal attempts +heal-cooldown: 60 + +# The number of items given if the quantity parameter is left out in /item or /give. +default-stack-size: 64 + +#what to prevent from /i /give +#e.g item-spawn-blacklist: 46,11,10 +item-spawn-blacklist: + +# Whether or not to reclaim memory on player logout; this is technical, and should only be changed under special circumstances. +# This generally increases server stability unless very specific runtime configurations are used. +# HOWEVER, it is known to cause lag upon users logging OUT, so beware! +reclaim-onlogout: false + +# Should primitive spawn protection be enabled? For most servers, this should be flase; it is better to use a third-party plugin to protect it. +spawn-protection: false + +# Nether settings (switch between worlds with "/world nether" and "/world normal") +# Sets whether the nether system is enabled, what folder to save the world in, and whether portals should teleport players between worlds. +nether: + enabled: false + folder: nether + portals-enabled: false + generate-exit-portals: false + +# Mob limit on spawnmob +spawnmob-limit: 10 + +# The message of the day, displayed on connect and by typing /motd. +motd: + - '&cWelcome, {PLAYER}&c!' + - '&fType &c/help&f for a list of commands.' + - 'Currently online: {PLAYERLIST}' + +# The server rules, available by typing /rules +rules: + - '[1] Be respectful' + - '[2] Be ethical' + - '[3] Use common sense' + +# Disabled commands will be completelly unavailable on the server. +disabled-commands: +# - nick + +# Restricted commands will only be available to ops. +# These will have NO EFFECT if you have Permissions installed! +# These are here only if you want something simpler than Permissions. +restricted-commands: + - bigtree + - item + - give + - heal + - plugin + - time + - top + - tp + - tphere + - tree + - setspawn + - antioch + - kick + - ban + - unban + - top + - jump + - tpo + - tppos + - tpohere + - economy + - setwarp + - delwarp + - essentials + - gc + - spawnmob + - broadcast + - burn + - ext + - kill + - ping + - banip + - unban + - mute + - kick + - kickall + - unbanip + - togglejail + - setjail + +# Note: All items MUST be followed by a quantity! +# Times are measured in seconds. +kits: + tools: + delay: 10 + items: + - 277 1 + - 278 1 + - 279 1 + +# Disable all signs +signs-disabled: false + +# Backup runs a command while saving is disabled +backup: + # Interval in minutes + interval: 60 + # Add a command that backups your data, e.g. + # command: 'rdiff-backup World1 backups/World1' + +# Set this true to enable permission per warp. +per-warp-permission: false + +# Sort output of /list command by groups +sort-list-by-groups: false + +############################################################ +# +------------------------------------------------------+ # +# | EssentialsHome | # +# +------------------------------------------------------+ # +############################################################ + +# When users die, should they respawn at their homes, instead of the spawnpoint? +respawn-at-home: false + +# When a user interacts with a bed, should their home be set to that location? +# If you enable this and remove default user access to the /sethome command, you can make beds the only way for players to set their home location. +bed-sethome: false + + + + +############################################################ +# +------------------------------------------------------+ # +# | EssentialsEco | # +# +------------------------------------------------------+ # +############################################################ + +# Defines the balance with which new players begin. Defaults to 0. +starting-balance: 0 + +# worth-# defines the value of an item when it is sold to the server via /sell. +#worth-1: 1 +#worth-278: 1000 + +# Defines the cost to use the given commands PER USE +command-costs: + # /example costs $1000 PER USE + #example: 1000 + # /kit tools costs $1500 PER USE + # kit-tools: 1500 + + + + + +############################################################ +# +------------------------------------------------------+ # +# | EssentialsHelp | # +# +------------------------------------------------------+ # +############################################################ + +#Show other plugins commands in help +non-ess-in-help: true + + + + + +############################################################ +# +------------------------------------------------------+ # +# | EssentialsServerlist | # +# +------------------------------------------------------+ # +############################################################ + +# This is your server's mcserverlist.net API key. Register your server at mcserverlist.net if you haven't already. +mcsl-key: '' + + + + + +############################################################ +# +------------------------------------------------------+ # +# | EssentialsChat | # +# +------------------------------------------------------+ # +############################################################ + +# If EssentialsChat is installed, this will define how far a player's voice travels, in blocks. Set to 0 to make all chat global. +# Note that users with the "essentials.chat.spy" permission will hear everything, regardless of this setting. +# Users with essentials.chat.shout can override this by prefixing text with an exclamation mark (!) +# Or with essentials.chat.question can override this by prefixing text with a question mark (?) +chat: + radius: 0 + + # If you want the default chat format, uncomment the next line and comment the other format. + #format: '<{DISPLAYNAME}> {MESSAGE}' + format: '&7[{GROUP}]&f {DISPLAYNAME}&7:&f {MESSAGE}' + + # You can also have group-specific formats: + group-formats: + Default: '{WORLDNAME} {DISPLAYNAME}&7:&f {MESSAGE}' + Admins: '{WORLDNAME} &c[{GROUP}]&f {DISPLAYNAME}&7:&c {MESSAGE}' + + + + + +############################################################ +# +------------------------------------------------------+ # +# | EssentialsProtect | # +# +------------------------------------------------------+ # +############################################################ + +protect: + # Database settings for sign/rail protection + # get mysql.jar and sqlite and place it in your serverroot/lib directory from here: + # http://java.net/projects/essentials/sources/svn/show/lib?rev=435 + + # mysql, sqlite or none + datatype: 'sqlite' + + # If you specified MySQL above, you MUST enter the appropriate details here. + # If you specified SQLite above, these will be IGNORED. + username: 'root' + password: 'root' + mysqlDb: 'jdbc:mysql://localhost:3306/minecraft' + + # For which block types would you like to be alerted? + # You can find a list of IDs in plugins/Essentials/Items.csv after loading Essentials for the first time. + alert: + # 10: lava + # 11: still lava + # 46: TNT + on-placement: 10,11,46 + # 1: rock (just an example--doesn't actually do much) + on-use: 1 + # 46: TNT + on-break: 46 + + # Users cannot PLACE these types of blocks/items. + # < 255 designates a BLOCK + # > 255 designates an ITEM (Some blocks can be placed as blocks OR items; lava blocks can be placed by lava buckets, for example.) + blacklist: + placement: 327,326,14,56,46,11,10,9,8 + usage: 327,326,325 + + #prevent people from breaking blocks + #break: 20,50 + break: + + + # General physics/behavior modifications + prevent: + lava-flow: false + water-flow: false + water-bucket-flow: false + fire-spread: false + lava-fire-spread: false + flint-fire: false + tnt-explosion: false + creeper-explosion: false + creeper-playerdamage: false + creeper-blockdamage: false + # Prevent the spawning of creatures + spawn: + creeper: false + ghast: true + slime: true + + # Maximum height the creeper should explode. -1 allows them to explode everywhere. + # Set prevent.creeper-explosion to true, if you want to disable creeper explosions. + creeper: + max-height: -1 + + # Protect various blocks. + protect: + # Protect all signs + signs: true + + # Prevent users from destroying rails + rails: true + + # Blocks below rails/signs are also protected if the respective rail/sign is protected. + # This makes it more difficult to circumvent protection, and should be enabled. + # This only has an effect if "rails" or "signs" is also enabled. + block-below: true + + # Prevent placing blocks above protected rails, this is to stop a potential griefing + prevent-block-on-rails: false + + # Disable various default physics and behaviors + disable: + # Should fall damage be disabled? + fall: false + + # Users with the essentials.protect.pvp permission will still be able to attack each other if this is set to true. + # They will be unable to attack users without that same permission node. + pvp: false + + # Should drowning damage be disabled? + # (Split into two behaviors; generally, you want both set to the same value) + drown: false + suffocate: false + + # Should damage via lava be disabled? Items that fall into lava will still burn to a crisp. ;) + lavadmg: false + + # Should arrow damage be disabled + projectiles: false + + # This will disable damage from touching cacti. + contactdmg: false + + # Burn, baby, burn! Should fire damage be disabled? + firedmg: false + + # Should people with build: false in permissions be allowed to build + # Set true to disable building for those people + build: false + + + + + + + +############################################################ +# +------------------------------------------------------+ # +# | New Players | # +# +------------------------------------------------------+ # +############################################################ + +newbies: + # Should we announce to the server when someone logs in for the first time? + # If so, use this format, replacing {DISPLAYNAME} with the player name. + # If not, set to '' + #announce-format: '' + announce-format: '&dWelcome {DISPLAYNAME} to the server!' + + # When we spawn for the first time, which spawnpoint do we use? + spawnpoint: newbies + +# End of File <-- No seriously, you're done with configuration. \ No newline at end of file diff --git a/Essentials/src/items.csv b/Essentials/src/items.csv new file mode 100644 index 000000000..3bf204167 --- /dev/null +++ b/Essentials/src/items.csv @@ -0,0 +1,887 @@ +#item,id,metadata +air,0,0 +stone,1,0 +rock,1,0 +grass,2,0 +dirt,3,0 +cobblestone,4,0 +cstone,4,0 +cobble,4,0 +plank,5,0 +woodplank,5,0 +wplank,5,0 +sapling,6,0 +bedrock,7,0 +admin,7,0 +adminium,7,0 +water,8,0 +stationarywater,9,0 +swater,9,0 +lava,10,0 +stationarylava,11,0 +slava,11,0 +sand,12,0 +gravel,13,0 +goldore,14,0 +gore,14,0 +ironore,15,0 +iore,15,0 +coalore,16,0 +core,16,0 +log,17,0 +trunk,17,0 +wood,17,0 +redwood,5,1 +rwood,5,1 +birchwood,5,2 +birch,5,2 +bwood,5,2 +leaves,18,0 +sponge,19,0 +glass,20,0 +lapislazuliore,21,0 +lapisore,21,0 +lore,21,0 +lapislazuliblock,22,0 +lapisblock,22,0 +lblock,22,0 +dispenser,23,0 +dispense,23,0 +sandstone,24,0 +sstone,24,0 +noteblock,25,0 +musicblock,25,0 +nblock,25,0 +mblock,25,0 +bedblock,26,0 +whitecloth,35,0 +cloth,35,0 +whitewool,35,0 +wool,35,0 +whitecotton,35,0 +cotton,35,0 +orangecloth,35,1 +orangewool,35,1 +orangecotton,35,1 +magentacloth,35,2 +magentawool,35,2 +magantacotton,35,2 +lightbluecloth,35,3 +lightbluewool,35,3 +lightbluecotton,35,3 +lbluecloth,35,3 +lbluewool,35,3 +lbluecotton,35,3 +yellowcloth,35,4 +yellowwool,35,4 +yellowcotton,35,4 +lightgreencloth,35,5 +lightgreenwool,35,5 +lightgreencotton,35,5 +lgreencloth,35,5 +lgreenwool,35,5 +lgreencotton,35,5 +pinkcloth,35,6 +pinkwool,35,6 +pinkcotton,35,6 +graycloth,35,7 +graywool,35,7 +graycotton,35,7 +lightgraycloth,35,8 +lightgraywool,35,8 +lightgraycotton,35,8 +lgraycloth,35,8 +lgraywool,35,8 +lgraycotton,35,8 +cyancloth,35,9 +cyanwool,35,9 +cyancotton,35,9 +purplecloth,35,10 +purplewool,35,10 +purplecotton,35,10 +bluecloth,35,11 +bluewool,35,11 +bluecotton,35,11 +browncloth,35,12 +brownwool,35,12 +browncotton,35,12 +darkgreencloth,35,13 +darkgreenwool,35,13 +darkgreencotton,35,13 +dgreencloth,35,13 +dgreenwool,35,13 +dgreencotton,35,13 +greencloth,35,13 +greenwool,35,13 +greencotton,35,13 +redcloth,35,14 +redwool,35,14 +redcotton,35,14 +blackcloth,35,15 +blackwool,35,15 +blackcotton,35,15 +yellowflower,37,0 +yflower,37,0 +flower,37,0 +redrose,38,0 +rrose,38,0 +redflower,38,0 +rflower,38,0 +brownmushroom,39,0 +brownmush,39,0 +bmushroom,39,0 +bmush,39,0 +redmushroom,40,0 +redmush,40,0 +rmushroom,40,0 +rmush,40,0 +goldblock,41,0 +gblock,41,0 +ironblock,42,0 +iblock,42,0 +smoothstonedoublestep,43,0 +stonedoublestep,43,0 +sdoublestep,43,0 +sdstep,43,0 +doublestep,43,0 +step,43,0 +smoothstonedoubleslab,43,0 +stonedoubleslab,43,0 +sdoubleslab,43,0 +sdslab,43,0 +doubleslab,43,0 +slab,43,0 +sanddstonedoublestep,43,1 +sstonedoublestep,43,1 +ssdoublestep,43,1 +ssdstep,43,1 +sanddstonedoubleslab,43,1 +sstonedoubleslab,43,1 +ssdoubleslab,43,1 +ssdslab,43,1 +woodplankdoublestep,43,2 +wplankdoublestep,43,2 +plankdoublestep,43,2 +wpdoublestep,43,2 +pdoublestep,43,2 +wpdstep,43,2 +pdstep,43,2 +woodplankdoubleslab,43,2 +wplankdoubleslab,43,2 +plankdoubleslab,43,2 +wpdoubleslab,43,2 +pdoubleslab,43,2 +wpdslab,43,2 +pdslab,43,2 +cobblestonedoublestep,43,3 +cobbledoublestep,43,3 +cstonedoublestep,43,3 +csdoublestep,43,3 +csdstep,43,3 +cobblestonedoubleslab,43,3 +cobbledoubleslab,43,3 +cstonedoubleslab,43,3 +csdoubleslab,43,3 +csdslab,43,3 +smoothstonestep,44,0 +stonestep,44,0 +sstep,44,0 +step,44,0 +smoothstoneslab,44,0 +stoneslab,44,0 +sslab,44,0 +slab,44,0 +sanddstonestep,44,1 +sstonestep,44,1 +ssstep,44,1 +sanddstoneslab,44,1 +sstoneslab,44,1 +ssslab,44,1 +woodplankstep,44,2 +wplankstep,44,2 +plankstep,44,2 +wpstep,44,2 +pstep,44,2 +woodplankslab,44,2 +wplankslab,44,2 +plankslab,44,2 +wpslab,44,2 +pslab,44,2 +cobblestonestep,44,3 +cobblestep,44,3 +cstonestep,44,3 +csstep,44,3 +cobblestoneslab,44,3 +cobbleslab,44,3 +cstoneslab,44,3 +csslab,44,3 +brickblock,45,0 +bblock,45,0 +tnt,46,0 +bookshelf,47,0 +bookblock,47,0 +mossycobblestone,48,0 +mosscobblestone,48,0 +mcobblestone,48,0 +mossycobble,48,0 +mosscobble,48,0 +mcobble,48,0 +obsidian,49,0 +obsi,49,0 +obby,49,0 +torch,50,0 +fire,51,0 +mobspawner,52,0 +monsterspawner,52,0 +mspawner,52,0 +spawner,52,0 +woodenstairs,53,0 +woodstairs,53,0 +wstairs,53,0 +chest,54,0 +redstonewireblock,55,0 +rstonewireblock,55,0 +redswireblock,55,0 +redwireblock,55,0 +rswireblock,55,0 +rwireblock,55,0 +redstonewire,55,0 +rstonewire,55,0 +redswire,55,0 +redwire,55,0 +rswire,55,0 +rwire,55,0 +diamondore,56,0 +dore,56,0 +diamondblock,57,0 +dblock,57,0 +workbench,58,0 +craftingbench,58,0 +crafterbench,58,0 +craftbench,58,0 +worktable,58,0 +craftingtable,58,0 +craftertable,58,0 +crafttable,58,0 +wbench,58,0 +cbench,58,0 +crops,59,0 +crop,59,0 +soil,60,0 +furnace,61,0 +burningfurnace,62,0 +bfurnace,62,0 +signpost,63,0 +spost,63,0 +woodendoorhalf,64,0 +wooddoorhalf,64,0 +wdoorhalf,64,0 +woodendoorbottom,64,0 +wooddoorbottom,64,0 +wdoorbottom,64,0 +woodendoorblock,64,0 +wooddoorblock,64,0 +wdoorblock,64,0 +ladder,65,0 +minecarttrack,66,0 +minecartrail,66,0 +mcarttrack,66,0 +mcartrail,66,0 +mctrack,66,0 +mcrail,66,0 +track,66,0 +rail,66,0 +cobblestonestairs,67,0 +cstonestairs,67,0 +stonestairs,67,0 +cobblestairs,67,0 +csstairs,67,0 +sstairs,67,0 +cstairs,67,0 +cobblestonestair,67,0 +cstonestair,67,0 +stonestair,67,0 +cobblestair,67,0 +csstair,67,0 +sstair,67,0 +cstair,67,0 +wallsign,68,0 +wsign,68,0 +lever,69,0 +stonepressureplate,70,0 +stonepressplate,70,0 +stonepplate,70,7 +stoneplate,70,0 +splate,70,0 +irondoorhalf,71,0 +idoorhalf,71,0 +irondoorbottom,71,0 +idoorbottom,71,0 +irondoorblock,71,0 +idoorblock,71,0 +woodenpressureplate,72,0 +woodenpressplate,72,0 +woodenpplate,72,0 +woodenplate,72,0 +woodpressureplate,72,0 +woodpressplate,72,0 +woodpplate,72,0 +woodplate,72,0 +wplate,72,0 +redstoneore,73,0 +redsore,73,0 +redore,73,0 +rstoneore,73,0 +rsore,73,0 +glowingredstoneore,74,0 +glowredstoneore,74,0 +gredstoneore,74,0 +glowingrstoneore,74,0 +glowrstoneore,74,0 +grstoneore,74,0 +glowingredsore,74,0 +glowredsore,74,0 +gredsore,74,0 +glowingredore,74,0 +glowredore,74,0 +gredore,74,0 +glowingrsore,74,0 +glowrsore,74,0 +grsore,74,0 +redstonetorchoff,75,0 +rstonetorchoff,75,0 +redstorchoff,75,0 +redtorchoff,75,0 +rstorchoff,75,0 +redstonetorchon,76,0 +redstonetorch,76,0 +rstonetorchon,76,0 +rstonetorch,76,0 +redstorchon,76,0 +redstorch,76,0 +redtorchon,76,0 +redtorch,76,0 +rstorchon,76,0 +rstorch,76,0 +stonebutton,77,0 +sbutton,77,0 +button,77,0 +snowcovering,78,0 +snowcover,78,0 +scover,78,0 +ice,79,0 +snowblock,80,0 +sblock,80,0 +cactus,81,0 +clayblock,82,0 +cblock,82,0 +reedblock,83,0 +rblock,83,0 +jukebox,84,0 +jbox,84,0 +fence,85,0 +pumpkin,86,0 +netherrack,87,0 +netherrock,87,0 +netherstone,87,0 +hellstone,87,0 +nstone,87,0 +hstone,87,0 +soulsand,88,0 +slowsand,88,0 +slowmud,88,0 +ssand,88,0 +smud,88,0 +mud,88,0 +glowingstone,89,0 +glowstone,89,0 +lightstone,89,0 +lstone,89,0 +portal,90,0 +jackolantern,91,0 +pumpkinlantern,91,0 +glowingpumpkin,91,0 +lightpumpkin,91,0 +jpumpkin,91,0 +plantren,91,0 +glowpumpkin,91,0 +gpumpkin,91,0 +lpumpkin,91,0 +cakeblock,92,0 +repeateroff,93,0 +repeatoff,93,0 +delayeroff,93,0 +delayoff,93,0 +dioderoff,93,0 +diodeoff,93,0 +repeateron,94,0 +repeaton,94,0 +delayeron,94,0 +delayon,94,0 +dioderon,94,0 +diodeon,94,0 +ironshovel,256,0 +ironspade,256,0 +ishovel,256,0 +ispade,256,0 +ironpickaxe,257,0 +ironpick,257,0 +ipickaxe,257,0 +ipick,257,0 +ironaxe,258,0 +iaxe,258,0 +flintandsteel,259,0 +lighter,259,0 +apple,260,0 +bow,261,0 +arrow,262,0 +coal,263,0 +diamond,264,0 +ironingot,265,0 +ironbar,265,0 +iingot,265,0 +ibar,265,0 +goldingot,266,0 +goldbar,266,0 +gingot,266,0 +gbar,266,0 +ironsword,267,0 +isword,267,0 +woodensword,268,0 +woodsword,268,0 +wsword,268,0 +woodenshovel,269,0 +woodenspade,269,0 +woodshovel,269,0 +woodspade,269,0 +wshovel,269,0 +wspade,269,0 +woodenpickaxe,270,0 +woodenpick,270,0 +woodpickaxe,270,0 +woodpick,270,0 +wpickaxe,270,0 +wpick,270,0 +woodenaxe,271,0 +woodaxe,271,0 +waxe,271,0 +stonesword,272,0 +ssword,272,0 +stoneshovel,273,0 +stonespade,273,0 +sshovel,273,0 +sspade,273,0 +stonepickaxe,274,0 +stonepick,274,0 +spickaxe,274,0 +spick,274,0 +stoneaxe,275,0 +saxe,275,0 +diamondsword,276,0 +dsword,276,0 +diamondshovel,277,0 +diamondspade,277,0 +dshovel,277,0 +dspade,277,0 +diamondpickaxe,278,0 +diamondpick,278,0 +dpickaxe,278,0 +dpick,278,0 +diamondaxe,279,0 +daxe,279,0 +stick,280,0 +bowl,281,0 +mushroomsoup,282,0 +mrsoup,282,0 +soup,282,0 +goldsword,283,0 +gsword,283,0 +goldshovel,284,0 +goldspade,284,0 +gshovel,284,0 +gspade,284,0 +goldpickaxe,285,0 +goldpick,285,0 +gpickaxe,285,0 +gpick,285,0 +goldaxe,286,0 +gaxe,286,0 +string,287,0 +rope,287,0 +feather,288,0 +gunpowder,289,0 +sulfur,289,0 +woodenhoe,290,0 +woodhoe,290,0 +whoe,290,0 +stonehoe,291,0 +shoe,291,0 +ironhoe,292,0 +ihoe,292,0 +diamondhoe,293,0 +dhoe,293,0 +goldhoe,294,0 +ghoe,294,0 +seeds,295 +seed,295,0 +wheat,296,0 +bread,297,0 +leatherhelmet,298,0 +leatherhelm,298,0 +leatherhat,298,0 +lhelmet,298,0 +lhelm,298,0 +lhat,298,0 +leatherchestplate,299,0 +leatherplatebody,299,0 +leatherplate,299,0 +leathershirt,299,0 +lchestplate,299,0 +lplatebody,299,0 +lplate,299,0 +lshirt,299,0 +leatherleggings,300,0 +leatherlegs,300,0 +leatherpants,300,0 +lleggings,300,0 +llegs,300,0 +lpants,300,0 +leatherboots,301,0 +leathershoes,301,0 +lboots,301,0 +lshoes,301,0 +chainmailhelmet,302,0 +chainmailhelm,302,0 +chainmailhat,302,0 +chainmhelmet,302,0 +chainmhelm,302,0 +chainmhat,302,0 +cmailhelmet,302,0 +cmailhelm,302,0 +cmailhat,302,0 +chainhelmet,302,0 +chainhelm,302,0 +chainhat,302,0 +cmhelmet,302,0 +cmhelm,302,0 +cmhat,302,0 +chelmet,302,0 +chelm,302,0 +chat,302,0 +chainmailchestplate,303,0 +chainmailplatebody,303,0 +chainmailplate,303,0 +chainmailshirt,303,0 +chainmchestplate,303,0 +chainmplatebody,303,0 +chainmplate,303,0 +chainmshirt,303,0 +cmailchestplate,303,0 +cmailplatebody,303,0 +cmailplate,303,0 +cmailshirt,303,0 +chainchestplate,303,0 +chainplatebody,303,0 +chainplate,303,0 +chainshirt,303,0 +cmchestplate,303,0 +cmplatebody,303,0 +cmplate,303,0 +cmshirt,303,0 +clchestplate,303,0 +cplatebody,303,0 +cplate,303,0 +cshirt,303,0 +chainmailleggings,304,0 +chainmaillegs,304,0 +chainmailpants,304,0 +chainmleggings,304,0 +chainmlegs,304,0 +chainmpants,304,0 +cmailleggings,304,0 +cmaillegs,304,0 +cmailpants,304,0 +chainleggings,304,0 +chainlegs,304,0 +chainpants,304,0 +cmleggings,304,0 +cmlegs,304,0 +cmpants,304,0 +cleggings,304,0 +clegs,304,0 +cpants,304,0 +chainmailboots,305,0 +chainmailshoes,305,0 +chainmboots,305,0 +chainmshoes,305,0 +cmailboots,305,0 +cmailshoes,305,0 +chainboots,305,0 +chainshoes,305,0 +cmboots,305,0 +cmshoes,305,0 +cboots,305,0 +cshoes,305,0 +ironhelmet,306,0 +ironhelm,306,0 +ironhat,306,0 +ihelmet,306,0 +ihelm,306,0 +ihat,306,0 +ironchestplate,307,0 +ironplatebody,307,0 +ironplate,307,0 +ironshirt,307,0 +ichestplate,307,0 +iplatebody,307,0 +iplate,307,0 +ishirt,307,0 +ironleggings,308,0 +ironlegs,308,0 +ironpants,308,0 +ileggings,308,0 +ilegs,308,0 +ipants,308,0 +ironboots,309,0 +ironshoes,309,0 +iboots,309,0 +ishoes,309,0 +diamondhelmet,310,0 +diamondhelm,310,0 +diamondhat,310,0 +dhelmet,310,0 +dhelm,310,0 +dhat,310,0 +diamondchestplate,311,0 +diamondplatebody,311,0 +diamondplate,311,0 +diamondshirt,311,0 +dchestplate,311,0 +dplatebody,311,0 +dplate,311,0 +dshirt,311,0 +diamondleggings,312,0 +diamondlegs,312,0 +diamondpants,312,0 +dleggings,312,0 +dlegs,312,0 +dpants,312,0 +diamondboots,313,0 +diamondshoes,313,0 +dboots,313,0 +dshoes,313,0 +goldhelmet,314,0 +goldhelm,314,0 +goldhat,314,0 +ghelmet,314,0 +ghelm,314,0 +ghat,314,0 +goldchestplate,315,0 +goldplatebody,315,0 +goldplate,315,0 +goldshirt,315,0 +gchestplate,315,0 +gplatebody,315,0 +gplateplate,315,0 +gshirt,315,0 +goldleggings,316,0 +goldlegs,316,0 +goldpants,316,0 +gleggings,316,0 +glegs,316,0 +gpants,316,0 +goldboots,317,0 +goldshoes,317,0 +gboots,317,0 +gshoes,317,0 +flint,318,0 +pork,319,0 +rawpork,319,0 +grilledpork,320,0 +cookedpork,320,0 +bacon,320,0 +painting,321,0 +picture,321,0 +goldenapple,322,0 +goldapple,322,0 +gapple,322,0 +sign,323,0 +woodendoor,324,0 +wooddoor,324,0 +wdoor,324,0 +bucket,325,0 +waterbucket,326,0 +wbucket,326,0 +lavabucket,327,0 +lbucket,327,0 +minecart,328,0 +mcart,328,0 +cart,328,0 +saddle,329,0 +irondoor,330,0 +idoor,330,0 +redstone,331,0 +rstone,331,0 +snowball,332,0 +snball,332,0 +boat,333,0 +leather,334,0 +milkbucket,335,0 +mbucket,335,0 +claybrick,336,0 +brick,336,0 +clayball,337,0 +cball,337,0 +clay,337,0 +reeds,338,0 +reed,338,0 +paper,339,0 +papyrus,339,0 +book,340,0 +slimeball,341,0 +slball,341,0 +storageminecart,342,0 +chestminecart,342,0 +storagemcart,342,0 +chestmcart,342,0 +storagecart,342,0 +chestcart,342,0 +sminecart,342,0 +cminecart,342,0 +smcart,342,0 +cmcart,342,0 +scart,342,0 +ccart,342,0 +engineminecart,343,0 +poweredminecart,343,0 +powerminecart,343,0 +furnaceminecart,343,0 +enginemcart,343,0 +poweredmcart,343,0 +powermcart,343,0 +furnacemcart,343,0 +enginecart,343,0 +poweredcart,343,0 +powercart,343,0 +furnacecart,343,0 +eminecart,343,0 +pminecart,343,0 +fminecart,343,0 +emcart,343,0 +pmcart,343,0 +cmcart,343,0 +ecart,343,0 +pcart,343,0 +fcart,343,0 +egg,344,0 +compass,345,0 +fishingrod,346,0 +fishrod,346,0 +frod,346,0 +rod,346,0 +watch,347,0 +clock,347,0 +lightstonedust,348,0 +glowstonedust,348,0 +lsdust,348,0 +gsdust,348,0 +rawfish,349,0 +rfish,349,0 +fish,349,0 +cookedfish,350,0 +cookfish,350,0 +cfish,350,0 +roastedfish,350,0 +roastfish,350,0 +rfish,350,0 +inksack,351,0 +inksac,351,0 +isack,351,0 +isac,351,0 +sack,351,0 +sac,351,0 +blackcolor,351,0 +blackdye,351,0 +rosered,351,1 +redrose,351,1 +redr,351,1 +redcolor,351,1 +reddye,351,1 +cactusgreen,351,2 +greencactus,351,2 +greencolor,351,2 +greendye,351,2 +cocobeans,351,3 +cocobean,351,3 +cbeans,351,3 +cbean,351,3 +beans,351,3 +bean,351,3 +browncocobeans,351,3 +browncocobean,351,3 +browncbeans,351,3 +browncbean,351,3 +brownbeans,351,3 +brownbean,351,3 +brownb,351,3 +browncolor,351,3 +browndye,351,3 +bluelapislzuli,351,4 +bluelapisl,351,4 +bluelapis,351,4 +bluel,351,4 +lapislzuli,351,4 +lapisl,351,4 +lapis,351,4 +bluecolor,351,4 +bluedye,351,4 +purplecolor,351,5 +purpledye,351,5 +cyancolor,351,6 +cyandye,351,6 +lightgraycolor,351,7 +lightgraydye,351,7 +lgraycolor,351,7 +lgraydye,351,7 +graycolor,351,8 +graydye,351,8 +pinkcolor,351,9 +pinkdye,351,9 +limecolor,351,10 +limedye,351,10 +dandelionyellow,351,11 +yellowdandelion,351,11 +yellowd,351,11 +yellowcolor,351,11 +yellowdye,351,11 +lightbluecolor,351,12 +lightbluedye,351,12 +lbluecolor,351,12 +lbluedye,351,12 +magentacolor,351,13 +magentadye,351,13 +orangecolor,351,14 +orangedye,351,14 +whitebonemeal,351,15 +whitebonem,351,15 +bonemeal,351,15 +bonem,351,15 +whitecolor,351,15 +whitedye,351,15 +bone,352,0 +sugar,353,0 +cake,354,0 +bed,355,0 +repeater,356,0 +repeat,356,0 +delayer,356,0 +delay,356,0 +diode,356,0 +goldrecord,2256,0 +golddisk,2256,0 +gorecord,2256,0 +godisk,2256,0 +greenrecord,2257,0 +greendisk,2257,0 +grrecord,2257,0 +grdisk,2257,0 \ No newline at end of file diff --git a/Essentials/src/plugin.yml b/Essentials/src/plugin.yml new file mode 100644 index 000000000..30e1f2cc3 --- /dev/null +++ b/Essentials/src/plugin.yml @@ -0,0 +1,248 @@ +# This determines the command prefix when there are conflicts (/name:home, /name:help, etc.) +name: Essentials +main: com.earth2me.essentials.Essentials +# Note to developers: This next line cannot change, or the automatic versioning system will break. +version: TeamCity +website: http://www.earth2me.net:8001/ +description: Provides an essential, core set of commands for Bukkit. +authors: [Zenexer, ementalo, Aelux, Brettflan, KimKandor, snowleo] +commands: + afk: + description: Marks you as away-from-keyboard. + usage: / + antioch: + description: 'A little surprise for operators. Warning: Point away from face.' + usage: / + back: + description: Teleports you to your location prior to teleporting/spawning/warping. + usage: / + backup: + description: Runs the backup command + usage: / + balance: + description: States the current balance of a player. Defaults to self. + usage: / + aliases: bal,money + ban: + description: Bans a player. + usage: / [player] + banip: + description: Bans an IP address. + usage: / [address] + broadcast: + description: Broadcasts a message to the entire server. + usage: / [msg] + bigtree: + description: Spawn a big tree where you are looking. + usage: / [tree|redwood] + burn: + description: Set a player on fire. + usage: / [player] [seconds] + clearinventory: + description: Clear all items in your inventory. + usage: / + compass: + description: Describes your current bearing. + usage: / + deljail: + description: Removes a jail + usage: / [jailname] + delwarp: + description: Deletes the specified warp. + usage: / [warp] + aliases: [remwarp,rmwarp] + depth: + description: States current depth, relative to sea level. + usage: /depth + eco: + description: Manages the server economy. + usage: / [give|take|reset] [player] [amount] + aliases: economy + essentials: + description: Reloads essentials. + usage: / + ext: + description: Extinguish players. + usage: / + getpos: + description: Get your current coordinates. + usage: / + aliases: [coords] + gc: + description: Reports garbage collection info; useful to plugin/CraftBukkit developers + usage: / + aliases: [mem,memory] + give: + description: Give a player an item. + usage: / [player] [item|numeric] + god: + description: Enables your godly powers. + usage: / + aliases: [tgm,godmode] + heal: + description: Heals you or the given player. + usage: / + help: + description: Views a list of available commands. + usage: / + helpop: + description: Request help from online operators. + usage: / [message] + home: + description: Teleport to your home. + usage: / + invsee: + description: See the inventory of other players. + usage: / + item: + description: Spawn an item. + usage: / [item|numeric] + aliases: [i] + jails: + description: List all jails. + usage: / + jump: + description: Jumps to the nearest block in the line of sight. + usage: / + aliases: [j] + kick: + description: Kicks a specified player with a reason. + usage: / + kickall: + description: Kicks all players off the server except the issuer. + usage: / + kit: + description: Obtains the specified kit or views all available kits. + usage: / + kill: + description: Kills specified player. + usage: / + list: + description: List all online players. + usage: / + aliases: [playerlist,who,online] + mail: + description: Manages inter-player, intra-server mail. + usage: / [read|clear|send [to] [message]] + me: + description: Describes an action in the context of the player. + usage: / [description] + motd: + description: Views the Message Of The Day. + usage: / + msg: + description: Sends a private message to the specified player. + usage: / + aliases: [m,t] + mute: + description: Mutes or unmutes a player. + usage: / [player] + nick: + description: Change your nickname or that of another player. + usage: / [nickname|off] + nuble: + description: Used by Nuble to request permission for takeoff. + usage: / identify [id] + pay: + description: Pays another player from your balance + usage: / [player] [amount] + ping: + description: Pong! + usage: / + aliases: [pong] + plugin: + description: Enables, disables, or reloads a plugin. + usage: / [enable|disable|reload] [plugin] + r: + description: Quickly reply to the last player to message you. + usage: / [message] + rules: + description: Views the server rules. + usage: / + reloadall: + description: Reloads all plugins. + usage: / + aliases: [rel] + sell: + description: Sells the item currently in your hand. + usage: / <-> + sethome: + description: Set your home to your current location. + usage: / + setjail: + description: Creates a jail where you specified named [jailname] + usage: / [jailname] + setwarp: + description: Creates a new warp. + usage: / [warp] + aliases: [createwarp] + spawnmob: + description: Spawns a mob. + usage: / [mob],: + suicide: + description: Causes you to perish + usage: / + time: + description: Change the server time to day or night. + usage: / [day|night] + togglejail: + description: Prevents a player from interacting with the world and teleports him/her to the the jail specified + usage: / [player] [jailname] + aliases: [tjail] + top: + description: Teleport to the highest block at your current coordinates. + usage: / + tp: + description: Teleport to a player. + usage: / [player] + tpa: + description: Request to teleport to the specified player. + usage: / + tpaccept: + description: Accepts a teleport request. + usage: / + tpahere: + description: Request that the specified player teleport to you. + usage: / + tpdeny: + description: Reject a teleport request. + usage: / + tphere: + description: Teleport a player to you. + usage: / [player] + aliases: s + tpo: + description: Teleport override for tptoggle. + usage: / + tpohere: + description: Teleport here override for tptoggle. + usage: / + tppos: + description: Teleport to coordinates. + usage: / + tptoggle: + description: Blocks all forms of teleportation. + usage: / + tree: + description: Spawn a tree where you are looking. + usage: / [tree|birch|redwood] + unban: + description: Unbans the specified player. + usage: / [player] + aliases: pardon + unbanip: + description: Unbans the specified IP address. + usage: / [address] + aliases: pardonip + warp: + description: List all warps or warp to the specified location. + usage: / + whois: + description: Determine the username behind a nickname. + usage: / [nickname] + world: + description: Switch between worlds. + usage: / [world] + worth: + description: Calculates the worth of items in hand or as specified. + usage: / \ No newline at end of file diff --git a/Essentials/test/com/earth2me/essentials/EssentialsTest.java b/Essentials/test/com/earth2me/essentials/EssentialsTest.java new file mode 100644 index 000000000..da98978df --- /dev/null +++ b/Essentials/test/com/earth2me/essentials/EssentialsTest.java @@ -0,0 +1,60 @@ +package com.earth2me.essentials; + +import junit.framework.TestCase; + + +public class EssentialsTest extends TestCase +{ + public EssentialsTest(String testName) + { + super(testName); + } + + private static void should(String what) + { + System.out.println("Essentials should " + what); + } + + @Override + protected void setUp() throws Exception + { + super.setUp(); + } + + @Override + protected void tearDown() throws Exception + { + super.tearDown(); + } + + public void testLoadClasses() + { + should("make all classes accessible"); + Essentials.loadClasses(); + try + { + ItemDb itemDb = null; + Mob mob = null; + NetherPortal netherPortal = null; + OfflinePlayer offlinePlayer = null; + Settings settings = null; + Spawn spawn = null; + TargetBlock targetBlock = null; + TeleportTimer teleportTimer = null; + User user = null; + assertNull(itemDb); + assertNull(mob); + assertNull(netherPortal); + assertNull(offlinePlayer); + assertNull(settings); + assertNull(spawn); + assertNull(targetBlock); + assertNull(teleportTimer); + assertNull(user); + } + catch (Throwable ex) + { + fail(ex.toString()); + } + } +} diff --git a/Essentials/test/com/earth2me/essentials/PermissionsTest.java b/Essentials/test/com/earth2me/essentials/PermissionsTest.java new file mode 100644 index 000000000..a630edf85 --- /dev/null +++ b/Essentials/test/com/earth2me/essentials/PermissionsTest.java @@ -0,0 +1,17 @@ +package com.earth2me.essentials; + +import junit.framework.TestCase; + + +public class PermissionsTest extends TestCase +{ + @Override + protected void setUp() throws Exception + { + super.setUp(); + } + + public void test() + { + } +} diff --git a/Essentials/test/com/earth2me/essentials/UserTest.java b/Essentials/test/com/earth2me/essentials/UserTest.java new file mode 100644 index 000000000..011ba4770 --- /dev/null +++ b/Essentials/test/com/earth2me/essentials/UserTest.java @@ -0,0 +1,72 @@ +package com.earth2me.essentials; + +import junit.framework.TestCase; +import org.bukkit.Location; + + +public class UserTest extends TestCase +{ + private OfflinePlayer base1; + + public UserTest(String testName) + { + super(testName); + base1 = new OfflinePlayer("TestPlayer1"); + } + + private void should(String what) + { + System.out.println(getName() + " should " + what); + } + + @Override + protected void setUp() throws Exception + { + super.setUp(); + } + + @Override + protected void tearDown() throws Exception + { + super.tearDown(); + } + + public void testUpdate() + { + should("update an existing player with the same name, rather than creating a new player"); + User.get(base1); + int size1 = User.size(); + OfflinePlayer base1alt = new OfflinePlayer(base1.getName()); + assertEquals(base1alt, User.get(base1alt).getBase()); + assertTrue(size1 == User.size()); + } + + public void testHome() throws Exception + { + should("return the home set by setHome"); + Location home = new Location(null, 1, 2, 3, 4, 5); + User user = User.get(base1); + user.setHome(home); + assertEquals(user.getHome(), home); + } + + public void testMoney() + { + should("properly set, take, give, and get money"); + User user = User.get(base1); + double i; + user.setMoney(i = 100.5); + user.takeMoney(50); + i -= 50; + user.giveMoney(25); + i += 25; + assertEquals(user.getMoney(), i); + } + + public void testGetGroup() + { + should("return the default group"); + User user = User.get(base1); + assertEquals(user.getGroup(), "default"); + } +} diff --git a/Essentials/workdir/EssentialsGroupManager/config.yml b/Essentials/workdir/EssentialsGroupManager/config.yml new file mode 100644 index 000000000..e69de29bb diff --git a/Essentials/workdir/banned-ips.txt b/Essentials/workdir/banned-ips.txt new file mode 100644 index 000000000..e69de29bb diff --git a/Essentials/workdir/banned-players.txt b/Essentials/workdir/banned-players.txt new file mode 100644 index 000000000..e69de29bb diff --git a/Essentials/workdir/ops.txt b/Essentials/workdir/ops.txt new file mode 100644 index 000000000..e69de29bb diff --git a/Essentials/workdir/plugins/Permissions/default.yml b/Essentials/workdir/plugins/Permissions/default.yml new file mode 100644 index 000000000..e69de29bb diff --git a/Essentials/workdir/server.log b/Essentials/workdir/server.log new file mode 100644 index 000000000..de34fdb17 --- /dev/null +++ b/Essentials/workdir/server.log @@ -0,0 +1,264 @@ +2011-02-28 16:56:00 [INFO] Starting minecraft server version Beta 1.3 +2011-02-28 16:56:00 [INFO] Loading properties +2011-02-28 16:56:00 [WARNING] server.properties does not exist +2011-02-28 16:56:00 [INFO] Generating new properties file +2011-02-28 16:56:00 [INFO] Starting Minecraft server on *:25565 +2011-02-28 16:56:00 [INFO] This server is running Craftbukkit version git-Bukkit-0.0.0-468-ga3bf56c-b450jnks (MC: 1.3) +2011-02-28 16:56:00 [WARNING] Failed to load ban list: java.io.FileNotFoundException: banned-players.txt (The system cannot find the file specified) +2011-02-28 16:56:00 [WARNING] Failed to load ip ban list: java.io.FileNotFoundException: banned-ips.txt (The system cannot find the file specified) +2011-02-28 16:56:00 [WARNING] Failed to load ops: java.io.FileNotFoundException: ops.txt (The system cannot find the file specified) +2011-02-28 16:56:00 [WARNING] Failed to load white-list: java.io.FileNotFoundException: white-list.txt (The system cannot find the file specified) +2011-02-28 16:56:00 [INFO] Preparing level "world" +2011-02-28 16:56:00 [INFO] Preparing start region +2011-02-28 16:56:01 [INFO] §eLoaded Essentials build TeamCity maintained by Zenexer, ementalo, Aelux, and Brettflan +2011-02-28 16:56:02 [INFO] Preparing spawn area: 4% +2011-02-28 16:56:03 [INFO] Preparing spawn area: 8% +2011-02-28 16:56:04 [INFO] Preparing spawn area: 20% +2011-02-28 16:56:05 [INFO] Preparing spawn area: 32% +2011-02-28 16:56:06 [INFO] Preparing spawn area: 40% +2011-02-28 16:56:07 [INFO] Preparing spawn area: 48% +2011-02-28 16:56:08 [INFO] Starting minecraft server version Beta 1.3 +2011-02-28 16:56:08 [INFO] Loading properties +2011-02-28 16:56:08 [INFO] Starting Minecraft server on *:25565 +2011-02-28 16:56:08 [INFO] This server is running Craftbukkit version git-Bukkit-0.0.0-468-ga3bf56c-b450jnks (MC: 1.3) +2011-02-28 16:56:09 [INFO] Preparing level "world" +2011-02-28 16:56:09 [INFO] Preparing start region +2011-02-28 16:56:10 [INFO] §eLoaded Essentials build TeamCity maintained by Zenexer, ementalo, Aelux, and Brettflan +2011-02-28 16:56:10 [INFO] Preparing spawn area: 4% +2011-02-28 16:56:10 [INFO] Should update an existing player with the same name, rather than creating a new player +2011-02-28 16:56:11 [INFO] Starting minecraft server version Beta 1.3 +2011-02-28 16:56:11 [INFO] > +2011-02-28 16:56:11 [INFO] Preparing spawn area: 8% +2011-02-28 16:57:39 [INFO] Starting minecraft server version Beta 1.3 +2011-02-28 16:57:39 [INFO] Loading properties +2011-02-28 16:57:39 [INFO] Starting Minecraft server on *:25565 +2011-02-28 16:57:39 [INFO] This server is running Craftbukkit version git-Bukkit-0.0.0-468-ga3bf56c-b450jnks (MC: 1.3) +2011-02-28 16:57:39 [INFO] Preparing level "world" +2011-02-28 16:57:39 [INFO] Preparing start region +2011-02-28 16:57:41 [INFO] §eLoaded Essentials build TeamCity maintained by Zenexer, ementalo, Aelux, and Brettflan +2011-02-28 16:57:41 [INFO] Preparing spawn area: 4% +2011-02-28 16:57:42 [INFO] Preparing spawn area: 8% +2011-02-28 16:57:43 [INFO] Preparing spawn area: 16% +2011-02-28 16:57:44 [INFO] Preparing spawn area: 24% +2011-02-28 16:57:45 [INFO] Preparing spawn area: 24% +2011-02-28 16:57:48 [INFO] Starting minecraft server version Beta 1.3 +2011-02-28 16:57:48 [INFO] Loading properties +2011-02-28 16:57:48 [INFO] Starting Minecraft server on *:25565 +2011-02-28 16:57:48 [INFO] This server is running Craftbukkit version git-Bukkit-0.0.0-468-ga3bf56c-b450jnks (MC: 1.3) +2011-02-28 16:57:49 [INFO] Preparing level "world" +2011-02-28 16:57:49 [INFO] Preparing start region +2011-02-28 16:57:50 [INFO] §eLoaded Essentials build TeamCity maintained by Zenexer, ementalo, Aelux, and Brettflan +2011-02-28 16:57:50 [INFO] Preparing spawn area: 8% +2011-02-28 16:57:51 [INFO] > +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] Starting minecraft server version Beta 1.3 +2011-02-28 16:57:51 [INFO] Preparing spawn area: 12% +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:51 [INFO] +2011-02-28 16:57:52 [INFO] +2011-02-28 16:57:52 [INFO] +2011-02-28 16:57:52 [INFO] +2011-02-28 16:57:52 [INFO] +2011-02-28 16:57:52 [INFO] +2011-02-28 16:57:52 [INFO] +2011-02-28 16:57:52 [INFO] +2011-02-28 16:57:52 [INFO] +2011-02-28 16:57:52 [INFO] +2011-02-28 16:57:52 [INFO] +2011-02-28 16:57:52 [INFO] +2011-02-28 16:57:52 [INFO] +2011-02-28 16:57:52 [INFO] +2011-02-28 16:57:52 [INFO] +2011-02-28 16:57:52 [INFO] +2011-02-28 16:57:52 [INFO] +2011-02-28 16:57:52 [INFO] +2011-02-28 16:57:52 [INFO] +2011-02-28 16:57:52 [INFO] +2011-02-28 16:57:52 [INFO] +2011-02-28 16:57:52 [INFO] +2011-02-28 16:57:52 [INFO] +2011-02-28 16:57:52 [INFO] +2011-02-28 16:57:52 [INFO] +2011-02-28 16:57:52 [INFO] +2011-02-28 16:57:52 [INFO] +2011-02-28 16:57:52 [INFO] +2011-02-28 16:57:52 [INFO] +2011-02-28 16:57:53 [INFO] +2011-02-28 16:57:53 [INFO] +2011-02-28 16:57:53 [INFO] +2011-02-28 16:57:53 [INFO] +2011-02-28 16:57:53 [INFO] +2011-02-28 16:57:53 [INFO] +2011-02-28 16:57:53 [INFO] +2011-02-28 16:57:53 [INFO] +2011-02-28 16:57:53 [INFO] +2011-02-28 16:57:53 [INFO] +2011-02-28 16:57:53 [INFO] +2011-02-28 16:57:53 [INFO] +2011-02-28 16:57:53 [INFO] +2011-02-28 16:57:53 [INFO] +2011-02-28 16:57:53 [INFO] +2011-02-28 16:57:53 [INFO] +2011-02-28 16:57:53 [INFO] +2011-02-28 16:57:53 [INFO] +2011-02-28 16:57:53 [INFO] +2011-02-28 16:57:53 [INFO] +2011-02-28 16:57:53 [INFO] +2011-02-28 16:57:53 [INFO] +2011-02-28 16:57:53 [INFO] +2011-02-28 16:57:53 [INFO] +2011-02-28 16:57:53 [INFO] +2011-02-28 16:57:54 [INFO] +2011-02-28 16:57:54 [INFO] +2011-02-28 16:57:54 [INFO] +2011-02-28 16:57:54 [INFO] +2011-02-28 16:57:54 [INFO] +2011-02-28 16:57:54 [INFO] +2011-02-28 16:57:54 [INFO] +2011-02-28 16:57:54 [INFO] +2011-02-28 16:57:54 [INFO] +2011-02-28 16:57:54 [INFO] +2011-02-28 16:57:54 [INFO] +2011-02-28 16:57:54 [INFO] +2011-02-28 16:57:54 [INFO] +2011-02-28 16:57:54 [INFO] +2011-02-28 16:57:54 [INFO] +2011-02-28 16:57:54 [INFO] +2011-02-28 16:57:54 [INFO] +2011-02-28 16:57:54 [INFO] +2011-02-28 16:57:54 [INFO] +2011-02-28 16:57:54 [INFO] +2011-02-28 16:57:54 [INFO] +2011-02-28 16:57:54 [INFO] +2011-02-28 16:57:55 [INFO] +2011-02-28 16:57:55 [INFO] +2011-02-28 16:57:55 [INFO] +2011-02-28 16:57:55 [INFO] +2011-02-28 16:57:55 [INFO] +2011-02-28 16:57:55 [INFO] +2011-02-28 16:57:55 [INFO] +2011-02-28 16:57:55 [INFO] +2011-02-28 16:57:55 [INFO] +2011-02-28 16:57:55 [INFO] +2011-02-28 16:57:55 [INFO] +2011-02-28 16:57:55 [INFO] +2011-02-28 16:57:55 [INFO] +2011-02-28 16:57:55 [INFO] +2011-02-28 16:57:55 [INFO] +2011-02-28 16:57:55 [INFO] +2011-02-28 16:57:55 [INFO] +2011-02-28 16:57:55 [INFO] +2011-02-28 16:57:55 [INFO] +2011-02-28 16:57:55 [INFO] +2011-02-28 16:57:56 [INFO] +2011-02-28 16:57:56 [INFO] +2011-02-28 16:57:56 [INFO] +2011-02-28 16:57:56 [INFO] +2011-02-28 16:59:07 [INFO] Starting minecraft server version Beta 1.3 +2011-02-28 16:59:07 [INFO] Loading properties +2011-02-28 16:59:07 [INFO] Starting Minecraft server on *:25565 +2011-02-28 16:59:07 [INFO] This server is running Craftbukkit version git-Bukkit-0.0.0-468-ga3bf56c-b450jnks (MC: 1.3) +2011-02-28 16:59:07 [INFO] Preparing level "world" +2011-02-28 16:59:07 [INFO] Preparing start region +2011-02-28 16:59:08 [INFO] Done (0.060s)! For help, type "help" or "?" +2011-02-28 16:59:08 [INFO] Stopping server +2011-02-28 16:59:08 [INFO] Saving chunks +2011-02-28 16:59:09 [INFO] Starting minecraft server version Beta 1.3 +2011-02-28 16:59:09 [INFO] Loading properties +2011-02-28 16:59:09 [INFO] Starting Minecraft server on *:25565 +2011-02-28 16:59:09 [INFO] This server is running Craftbukkit version git-Bukkit-0.0.0-468-ga3bf56c-b450jnks (MC: 1.3) +2011-02-28 16:59:09 [INFO] Preparing level "world" +2011-02-28 16:59:09 [INFO] Preparing start region +2011-02-28 16:59:10 [INFO] Done (0.011s)! For help, type "help" or "?" +2011-02-28 16:59:10 [INFO] Stopping server +2011-02-28 16:59:10 [INFO] Saving chunks diff --git a/Essentials/workdir/server.log.1 b/Essentials/workdir/server.log.1 new file mode 100644 index 000000000..e69de29bb diff --git a/Essentials/workdir/server.log.1.lck b/Essentials/workdir/server.log.1.lck new file mode 100644 index 000000000..e69de29bb diff --git a/Essentials/workdir/server.properties b/Essentials/workdir/server.properties new file mode 100644 index 000000000..c1f6fa8df --- /dev/null +++ b/Essentials/workdir/server.properties @@ -0,0 +1,13 @@ +#Minecraft server properties +#Mon Feb 28 16:56:01 EST 2011 +level-name=world +hellworld=false +spawn-monsters=true +online-mode=true +spawn-animals=true +max-players=20 +server-ip= +pvp=true +server-port=25565 +white-list=false +spawn-protection=16 diff --git a/Essentials/workdir/userdata/TestPlayer1.yml b/Essentials/workdir/userdata/TestPlayer1.yml new file mode 100644 index 000000000..c419a1196 --- /dev/null +++ b/Essentials/workdir/userdata/TestPlayer1.yml @@ -0,0 +1,2 @@ +home: [1.0, 2.0, 3.0, 4.0, 5.0, world] +money: 75.5 diff --git a/Essentials/workdir/white-list.txt b/Essentials/workdir/white-list.txt new file mode 100644 index 000000000..e69de29bb diff --git a/EssentialsChat/build.xml b/EssentialsChat/build.xml new file mode 100644 index 000000000..ed22cfe0c --- /dev/null +++ b/EssentialsChat/build.xml @@ -0,0 +1,76 @@ + + ]> + + + + + + + + + + Builds, tests, and runs the project EssentialsChat. + + &buildinc; + + diff --git a/EssentialsChat/nbproject/build-impl.xml b/EssentialsChat/nbproject/build-impl.xml new file mode 100644 index 000000000..e0b698395 --- /dev/null +++ b/EssentialsChat/nbproject/build-impl.xml @@ -0,0 +1,1072 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + + + + + + java -cp "${run.classpath.with.dist.jar}" ${main.class} + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + + + + + + + + Must select one file in the IDE or set profile.class + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + 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 applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/EssentialsChat/nbproject/genfiles.properties b/EssentialsChat/nbproject/genfiles.properties new file mode 100644 index 000000000..e53628d44 --- /dev/null +++ b/EssentialsChat/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=7c7f517b +build.xml.script.CRC32=71afd555 +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=7c7f517b +nbproject/build-impl.xml.script.CRC32=c24d2db5 +nbproject/build-impl.xml.stylesheet.CRC32=19debb58@1.42.1.45 diff --git a/EssentialsChat/nbproject/private/private.properties b/EssentialsChat/nbproject/private/private.properties new file mode 100644 index 000000000..94183418a --- /dev/null +++ b/EssentialsChat/nbproject/private/private.properties @@ -0,0 +1 @@ +user.properties.file=C:\\Users\\Paul\\.netbeans\\7.0beta2\\build.properties diff --git a/EssentialsChat/nbproject/project.properties b/EssentialsChat/nbproject/project.properties new file mode 100644 index 000000000..315a26576 --- /dev/null +++ b/EssentialsChat/nbproject/project.properties @@ -0,0 +1,79 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.title=EssentialsChat +application.vendor=Paul +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/EssentialsChat.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +file.reference.craftbukkit-0.0.1-SNAPSHOT.jar=../lib/craftbukkit-0.0.1-SNAPSHOT.jar +file.reference.Permissions.jar=..\\lib\\Permissions.jar +includes=** +jar.compress=false +javac.classpath=\ + ${file.reference.craftbukkit-0.0.1-SNAPSHOT.jar}:\ + ${file.reference.Permissions.jar}:\ + ${reference.Essentials.jar} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.5 +javac.target=1.5 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir}:\ + ${libs.junit.classpath}:\ + ${libs.junit_4.classpath} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +project.Essentials=../Essentials +reference.Essentials.jar=${project.Essentials}/dist/Essentials.jar +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project +# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value +# or test-sys-prop.name=value to set system properties for unit tests): +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/EssentialsChat/nbproject/project.xml b/EssentialsChat/nbproject/project.xml new file mode 100644 index 000000000..da40bbe42 --- /dev/null +++ b/EssentialsChat/nbproject/project.xml @@ -0,0 +1,28 @@ + + + org.netbeans.modules.java.j2seproject + + + EssentialsChat + + + + + + + + + ..\lib\nblibraries.properties + + + + Essentials + jar + + jar + clean + jar + + + + diff --git a/EssentialsChat/src/com/earth2me/essentials/chat/EssentialsChat.java b/EssentialsChat/src/com/earth2me/essentials/chat/EssentialsChat.java new file mode 100644 index 000000000..266bd104e --- /dev/null +++ b/EssentialsChat/src/com/earth2me/essentials/chat/EssentialsChat.java @@ -0,0 +1,43 @@ +package com.earth2me.essentials.chat; + +import com.earth2me.essentials.Essentials; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.bukkit.event.Event.Priority; +import org.bukkit.event.Event.Type; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.java.JavaPlugin; + + +public class EssentialsChat extends JavaPlugin +{ + private static final Logger logger = Logger.getLogger("Minecraft"); + + public EssentialsChat() + { + super(); + } + + public void onEnable() + { + Plugin p = this.getServer().getPluginManager().getPlugin("Essentials"); + if (p != null) { + if (!this.getServer().getPluginManager().isPluginEnabled(p)) { + this.getServer().getPluginManager().enablePlugin(p); + } + } + PluginManager pm = getServer().getPluginManager(); + EssentialsChatPlayerListener playerListener = new EssentialsChatPlayerListener(getServer()); + pm.registerEvent(Type.PLAYER_JOIN, playerListener, Priority.Monitor, this); + pm.registerEvent(Type.PLAYER_CHAT, playerListener, Priority.Highest, this); + if (!this.getDescription().getVersion().equals(Essentials.getStatic().getDescription().getVersion())) { + logger.log(Level.WARNING, "Version mismatch! Please update all Essentials jars to the same version."); + } + logger.info("Loaded " + this.getDescription().getName() + " build " + this.getDescription().getVersion() + " by " + Essentials.AUTHORS); + } + + public void onDisable() + { + } +} diff --git a/EssentialsChat/src/com/earth2me/essentials/chat/EssentialsChatPlayerListener.java b/EssentialsChat/src/com/earth2me/essentials/chat/EssentialsChatPlayerListener.java new file mode 100644 index 000000000..e351cc865 --- /dev/null +++ b/EssentialsChat/src/com/earth2me/essentials/chat/EssentialsChatPlayerListener.java @@ -0,0 +1,61 @@ +package com.earth2me.essentials.chat; + +import com.earth2me.essentials.Essentials; +import org.bukkit.Server; +import org.bukkit.event.player.*; + + +public class EssentialsChatPlayerListener extends PlayerListener +{ + private final Server server; + + public EssentialsChatPlayerListener(Server server) + { + this.server = server; + } + + @Override + @SuppressWarnings("CallToThreadDumpStack") + public void onPlayerJoin(PlayerJoinEvent event) + { + try + { + Essentials.loadClasses(); + EssentialsChatWorker.onPlayerJoin(server, event); + } + catch (Throwable ex) + { + ex.printStackTrace(); + } + } + + @Override + @SuppressWarnings("CallToThreadDumpStack") + public void onPlayerRespawn(PlayerRespawnEvent event) + { + try + { + Essentials.loadClasses(); + EssentialsChatWorker.onPlayerRespawn(server, event); + } + catch (Throwable ex) + { + ex.printStackTrace(); + } + } + + @Override + @SuppressWarnings("CallToThreadDumpStack") + public void onPlayerChat(PlayerChatEvent event) + { + try + { + Essentials.loadClasses(); + EssentialsChatWorker.onPlayerChat(server, event); + } + catch (Throwable ex) + { + ex.printStackTrace(); + } + } +} diff --git a/EssentialsChat/src/com/earth2me/essentials/chat/EssentialsChatWorker.java b/EssentialsChat/src/com/earth2me/essentials/chat/EssentialsChatWorker.java new file mode 100644 index 000000000..e11504259 --- /dev/null +++ b/EssentialsChat/src/com/earth2me/essentials/chat/EssentialsChatWorker.java @@ -0,0 +1,122 @@ +package com.earth2me.essentials.chat; + +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import com.nijikokun.bukkit.Permissions.Permissions; +import java.util.logging.Logger; +import org.bukkit.Location; +import org.bukkit.Server; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerChatEvent; +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.event.player.PlayerRespawnEvent; + + +public class EssentialsChatWorker +{ + private static final Logger logger = Logger.getLogger("Minecraft"); + + public static void onPlayerRespawn(Server server, PlayerRespawnEvent event) + { + User user = User.get(event.getPlayer()); + updateDisplayName(user); + } + + public static void onPlayerJoin(Server server, PlayerEvent event) + { + User user = User.get(event.getPlayer()); + updateDisplayName(user); + } + + private static void updateDisplayName(User user) + { + try + { + String group = user.getGroup(); + try + { + String prefix = Permissions.Security.getGroupPrefix(user.getWorld().getName(), group).replace('&', '§').replace("{WORLDNAME}", user.getWorld().getName()); + String suffix = Permissions.Security.getGroupSuffix(user.getWorld().getName(), group).replace('&', '§').replace("{WORLDNAME}", user.getWorld().getName()); + user.setDisplayName(prefix + user.getNick() + suffix + (suffix.endsWith("§f") ? "" : "§f")); + } + catch (Throwable ex) + { + logger.warning("Missing a prefix or suffix for " + group); + } + } + catch (Throwable ex) + { + logger.warning("Missing Permissions/GroupManager; chat prefixes/suffixes will be disabled."); + } + } + + public static void onPlayerChat(Server server, PlayerChatEvent event) + { + User user = User.get(event.getPlayer()); + updateDisplayName(user); + + if (user.isAuthorized("essentials.chat.color")) + event.setMessage(event.getMessage().replaceAll("&([0-9a-f])", "§$1")); + + event.setFormat(Essentials.getSettings().getChatFormat(user.getGroup()) + .replace('&', '§') + .replace("§§", "&") + .replace("{DISPLAYNAME}", "%1$s") + .replace("{GROUP}", user.getGroup()) + .replace("{MESSAGE}", "%2$s") + .replace("{WORLDNAME}", user.getWorld().getName())); + + int radius = Essentials.getSettings().getChatRadius(); + if (radius < 1) return; + + if (event.getMessage().startsWith("!") && event.getMessage().length() > 1) + { + if (user.isAuthorized("essentials.chat.shout")) + { + event.setMessage(event.getMessage().substring(1)); + event.setFormat("§7[Shout]§f " + event.getFormat()); + return; + } + user.sendMessage("§cYou are not authorized to shout."); + event.setCancelled(true); + return; + } + + if (event.getMessage().startsWith("?") && event.getMessage().length() > 1) + { + if (user.isAuthorized("essentials.chat.question")) + { + event.setMessage(event.getMessage().substring(1)); + event.setFormat("§7[Question]§f " + event.getFormat()); + return; + } + user.sendMessage("§cYou are not authorized to use question."); + event.setCancelled(true); + return; + } + + event.setCancelled(true); + logger.info("Local: <" + user.getName() + "> " + event.getMessage()); + + Location loc = user.getLocation(); + int x = loc.getBlockX(); + int y = loc.getBlockY(); + int z = loc.getBlockZ(); + + for (Player p : server.getOnlinePlayers()) + { + User u = User.get(p); + if (u != user && !u.isAuthorized("essentials.chat.spy")) + { + Location l = u.getLocation(); + int dx = Math.abs(x - l.getBlockX()); + int dy = Math.abs(y - l.getBlockY()); + int dz = Math.abs(z - l.getBlockZ()); + int delta = dx + dy + dz; + if (delta > radius) continue; + } + + u.sendMessage(String.format(event.getFormat(), user.getDisplayName(), event.getMessage())); + } + } +} diff --git a/EssentialsChat/src/plugin.yml b/EssentialsChat/src/plugin.yml new file mode 100644 index 000000000..b4f7bb9c9 --- /dev/null +++ b/EssentialsChat/src/plugin.yml @@ -0,0 +1,8 @@ +# This determines the command prefix when there are conflicts (/name:home, /name:help, etc.) +name: EssentialsChat +main: com.earth2me.essentials.chat.EssentialsChat +# Note to developers: This next line cannot change, or the automatic versioning system will break. +version: TeamCity +website: http://www.earth2me.net:8001/ +description: Provides chat control features for Essentials. Requires Permissions. +authors: [Zenexer, ementalo, Aelux, Brettflan, KimKandor, snowleo] \ No newline at end of file diff --git a/EssentialsGroupBridge/build.xml b/EssentialsGroupBridge/build.xml new file mode 100644 index 000000000..94dd95861 --- /dev/null +++ b/EssentialsGroupBridge/build.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + Builds, tests, and runs the project EssentialsGroupBridge. + + + diff --git a/EssentialsGroupBridge/nbproject/build-impl.xml b/EssentialsGroupBridge/nbproject/build-impl.xml new file mode 100644 index 000000000..30d2e9bf6 --- /dev/null +++ b/EssentialsGroupBridge/nbproject/build-impl.xml @@ -0,0 +1,1047 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + + + + + + java -cp "${run.classpath.with.dist.jar}" ${main.class} + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + + + + + + + + Must select one file in the IDE or set profile.class + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + 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 applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/EssentialsGroupBridge/nbproject/genfiles.properties b/EssentialsGroupBridge/nbproject/genfiles.properties new file mode 100644 index 000000000..194afdd81 --- /dev/null +++ b/EssentialsGroupBridge/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=475c8f4d +build.xml.script.CRC32=674d9b15 +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=475c8f4d +nbproject/build-impl.xml.script.CRC32=5fe43282 +nbproject/build-impl.xml.stylesheet.CRC32=19debb58@1.42.1.45 diff --git a/EssentialsGroupBridge/nbproject/private/private.properties b/EssentialsGroupBridge/nbproject/private/private.properties new file mode 100644 index 000000000..94183418a --- /dev/null +++ b/EssentialsGroupBridge/nbproject/private/private.properties @@ -0,0 +1 @@ +user.properties.file=C:\\Users\\Paul\\.netbeans\\7.0beta2\\build.properties diff --git a/EssentialsGroupBridge/nbproject/project.properties b/EssentialsGroupBridge/nbproject/project.properties new file mode 100644 index 000000000..0649cc58f --- /dev/null +++ b/EssentialsGroupBridge/nbproject/project.properties @@ -0,0 +1,78 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.title=EssentialsGroupBridge +application.vendor=gabrielcouto +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/EssentialsGroupBridge.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +file.reference.craftbukkit-0.0.1-SNAPSHOT.jar=..\\lib\\craftbukkit-0.0.1-SNAPSHOT.jar +file.reference.Permissions.jar=..\\lib\\Permissions.jar +includes=** +jar.compress=false +javac.classpath=\ + ${reference.EssentialsGroupManager.jar}:\ + ${file.reference.craftbukkit-0.0.1-SNAPSHOT.jar}:\ + ${file.reference.Permissions.jar} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.6 +javac.target=1.6 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +main.class= +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +platform.active=default_platform +project.EssentialsGroupManager=../EssentialsGroupManager +reference.EssentialsGroupManager.jar=${project.EssentialsGroupManager}/dist/EssentialsGroupManager.jar +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project +# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value +# or test-sys-prop.name=value to set system properties for unit tests): +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/EssentialsGroupBridge/nbproject/project.xml b/EssentialsGroupBridge/nbproject/project.xml new file mode 100644 index 000000000..f7234f600 --- /dev/null +++ b/EssentialsGroupBridge/nbproject/project.xml @@ -0,0 +1,25 @@ + + + org.netbeans.modules.java.j2seproject + + + EssentialsGroupBridge + + + + + + + + + + EssentialsGroupManager + jar + + jar + clean + jar + + + + diff --git a/EssentialsGroupBridge/src/com/nijiko/Messaging.class b/EssentialsGroupBridge/src/com/nijiko/Messaging.class new file mode 100644 index 0000000000000000000000000000000000000000..f563d00856f3b150ad0a22dbca0d991c3d2b249c GIT binary patch literal 2604 zcma)7Yj+b>6y4J_$utcGr?k8*0%A$hmXt!vqp<=-P)Q3~tc8j?Nr!gY=_E`h#o_}& z6czA|isFM${i?WDL0yXvx|SdOCH@Gt?lT$MK!ZzGlQZml?!No%bLQrce}29Vpab89 zQKevcHaD5H&2e)gm+UhN1%1@CN5iOAuxwnP(vy~Mk0uXg#*M72Ae6WCX~R*lI-PSy zlbPbggy|*?+cn+kW(S@_rXxgqlqAZWl_{YC6zm778Eq5E6J9#b!W6VNkt0MvGhU( z1Fplmx`+Q46knXBqEUg;8o^4e4rA3_?v%KrSc3;CAe*yY-LxrkO}T*HG2Iz3P8JP2 zYjnqt3DMdp9>O{W!9w0LDR@(PzArdlL9y)J5XHmTs37bZ>`9gm?knGY*J)+d+=W*t zllpUx$q~>k>B%Dh6x7@?m<85X5GO;DGi{g4ipkHD90G1puw=m1vlD%K-fM0cF&3WJ zodTsdmrK7>_~OGOoS=>Djs8b413sxREABM=uy$js^sK$6^~Oy z%GRf*2_Nv`Eh=b8I5p}RhE4pSk9Vl(lXTb6Ey9Ox}Z-nG{x?Jy?Xa)!IPH!kF-S!yQMw_Uqq2ado8}iwJ^R? zu=0NQcobiYQ?+tb>34y`A_KXilQs66a%I=e|6FVq=dqsj0sgY^j*wfPPc={x=0^}9 z&M5za%8!Wrz=tYC`5j>d)}b0}vBX1#f|tF&Ey*YwgNd71y09(efu$|cQUV@;#>5)b zV>uBy^Ka6sj6;E*8T7X_b!ZKw1kH@{vnSK9as&K}j? zyot9Gvv^0l#IISre=l3MjI9wLdwr_GC-~H_dn;pUAS=wV!)6uA2!ivk!WDex6ZCpb z25J*6xA6H-xLSpUxh}m9XW9949!(>Ynd;NXlPHquzJd!rVLx+3QT+`>e#cUNv&Rd> ir2(y@3BX0Zn3wpPTrSgC?-waU#u?Gb^$j1Z@a@0#cs)1( literal 0 HcmV?d00001 diff --git a/EssentialsGroupBridge/src/com/nijiko/Misc$string.class b/EssentialsGroupBridge/src/com/nijiko/Misc$string.class new file mode 100644 index 0000000000000000000000000000000000000000..124b535c30332a73a51c17ddd1463f120e8976f3 GIT binary patch literal 982 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 H%E8fJsL98- literal 0 HcmV?d00001 diff --git a/EssentialsGroupBridge/src/com/nijiko/configuration/DefaultConfiguration.class b/EssentialsGroupBridge/src/com/nijiko/configuration/DefaultConfiguration.class new file mode 100644 index 0000000000000000000000000000000000000000..06d9ee23b24470eaab2cb4d4489dffb97c851b92 GIT binary patch literal 435 zcmb7AJx_!{5Pb`Ha2%c|e#O#GFHsU(KbkXEL<`LId$5O#uxns3@n=~W6AOQUKgu|u zi550yli8V<_h#nJ`^W1WfMe{quowiWC%UauaVfhAyMOsV>O47nw3WHkmv}pf$qYagm>+?C|cP51P)4OGXMYp literal 0 HcmV?d00001 diff --git a/EssentialsGroupBridge/src/com/nijiko/database/Wrapper$Type.class b/EssentialsGroupBridge/src/com/nijiko/database/Wrapper$Type.class new file mode 100644 index 0000000000000000000000000000000000000000..173279ddfd67eabcb1eef8be08495fb5fdd7273d GIT binary patch literal 1107 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 R9sFF0=8sYe`9*!{e*qG~8Vvvd literal 0 HcmV?d00001 diff --git a/EssentialsGroupBridge/src/com/nijiko/permissions/Control.class b/EssentialsGroupBridge/src/com/nijiko/permissions/Control.class new file mode 100644 index 0000000000000000000000000000000000000000..d0d8845ac42d84af80f6a15abb85d313c1dcb122 GIT binary patch literal 27337 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 literal 0 HcmV?d00001 diff --git a/EssentialsGroupBridge/src/com/nijiko/permissions/PermissionHandler.class b/EssentialsGroupBridge/src/com/nijiko/permissions/PermissionHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..a23287a5bfd1a923ff8ac38fd75e96b19e8617c2 GIT binary patch literal 3198 zcmbVOSyLNF5bgn)LjepvFyz8ljD%xvLN40^Y(TaVh$AK;Rrb@c8i|3`4mH|!g`btD zROKN*AU`UVo>6Nhd1q}o4^nUUeDn3!J;&}p|Niwi04&3+Q5a%S@Kw_b<*7VV-nr0C z*=k7@w!DMnd5ed&KFtQ>;8LcrGE)%whIO19wpMtsQM79_#RR`5mLh6=?%A(HWAo@+| zpvK^Oq1sh=7-<zg^hq4j!DAovg{0?9x-G!dWhEjpxVQJ0s+;z#dP3%jz^Fi3hBsJ?{i>pMUiJLH! z+-@~m$k%2ip9}=;skV3WSR?7_Orh8YB~>zb^log>k{H}^$Vw;J{xE9rloOp|+C5x! zaHrc)#9iFkExo->BhwKxcUp_4dMoVO)jldQuHFAmjC1oo?paL-V$wS6K|ucS3CFv` zEA$>S5k@k)@D2igA#}-IO}=~MF)*9srB?B|*$8QTIzsE)+eQZW98;aZd|901g~TI) zcgFmy809v_k!(r46W7B~MfOg>vSxcScjw^sH{KD9put*OeAB~42ZMoY=eUuhGNcYo zb#fnQQJ25t)z}Ff#&sK*^m!Y+5leG5&vgLZH%nUq1J|)g3r$CyeVtF|sf3Ye2t8<* z9EmFKF1e8o1$5;)yHHlKeJu{QgpQQufyE*62DazdmeA={FbmW_lJqS-loXWa>(p}< z`O;ag^+l5m{o#bYpQFQ^KU6Wkhs~=Sk4HBLeW^S&Z?D`fz)uqV&;eM*C;Sw_|55Zj zv<&T~r9WZp4}2JcJpP+ufCcyj|0mi2w3A@IdZysAwbL+T?G?Cc?KO&DCw~@M41N}F zSUX4l9F5Pzr^x)7&G|Xv=HZLP{}TNLxM}Atz%6TU!<}UOE{@-ZuM+ier@do%Kw0LJ|y3RZ|wNDWS8MP>o3Fi*o_}hAHa|JGd=mqjy!_LWS?XpN~EEL zn%o>Klw~C|%PJvOGZAZ4@fvp2o#iP!vr3;Lmm9GT8y2w+n;D2Q)l$x^DbBCQ6(MKOdY$VV>eUB9_iT2)Ui)G_T4&gA06O+ I8iJqy1JZ^j)Bpeg literal 0 HcmV?d00001 diff --git a/EssentialsGroupBridge/src/com/nijikokun/bukkit/Permissions/Permissions.java b/EssentialsGroupBridge/src/com/nijikokun/bukkit/Permissions/Permissions.java new file mode 100644 index 000000000..bca7a89ed --- /dev/null +++ b/EssentialsGroupBridge/src/com/nijikokun/bukkit/Permissions/Permissions.java @@ -0,0 +1,102 @@ +package com.nijikokun.bukkit.Permissions; + +import com.nijiko.Misc; +import com.nijiko.configuration.DefaultConfiguration; +import com.nijiko.permissions.PermissionHandler; +import java.util.logging.Logger; +import org.anjocaido.groupmanager.GroupManager; +import org.anjocaido.groupmanager.permissions.NijikoPermissionsProxy; +import org.bukkit.Server; +import org.bukkit.event.player.PlayerChatEvent; +import org.bukkit.event.player.PlayerListener; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.java.JavaPlugin; + +public class Permissions extends JavaPlugin { + + private class Listener extends PlayerListener { + + private Permissions plugin; + + public Listener(Permissions plugin) { + //compiled code + throw new RuntimeException("Compiled Code"); + } + + public void onPlayerCommand(PlayerChatEvent event) { + //compiled code + throw new RuntimeException("Compiled Code"); + } + } + public static final Logger log = Logger.getLogger("Fake Permissions"); + public static String name = "Permissions"; + public static String codename = "Hacked Permissions by AnjoCaido"; + public static String version = "2.0"; + public static PermissionHandler Security = null; + public static Misc Misc = new Misc(); + public static Server Server; + private Listener Listener = null; + private DefaultConfiguration config = null; + private GroupManager groupManager; + + @Override + public void onDisable() { + //compiled code + //throw new RuntimeException("Compiled Code"); + // EXAMPLE: Custom code, here we just output some info so we can check all is well + PluginDescriptionFile pdfFile = this.getDescription(); + System.out.println("Fake " + pdfFile.getName() + " version " + pdfFile.getVersion() + " is disabled!"); + } + + @Override + public void onEnable() { + Server = this.getServer(); + PluginDescriptionFile pdfFile = this.getDescription(); + + if (Security == null) {//make sure we have only one instance + Plugin p = (Plugin)(this.getServer() == null ? new GroupManager() : this.getServer().getPluginManager().getPlugin("GroupManager")); + if (p != null) { + if (!p.isEnabled()) { + if (this.getServer() == null) { + p.onEnable(); + } else { + this.getServer().getPluginManager().enablePlugin(p); + } + } + GroupManager gm = (GroupManager) p; + groupManager = gm; + Security = new NijikoPermissionsProxy(gm); + } else { + System.err.println("OOOPS! Fake " + pdfFile.getName() + " version " + pdfFile.getVersion() + " couldn't find GroupManager!"); + this.getPluginLoader().disablePlugin(this); + } + } + // EXAMPLE: Custom code, here we just output some info so we can check all is well + if (pdfFile != null) + System.out.println("Fake " + pdfFile.getName() + " version " + pdfFile.getVersion() + " is enabled!"); + } + + private void registerEvents() { + //compiled code + //throw new RuntimeException("Compiled Code"); + } + + public PermissionHandler getHandler() { + //compiled code + //throw new RuntimeException("Compiled Code"); + //System.out.println("Alguem chamou o handler"); + checkEnable(); + return Security; + } + + public void setupPermissions() { + checkEnable(); + } + + private void checkEnable() { + if (!this.isEnabled() && Security == null && this.getServer() != null) { + this.getServer().getPluginManager().enablePlugin(this); + } + } +} diff --git a/EssentialsGroupBridge/src/org/anjocaido/groupmanager/permissions/NijikoPermissionsProxy.java b/EssentialsGroupBridge/src/org/anjocaido/groupmanager/permissions/NijikoPermissionsProxy.java new file mode 100644 index 000000000..18da0cd56 --- /dev/null +++ b/EssentialsGroupBridge/src/org/anjocaido/groupmanager/permissions/NijikoPermissionsProxy.java @@ -0,0 +1,428 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.anjocaido.groupmanager.permissions; + +import com.nijiko.permissions.Control; +import java.io.File; +import java.util.Map; +import org.anjocaido.groupmanager.GroupManager; +import org.bukkit.entity.Player; +import org.bukkit.util.config.Configuration; + +/** + * Everything here maintains the model created by Nijikokun + * + * But implemented to use GroupManager system. Which provides instant changes, + * without file access. + * + * @author gabrielcouto + */ +public class NijikoPermissionsProxy extends Control { + GroupManager plugin; + public NijikoPermissionsProxy(GroupManager plugin){ + super(null); + this.plugin = plugin; + } + + @Override + public void addGroupPermission(String world, String group, String node) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void removeGroupPermission(String world, String group, String node) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void addGroupInfo(String world, String group, String node, Object data) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void removeGroupInfo(String world, String group, String node) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void addUserPermission(String world, String user, String node) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void removeUserPermission(String world, String user, String node) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void addUserInfo(String world, String user, String node, Object data) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void removeUserInfo(String world, String user, String node) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void removeUserInfo(String user, String node) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void addGroupPermission(String group, String node) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void removeGroupPermission(String group, String node) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void addGroupInfo(String group, String node, Object data) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void removeGroupInfo(String group, String node) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void addUserPermission(String user, String node) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void removeUserPermission(String user, String node) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void addUserInfo(String user, String node, Object data) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setDefaultWorld(String world) { + //throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setDirectory(File directory) { + //throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean loadWorld(String world) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void forceLoadWorld(String world) { + //throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean checkWorld(String world) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void load() { + //throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void load(String world, Configuration config) { + //throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void reload() { + plugin.getWorldsHolder().reloadAll(); + //throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean reload(String world) { + plugin.getWorldsHolder().reloadWorld(world); + return true; + } + + @Override + public void setCache(Map Cache) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setCache(String world, Map Cache) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setCacheItem(String player, String permission, boolean data) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setCacheItem(String world, String player, String permission, boolean data) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Map getCache() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Map getCache(String world) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean getCacheItem(String player, String permission) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean getCacheItem(String world, String player, String permission) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void removeCachedItem(String player, String permission) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void removeCachedItem(String world, String player, String permission) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void clearCache() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void clearCache(String world) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void clearAllCache() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean has(Player player, String permission) { + //throw new UnsupportedOperationException("Not supported yet."); + return permission(player, permission); + } + + @Override + public boolean permission(Player player, String permission) { + //throw new UnsupportedOperationException("Not supported yet."); + if(permission==null || permission.equals("")){ + return false; + } + if(player==null){ + GroupManager.logger.severe("A plugin is asking permission '"+permission+"' for a null player... Which plugin does that? Bastards!"); + return false; + } + if(player.getWorld()==null){ + GroupManager.logger.warning("The player "+player.getName()+" has a null world? Treating as default world!"); + return plugin.getWorldsHolder().getDefaultWorld().getPermissionsHandler().has(player, permission); + } + return plugin.getWorldsHolder().getWorldData(player.getWorld().getName()).getPermissionsHandler().has(player, permission); + } + + @Override + public String getGroup(String world, String name) { + return plugin.getWorldsHolder().getWorldData(world).getPermissionsHandler().getGroup(name); + } + + @Deprecated + @Override + public String getGroup(String name) { + return plugin.getWorldsHolder().getDefaultWorld().getPermissionsHandler().getGroup(name); + } + + @Override + public String[] getGroups(String world, String name) { + return plugin.getWorldsHolder().getWorldData(world).getPermissionsHandler().getGroups(name); + } + + @Deprecated + @Override + public String[] getGroups(String name) { + return plugin.getWorldsHolder().getDefaultWorld().getPermissionsHandler().getGroups(name); + } + + @Override + public boolean inGroup(String world, String name, String group) { + return plugin.getWorldsHolder().getWorldData(world).getPermissionsHandler().inGroup(name,group); + } + + @Deprecated + @Override + public boolean inGroup(String name, String group) { + return plugin.getWorldsHolder().getDefaultWorld().getPermissionsHandler().inGroup(name,group); + } + + @Override + public String getGroupPrefix(String world, String group) { + return plugin.getWorldsHolder().getWorldData(world).getPermissionsHandler().getGroupPrefix(group); + } + + @Override + public String getGroupPrefix(String group) { + return plugin.getWorldsHolder().getDefaultWorld().getPermissionsHandler().getGroupPrefix(group); + } + + @Override + public String getGroupSuffix(String world, String group) { + return plugin.getWorldsHolder().getWorldData(world).getPermissionsHandler().getGroupSuffix(group); + } + + @Override + public String getGroupSuffix(String group) { + return plugin.getWorldsHolder().getDefaultWorld().getPermissionsHandler().getGroupSuffix(group); + } + + @Override + public boolean canGroupBuild(String world, String group) { + return plugin.getWorldsHolder().getWorldData(world).getPermissionsHandler().canGroupBuild(group); + } + + @Deprecated + @Override + public boolean canGroupBuild(String group) { + return plugin.getWorldsHolder().getDefaultWorld().getPermissionsHandler().canGroupBuild(group); + } + + @Override + public String getGroupPermissionString(String world, String group, String permission) { + return plugin.getWorldsHolder().getWorldData(world).getPermissionsHandler().getGroupPermissionString(group,permission); + } + + @Override + public String getGroupPermissionString(String group, String permission) { + return plugin.getWorldsHolder().getDefaultWorld().getPermissionsHandler().getGroupPermissionString(group,permission); + } + + @Override + public int getGroupPermissionInteger(String world, String group, String permission) { + return plugin.getWorldsHolder().getWorldData(world).getPermissionsHandler().getGroupPermissionInteger(group,permission); + } + + @Override + public int getGroupPermissionInteger(String group, String permission) { + return plugin.getWorldsHolder().getDefaultWorld().getPermissionsHandler().getGroupPermissionInteger(group,permission); + } + + @Override + public boolean getGroupPermissionBoolean(String world, String group, String permission) { + return plugin.getWorldsHolder().getWorldData(world).getPermissionsHandler().getGroupPermissionBoolean(group,permission); + } + + @Override + public boolean getGroupPermissionBoolean(String group, String permission) { + return plugin.getWorldsHolder().getDefaultWorld().getPermissionsHandler().getGroupPermissionBoolean(group,permission); + } + + @Override + public double getGroupPermissionDouble(String world, String group, String permission) { + return plugin.getWorldsHolder().getWorldData(world).getPermissionsHandler().getGroupPermissionDouble(group,permission); + } + + @Override + public double getGroupPermissionDouble(String group, String permission) { + return plugin.getWorldsHolder().getDefaultWorld().getPermissionsHandler().getGroupPermissionDouble(group,permission); + } + + @Override + public String getUserPermissionString(String world, String name, String permission) { + return plugin.getWorldsHolder().getWorldData(world).getPermissionsHandler().getUserPermissionString(name,permission); + } + + @Override + public String getUserPermissionString(String name, String permission) { + return plugin.getWorldsHolder().getDefaultWorld().getPermissionsHandler().getUserPermissionString(name,permission); + } + + @Override + public int getUserPermissionInteger(String world, String name, String permission) { + return plugin.getWorldsHolder().getWorldData(world).getPermissionsHandler().getUserPermissionInteger(name,permission); + } + + @Override + public int getUserPermissionInteger(String name, String permission) { + return plugin.getWorldsHolder().getDefaultWorld().getPermissionsHandler().getUserPermissionInteger(name,permission); + } + + @Override + public boolean getUserPermissionBoolean(String world, String name, String permission) { + return plugin.getWorldsHolder().getWorldData(world).getPermissionsHandler().getUserPermissionBoolean(name,permission); + } + + @Override + public boolean getUserPermissionBoolean(String name, String permission) { + return plugin.getWorldsHolder().getDefaultWorld().getPermissionsHandler().getUserPermissionBoolean(name,permission); + } + + @Override + public double getUserPermissionDouble(String world, String name, String permission) { + return plugin.getWorldsHolder().getWorldData(world).getPermissionsHandler().getUserPermissionDouble(name,permission); + } + + @Override + public double getUserPermissionDouble(String name, String permission) { + return plugin.getWorldsHolder().getDefaultWorld().getPermissionsHandler().getUserPermissionDouble(name,permission); + } + + @Override + public String getPermissionString(String world, String name, String permission) { + return plugin.getWorldsHolder().getWorldData(world).getPermissionsHandler().getPermissionString(name,permission); + } + + @Override + public String getPermissionString(String name, String permission) { + return plugin.getWorldsHolder().getDefaultWorld().getPermissionsHandler().getPermissionString(name,permission); + } + + @Override + public int getPermissionInteger(String world, String name, String permission) { + return plugin.getWorldsHolder().getWorldData(world).getPermissionsHandler().getPermissionInteger(name,permission); + } + + @Override + public int getPermissionInteger(String name, String permission) { + return plugin.getWorldsHolder().getDefaultWorld().getPermissionsHandler().getPermissionInteger(name,permission); + } + + @Override + public boolean getPermissionBoolean(String world, String name, String permission) { + return plugin.getWorldsHolder().getWorldData(world).getPermissionsHandler().getPermissionBoolean(name,permission); + } + + @Override + public boolean getPermissionBoolean(String name, String permission) { + return plugin.getWorldsHolder().getDefaultWorld().getPermissionsHandler().getPermissionBoolean(name,permission); + } + + @Override + public double getPermissionDouble(String world, String name, String permission) { + return plugin.getWorldsHolder().getWorldData(world).getPermissionsHandler().getPermissionDouble(name,permission); + } + + @Override + public double getPermissionDouble(String name, String permission) { + return plugin.getWorldsHolder().getDefaultWorld().getPermissionsHandler().getPermissionDouble(name,permission); + } + +} diff --git a/EssentialsGroupBridge/src/plugin.yml b/EssentialsGroupBridge/src/plugin.yml new file mode 100644 index 000000000..af93ee4a0 --- /dev/null +++ b/EssentialsGroupBridge/src/plugin.yml @@ -0,0 +1,3 @@ +name: Permissions +version: 2.5.1 +main: com.nijikokun.bukkit.Permissions.Permissions diff --git a/EssentialsGroupManager/build.xml b/EssentialsGroupManager/build.xml new file mode 100644 index 000000000..9eb86de21 --- /dev/null +++ b/EssentialsGroupManager/build.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + Builds, tests, and runs the project EssentialsGroupManager. + + + diff --git a/EssentialsGroupManager/nbproject/build-impl.xml b/EssentialsGroupManager/nbproject/build-impl.xml new file mode 100644 index 000000000..cf2c8bef0 --- /dev/null +++ b/EssentialsGroupManager/nbproject/build-impl.xml @@ -0,0 +1,1033 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + + + + + + java -cp "${run.classpath.with.dist.jar}" ${main.class} + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + + + + + + + + Must select one file in the IDE or set profile.class + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + 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 applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/EssentialsGroupManager/nbproject/genfiles.properties b/EssentialsGroupManager/nbproject/genfiles.properties new file mode 100644 index 000000000..b34deb399 --- /dev/null +++ b/EssentialsGroupManager/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=a6709b83 +build.xml.script.CRC32=5b346364 +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=a6709b83 +nbproject/build-impl.xml.script.CRC32=70ed0f6c +nbproject/build-impl.xml.stylesheet.CRC32=19debb58@1.42.1.45 diff --git a/EssentialsGroupManager/nbproject/private/private.properties b/EssentialsGroupManager/nbproject/private/private.properties new file mode 100644 index 000000000..94183418a --- /dev/null +++ b/EssentialsGroupManager/nbproject/private/private.properties @@ -0,0 +1 @@ +user.properties.file=C:\\Users\\Paul\\.netbeans\\7.0beta2\\build.properties diff --git a/EssentialsGroupManager/nbproject/project.properties b/EssentialsGroupManager/nbproject/project.properties new file mode 100644 index 000000000..c3e38f7a8 --- /dev/null +++ b/EssentialsGroupManager/nbproject/project.properties @@ -0,0 +1,73 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.title=EssentialsGroupManager +application.vendor=gabrielcouto +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/EssentialsGroupManager.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +file.reference.craftbukkit-0.0.1-SNAPSHOT.jar=..\\lib\\craftbukkit-0.0.1-SNAPSHOT.jar +includes=** +jar.compress=false +javac.classpath=\ + ${file.reference.craftbukkit-0.0.1-SNAPSHOT.jar} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.6 +javac.target=1.6 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +main.class= +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project +# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value +# or test-sys-prop.name=value to set system properties for unit tests): +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/EssentialsGroupManager/nbproject/project.xml b/EssentialsGroupManager/nbproject/project.xml new file mode 100644 index 000000000..6cc53fda9 --- /dev/null +++ b/EssentialsGroupManager/nbproject/project.xml @@ -0,0 +1,15 @@ + + + org.netbeans.modules.java.j2seproject + + + EssentialsGroupManager + + + + + + + + + diff --git a/EssentialsGroupManager/src/config.yml b/EssentialsGroupManager/src/config.yml new file mode 100644 index 000000000..68308cca2 --- /dev/null +++ b/EssentialsGroupManager/src/config.yml @@ -0,0 +1,14 @@ +settings: + data: + save: + minutes: 10 + logging: + level: INFO + permission: + world: + mirror: + world1: + - world2 + - world3 + world4: + - world5 \ No newline at end of file diff --git a/EssentialsGroupManager/src/groups.yml b/EssentialsGroupManager/src/groups.yml new file mode 100644 index 000000000..73c55b880 --- /dev/null +++ b/EssentialsGroupManager/src/groups.yml @@ -0,0 +1,172 @@ +groups: + Default: + default: true + permissions: + - essentials.help + - essentials.home + - essentials.motd + - essentials.sethome + - essentials.spawn + inheritance: [] + info: + prefix: '' + build: false + suffix: '' + SemiAdmin: + default: false + permissions: + - +groupmanager.mandemote + - +groupmanager.manpromote + - -groupmanager.* + - '*' + inheritance: + - moderator + info: + prefix: '&c' + build: true + suffix: SemiAdmin + RedFaction: + default: false + permissions: [] + inheritance: + - peasant + info: + prefix: '&c' + roles-category: faction + build: true + suffix: Red + Farmer: + default: false + permissions: + - essentials.kit + - essentials.kit.farmer + - essentials.spawnmob + inheritance: [] + info: + roles-requirement: + - BlueFaction + - RedFaction + prefix: '' + roles-category: job + build: false + suffix: '' + Healer: + default: false + permissions: + - essentials.kit + - essentials.kit.healer + - essentials.heal + inheritance: [] + info: + roles-requirement: + - BlueFaction + - RedFaction + prefix: '' + roles-category: job + build: false + suffix: '' + Fighter: + default: false + permissions: + - essentials.kit + - essentials.kit.fighter + inheritance: [] + info: + prefix: '' + roles-category: skill + build: false + suffix: '' + Admin: + default: false + permissions: + - '*' + inheritance: + - semiadmin + info: + prefix: '' + build: true + suffix: '' + Miner: + default: false + permissions: + - essentials.kit + - essentials.kit.miner + - flashlight.regular + inheritance: [] + info: + roles-requirement: + - BlueFaction + - RedFaction + prefix: '' + roles-category: job + build: false + suffix: '' + FlyingMan: + default: false + permissions: + - nocheat.moving + inheritance: [] + info: + roles-requirement: Fighter&SuperCart + prefix: '' + roles-category: skill + build: false + suffix: '' + Peasant: + default: false + permissions: + - roles.joinrole + - roles.leaverole + - roles.myroles + inheritance: + - default + info: + prefix: '&e' + build: true + suffix: Peasant + BlueFaction: + default: false + permissions: [] + inheritance: + - peasant + info: + prefix: '&d' + roles-category: faction + build: true + suffix: Blue + Railer: + default: false + permissions: + - essentials.kit + - essentials.kit.railer + inheritance: [] + info: + roles-requirement: Miner + prefix: '' + roles-category: subjob + build: false + suffix: '' + SuperCart: + default: false + permissions: + - minecartmania.* + inheritance: [] + info: + roles-requirement: Railer + prefix: '' + roles-category: skill + build: false + suffix: '' + Moderator: + default: false + permissions: + - essentials.tp + - essentials.tphere + - essentials.item + - essentials.give + inheritance: + - default + info: + prefix: '&c' + build: true + suffix: Mod \ No newline at end of file diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/GMConfiguration.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/GMConfiguration.java new file mode 100644 index 000000000..68253eccc --- /dev/null +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/GMConfiguration.java @@ -0,0 +1,120 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.anjocaido.groupmanager; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Map; +import java.util.logging.Level; +import org.anjocaido.groupmanager.utils.Tasks; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.SafeConstructor; +import org.yaml.snakeyaml.reader.UnicodeReader; + +/** + * + * @author gabrielcouto + */ +public class GMConfiguration { + + private GroupManager plugin; + private Map rootDataNode; + private File configFile; + + public GMConfiguration(GroupManager plugin) { + this.plugin = plugin; + load(); + } + + public void load() { + if (!plugin.getDataFolder().exists()) { + plugin.getDataFolder().mkdirs(); + } + configFile = new File(plugin.getDataFolder(), "config.yml"); + + if (!configFile.exists()) { + try { + Tasks.copy(plugin.getResourceAsStream("config.yml"), configFile); + } catch (IOException ex) { + GroupManager.logger.log(Level.SEVERE, null, ex); + } + } + + Yaml yaml = new Yaml(new SafeConstructor()); + FileInputStream rx = null; + try { + rx = new FileInputStream(configFile); + } catch (FileNotFoundException ex) { + GroupManager.logger.log(Level.SEVERE, null, ex); + } + try { + rootDataNode = (Map) yaml.load(new UnicodeReader(rx)); + if (rootDataNode == null) { + throw new NullPointerException(); + } + } catch (Exception ex) { + throw new IllegalArgumentException("The following file couldn't pass on Parser.\n" + configFile.getPath(), ex); + } finally { + try { + rx.close(); + } catch (IOException ex) { + } + } + adjustLoggerLevel(); + } + + public Map getMirrorsMap() { + if (rootDataNode.get("settings") instanceof Map) { + Map settingsNode = (Map) rootDataNode.get("settings"); + if (settingsNode.get("permission") instanceof Map) { + Map permissionNode = (Map) settingsNode.get("permission"); + if (permissionNode.get("world") instanceof Map) { + Map worldsNode = (Map) permissionNode.get("world"); + if (worldsNode.get("mirror") instanceof Map) { + Map mirrorsNode = (Map) worldsNode.get("mirror"); + return mirrorsNode; + } + } + } + } + return null; + } + + public Integer getSaveInterval() { + if (rootDataNode.get("settings") instanceof Map) { + Map settingsNode = (Map) rootDataNode.get("settings"); + if (settingsNode.get("data") instanceof Map) { + Map dataNode = (Map) settingsNode.get("data"); + if (dataNode.get("save") instanceof Map) { + Map saveNode = (Map) dataNode.get("save"); + if (saveNode.get("minutes") instanceof Integer) { + return (Integer) saveNode.get("minutes"); + } + } + } + } + return 10; + } + + public void adjustLoggerLevel() { + if (rootDataNode.get("settings") instanceof Map) { + Map settingsNode = (Map) rootDataNode.get("settings"); + if (settingsNode.get("logging") instanceof Map) { + Map loggingNode = (Map) settingsNode.get("logging"); + if (loggingNode.get("level") instanceof String) { + String level = (String) loggingNode.get("level"); + try { + GroupManager.logger.setLevel(Level.parse(level)); + return; + } catch (Exception e) { + } + } + } + } + GroupManager.logger.setLevel(Level.INFO); + } +} diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/GroupManager.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/GroupManager.java new file mode 100644 index 000000000..2ea0007b0 --- /dev/null +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/GroupManager.java @@ -0,0 +1,1634 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.anjocaido.groupmanager; + +import org.anjocaido.groupmanager.permissions.AnjoPermissionsHandler; +import org.anjocaido.groupmanager.utils.GroupManagerPermissions; +import org.anjocaido.groupmanager.data.Variables; +import org.anjocaido.groupmanager.data.User; +import org.anjocaido.groupmanager.data.Group; +import org.anjocaido.groupmanager.dataholder.OverloadedWorldHolder; +import org.anjocaido.groupmanager.dataholder.WorldDataHolder; +import java.io.File; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.anjocaido.groupmanager.dataholder.worlds.WorldsHolder; +import org.anjocaido.groupmanager.utils.GMLoggerHandler; +import org.anjocaido.groupmanager.utils.PermissionCheckResult; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.entity.Player; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.java.JavaPlugin; + +/** + * + * @author gabrielcouto + */ +public class GroupManager extends JavaPlugin { + + private File configFile; + private File backupFolder; + private Runnable commiter; + private ScheduledThreadPoolExecutor scheduler; + private Map> overloadedUsers = new HashMap>(); + private Map selectedWorlds = new HashMap(); + private WorldsHolder worldsHolder; + private boolean validateOnlinePlayer = true; + private boolean isReady = false; + private GMConfiguration config; + public static final Logger logger = Logger.getLogger(GroupManager.class.getName()); + + @Override + public void onDisable() { + if (worldsHolder != null) { + worldsHolder.saveChanges(); + } + disableScheduler(); + // EXAMPLE: Custom code, here we just output some info so we can check all is well + PluginDescriptionFile pdfFile = this.getDescription(); + System.out.println(pdfFile.getName() + " version " + pdfFile.getVersion() + " is disabled!"); + } + + @Override + public void onEnable() { + GroupManager.logger.setUseParentHandlers(false); + GMLoggerHandler ch = new GMLoggerHandler(); + GroupManager.logger.addHandler(ch); + logger.setLevel(Level.ALL); + if (worldsHolder == null) { + prepareFileFields(); + prepareConfig(); + worldsHolder = new WorldsHolder(this); + } + + PluginDescriptionFile pdfFile = this.getDescription(); + if (worldsHolder == null) { + GroupManager.logger.severe("Can't enable " + pdfFile.getName() + " version " + pdfFile.getVersion() + ", bad loading!"); + this.getServer().getPluginManager().disablePlugin(this); + throw new IllegalStateException("An error ocurred while loading GroupManager"); + } + + enableScheduler(); + System.out.println(pdfFile.getName() + " version " + pdfFile.getVersion() + " is enabled!"); + } + + public InputStream getResourceAsStream(String fileName) { + return this.getClassLoader().getResourceAsStream(fileName); + } + + private void prepareFileFields() { + configFile = new File(this.getDataFolder(), "config.yml"); + backupFolder = new File(this.getDataFolder(), "backup"); + if (!backupFolder.exists()) { + getBackupFolder().mkdirs(); + } + } + + private void prepareConfig() { + config = new GMConfiguration(this); + } + + public void enableScheduler() { + if (worldsHolder != null) { + disableScheduler(); + commiter = new Runnable() { + + @Override + public void run() { + GroupManager.this.worldsHolder.saveChanges(); + } + }; + scheduler = new ScheduledThreadPoolExecutor(1); + int minutes = getConfig().getSaveInterval(); + scheduler.scheduleAtFixedRate(commiter, minutes, minutes, TimeUnit.MINUTES); + GroupManager.logger.info("Scheduled Data Saving is set for every " + minutes + " minutes!"); + } + } + + public void disableScheduler() { + if (scheduler != null) { + try { + scheduler.setContinueExistingPeriodicTasksAfterShutdownPolicy(false); + scheduler.setExecuteExistingDelayedTasksAfterShutdownPolicy(false); + scheduler.shutdown(); + } catch (Exception e) { + } + scheduler = null; + GroupManager.logger.info("Scheduled Data Saving is disabled!"); + } + } + + /** + * Use the WorldsHolder saveChanges directly instead + * Saves the data on file + */ + @Deprecated + public void commit() { + if (worldsHolder != null) { + worldsHolder.saveChanges(); + } + } + + /** + * Use worlds holder to reload a specific world + * Reloads the data + */ + @Deprecated + public void reload() { + worldsHolder.reloadAll(); + } + + public WorldsHolder getWorldsHolder() { + return worldsHolder; + } + + /** + * The handler in the interface created by AnjoCaido + * @return + */ + @Deprecated + public AnjoPermissionsHandler getPermissionHandler() { + return worldsHolder.getDefaultWorld().getPermissionsHandler(); + } + + /** + * A simple interface, for ones that don't want to mess with overloading. + * Yet it is affected by overloading. But seamless. + * @return the dataholder with all information + */ + @Deprecated + public WorldDataHolder getData() { + return worldsHolder.getDefaultWorld(); + } + + /** + * Use this if you want to play with overloading. + * @return a dataholder with overloading interface + */ + @Deprecated + public OverloadedWorldHolder getOverloadedClassData() { + return worldsHolder.getDefaultWorld(); + } + + /** + * Called when a command registered by this plugin is received. + * @param sender + * @param cmd + * @param args + */ + @Override + public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) { + boolean playerCanDo = false; + boolean isConsole = false; + Player senderPlayer = null; + Group senderGroup = null; + User senderUser = null; + + + //DETERMINING PLAYER INFORMATION + if (sender instanceof Player) { + senderPlayer = (Player) sender; + senderUser = worldsHolder.getWorldData(senderPlayer).getUser(senderPlayer.getName()); + senderGroup = senderUser.getGroup(); + if (worldsHolder.getWorldPermissions(senderPlayer).has(senderPlayer, "groupmanager." + cmd.getName())) { + playerCanDo = true; + } + } else if (sender instanceof ConsoleCommandSender) { + isConsole = true; + } + + //PERMISSIONS FOR COMMAND BEING LOADED + OverloadedWorldHolder dataHolder = null; + AnjoPermissionsHandler permissionHandler = null; + + if (senderPlayer != null) { + dataHolder = worldsHolder.getWorldData(senderPlayer); + } + + String selectedWorld = selectedWorlds.get(sender); + if (selectedWorld != null) { + dataHolder = worldsHolder.getWorldData(selectedWorld); + } + + if (dataHolder != null) { + permissionHandler = dataHolder.getPermissionsHandler(); + } + + //VARIABLES USED IN COMMANDS + + + int count; + PermissionCheckResult permissionResult = null; + ArrayList removeList = null; + String auxString = null; + List match = null; + User auxUser = null; + Group auxGroup = null; + Group auxGroup2 = null; + + GroupManagerPermissions execCmd = null; + try { + execCmd = GroupManagerPermissions.valueOf(cmd.getName()); + } catch (Exception e) { + //this error happened once with someone. now im prepared... i think + GroupManager.logger.severe("==================================================="); + GroupManager.logger.severe("= ERROR REPORT START ="); + GroupManager.logger.severe("==================================================="); + GroupManager.logger.severe("= COPY AND PASTE THIS TO GROUPMANAGER DEVELOPER ="); + GroupManager.logger.severe("==================================================="); + GroupManager.logger.severe(this.getDescription().getName()); + GroupManager.logger.severe(this.getDescription().getVersion()); + GroupManager.logger.severe("An error occured while trying to execute command:"); + GroupManager.logger.severe(cmd.getName()); + GroupManager.logger.severe("With " + args.length + " arguments:"); + for (String ar : args) { + GroupManager.logger.severe(ar); + } + GroupManager.logger.severe("The field '" + cmd.getName() + "' was not found in enum."); + GroupManager.logger.severe("And could not be parsed."); + GroupManager.logger.severe("FIELDS FOUND IN ENUM:"); + for (GroupManagerPermissions val : GroupManagerPermissions.values()) { + GroupManager.logger.severe(val.name()); + } + GroupManager.logger.severe("==================================================="); + GroupManager.logger.severe("= ERROR REPORT ENDED ="); + GroupManager.logger.severe("==================================================="); + sender.sendMessage("An error occurred. Ask the admin to take a look at the console."); + } + + if (isConsole || playerCanDo) { + switch (execCmd) { + case manuadd: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length != 2) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + if (validateOnlinePlayer) { + match = this.getServer().matchPlayer(args[0]); + if (match.size() != 1) { + sender.sendMessage(ChatColor.RED + "Player not found!"); + return false; + } + } + if (match != null) { + auxUser = dataHolder.getUser(match.get(0).getName()); + } else { + auxUser = dataHolder.getUser(args[0]); + } + auxGroup = dataHolder.getGroup(args[1]); + if (auxGroup == null) { + sender.sendMessage(ChatColor.RED + "Group not found!"); + return false; + } + //VALIDANDO PERMISSAO + if (!isConsole && (senderGroup != null ? permissionHandler.inGroup(auxUser.getName(), senderGroup.getName()) : false)) { + sender.sendMessage(ChatColor.RED + "Can't modify player with same permissions than you, or higher."); + return false; + } + //PARECE OK + auxUser.setGroup(auxGroup); + sender.sendMessage(ChatColor.YELLOW + "You changed player '" + auxUser.getName() + "' group to '" + auxGroup.getName() + "'."); + + return true; + //break; + case manudel: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length != 1) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + if (validateOnlinePlayer) { + match = this.getServer().matchPlayer(args[0]); + if (match.size() != 1) { + sender.sendMessage(ChatColor.RED + "Player not found!"); + return false; + } + } + if (match != null) { + auxUser = dataHolder.getUser(match.get(0).getName()); + } else { + auxUser = dataHolder.getUser(args[0]); + } + //VALIDANDO PERMISSAO + if (!isConsole && (senderGroup != null ? permissionHandler.inGroup(auxUser.getName(), senderGroup.getName()) : false)) { + sender.sendMessage(ChatColor.RED + "Can't modify player with same permissions than you, or higher."); + return false; + } + //PARECE OK + dataHolder.removeUser(auxUser.getName()); + sender.sendMessage(ChatColor.YELLOW + "You changed player '" + auxUser.getName() + "' to default settings."); + + return true; + case manuaddsub: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length != 2) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + if (validateOnlinePlayer) { + match = this.getServer().matchPlayer(args[0]); + if (match.size() != 1) { + sender.sendMessage(ChatColor.RED + "Player not found!"); + return false; + } + } + if (match != null) { + auxUser = dataHolder.getUser(match.get(0).getName()); + } else { + auxUser = dataHolder.getUser(args[0]); + } + auxGroup = dataHolder.getGroup(args[1]); + if (auxGroup == null) { + sender.sendMessage(ChatColor.RED + "Group not found!"); + return false; + } + //VALIDANDO PERMISSAO + if (!isConsole && (senderGroup != null ? permissionHandler.inGroup(auxUser.getName(), senderGroup.getName()) : false)) { + sender.sendMessage(ChatColor.RED + "Can't modify player with same permissions than you, or higher."); + return false; + } + //PARECE OK + auxUser.addSubGroup(auxGroup); + sender.sendMessage(ChatColor.YELLOW + "You changed player '" + auxUser.getName() + "' group to '" + auxGroup.getName() + "'."); + + return true; + case manudelsub: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length != 1) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + if (validateOnlinePlayer) { + match = this.getServer().matchPlayer(args[0]); + if (match.size() != 1) { + sender.sendMessage(ChatColor.RED + "Player not found!"); + return false; + } + } + if (match != null) { + auxUser = dataHolder.getUser(match.get(0).getName()); + } else { + auxUser = dataHolder.getUser(args[0]); + } + //VALIDANDO PERMISSAO + if (!isConsole && (senderGroup != null ? permissionHandler.inGroup(auxUser.getName(), senderGroup.getName()) : false)) { + sender.sendMessage(ChatColor.RED + "Can't modify player with same permissions than you, or higher."); + return false; + } + //PARECE OK + auxUser.removeSubGroup(auxGroup); + sender.sendMessage(ChatColor.YELLOW + "You removed subgroup '" + auxGroup.getName() + "' from player '" + auxUser.getName() + "' list."); + + return true; + case mangadd: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length != 1) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + auxGroup = dataHolder.getGroup(args[0]); + if (auxGroup != null) { + sender.sendMessage(ChatColor.RED + "Group already exists!"); + return false; + } + //PARECE OK + auxGroup = dataHolder.createGroup(args[0]); + sender.sendMessage(ChatColor.YELLOW + "You created a group named: " + auxGroup.getName()); + + return true; + case mangdel: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length != 1) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + auxGroup = dataHolder.getGroup(args[0]); + if (auxGroup == null) { + sender.sendMessage(ChatColor.RED + "Group not exists!"); + return false; + } + //PARECE OK + dataHolder.removeGroup(auxGroup.getName()); + sender.sendMessage(ChatColor.YELLOW + "You deleted a group named " + auxGroup.getName() + ", it's users are default group now."); + + return true; + case manuaddp: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length != 2) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + if (validateOnlinePlayer) { + match = this.getServer().matchPlayer(args[0]); + if (match.size() != 1) { + sender.sendMessage(ChatColor.RED + "Player not found!"); + return false; + } + } + if (match != null) { + auxUser = dataHolder.getUser(match.get(0).getName()); + } else { + auxUser = dataHolder.getUser(args[0]); + } + //VALIDANDO SUA PERMISSAO + if (!isConsole && (senderGroup != null ? permissionHandler.inGroup(auxUser.getName(), senderGroup.getName()) : false)) { + sender.sendMessage(ChatColor.RED + "Can't modify player with same group than you, or higher."); + return false; + } + permissionResult = permissionHandler.checkFullUserPermission(senderUser, args[1]); + if (!isConsole && (permissionResult.resultType.equals(PermissionCheckResult.Type.NOTFOUND) + || permissionResult.resultType.equals(PermissionCheckResult.Type.NEGATION))) { + sender.sendMessage(ChatColor.RED + "Can't add a permission you don't have."); + return false; + } + //VALIDANDO PERMISSAO DO DESTINO + permissionResult = permissionHandler.checkUserOnlyPermission(auxUser, args[1]); + if (args[1].startsWith("+")) { + if (permissionResult.resultType.equals(PermissionCheckResult.Type.EXCEPTION)) { + sender.sendMessage(ChatColor.RED + "The user already has direct access to that permission."); + sender.sendMessage(ChatColor.RED + "Node: " + permissionResult.accessLevel); + return false; + } + } else if (args[1].startsWith("-")) { + if (permissionResult.resultType.equals(PermissionCheckResult.Type.EXCEPTION)) { + sender.sendMessage(ChatColor.RED + "The user already has an exception for this node."); + sender.sendMessage(ChatColor.RED + "Node: " + permissionResult.accessLevel); + return false; + } else if (permissionResult.resultType.equals(PermissionCheckResult.Type.NEGATION)) { + sender.sendMessage(ChatColor.RED + "The user already has a matching node "); + sender.sendMessage(ChatColor.RED + "Node: " + permissionResult.accessLevel); + return false; + } + } else { + if (permissionResult.resultType.equals(PermissionCheckResult.Type.FOUND)) { + sender.sendMessage(ChatColor.RED + "The user already has direct access to that permission."); + sender.sendMessage(ChatColor.RED + "Node: " + permissionResult.accessLevel); + return false; + } + } + //PARECE OK + auxUser.addPermission(args[1]); + sender.sendMessage(ChatColor.YELLOW + "You added '" + args[1] + "' to player '" + auxUser.getName() + "' permissions."); + return true; + //break; + case manudelp: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length != 2) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + if (validateOnlinePlayer) { + match = this.getServer().matchPlayer(args[0]); + if (match.size() != 1) { + sender.sendMessage(ChatColor.RED + "Player not found!"); + return false; + } + } + if (match != null) { + auxUser = dataHolder.getUser(match.get(0).getName()); + } else { + auxUser = dataHolder.getUser(args[0]); + } + //VALIDANDO SUA PERMISSAO + if (!isConsole && (senderGroup != null ? permissionHandler.inGroup(auxUser.getName(), senderGroup.getName()) : false)) { + sender.sendMessage(ChatColor.RED + "Can't modify player with same group than you, or higher."); + return false; + } + permissionResult = permissionHandler.checkFullUserPermission(senderUser, args[1]); + if (!isConsole && (permissionResult.resultType.equals(PermissionCheckResult.Type.NOTFOUND) + || permissionResult.resultType.equals(PermissionCheckResult.Type.NEGATION))) { + sender.sendMessage(ChatColor.RED + "Can't remove a permission you don't have."); + return false; + } + //VALIDANDO PERMISSAO DO DESTINO + permissionResult = permissionHandler.checkUserOnlyPermission(auxUser, args[1]); + if (permissionResult.resultType.equals(PermissionCheckResult.Type.NOTFOUND)) { + sender.sendMessage(ChatColor.RED + "The user doesn't have direct access to that permission."); + return false; + } + if (!auxUser.hasSamePermissionNode(args[1])) { + sender.sendMessage(ChatColor.RED + "This permission node doesn't match any node."); + sender.sendMessage(ChatColor.RED + "But might match node: " + permissionResult.accessLevel); + return false; + } + //PARECE OK + auxUser.removePermission(args[1]); + sender.sendMessage(ChatColor.YELLOW + "You removed '" + args[1] + "' from player '" + auxUser.getName() + "' permissions."); + + return true; + //break; + case manulistp: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length != 1) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + if (validateOnlinePlayer) { + match = this.getServer().matchPlayer(args[0]); + if (match.size() != 1) { + sender.sendMessage(ChatColor.RED + "Player not found!"); + return false; + } + } + if (match != null) { + auxUser = dataHolder.getUser(match.get(0).getName()); + } else { + auxUser = dataHolder.getUser(args[0]); + } + //VALIDANDO PERMISSAO + //PARECE OK + auxString = ""; + for (String perm : auxUser.getPermissionList()) { + auxString += perm + ", "; + } + if (auxString.lastIndexOf(",") > 0) { + auxString = auxString.substring(0, auxString.lastIndexOf(",")); + sender.sendMessage(ChatColor.YELLOW + "The player '" + auxUser.getName() + "' has following permissions: " + ChatColor.WHITE + auxString); + sender.sendMessage(ChatColor.YELLOW + "And all permissions from group: " + auxUser.getGroupName()); + auxString = ""; + for (String subGroup : auxUser.subGroupListStringCopy()) { + auxString += subGroup + ", "; + } + if (auxString.lastIndexOf(",") > 0) { + auxString = auxString.substring(0, auxString.lastIndexOf(",")); + sender.sendMessage(ChatColor.YELLOW + "And all permissions from subgroups: " + auxString); + } + } else { + sender.sendMessage(ChatColor.YELLOW + "The player '" + auxUser.getName() + "' has no specific permissions."); + sender.sendMessage(ChatColor.YELLOW + "Only all permissions from group: " + auxUser.getGroupName()); + auxString = ""; + for (String subGroup : auxUser.subGroupListStringCopy()) { + auxString += subGroup + ", "; + } + if (auxString.lastIndexOf(",") > 0) { + auxString = auxString.substring(0, auxString.lastIndexOf(",")); + sender.sendMessage(ChatColor.YELLOW + "And all permissions from subgroups: " + auxString); + } + } + return true; + case manucheckp: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length != 2) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + if (validateOnlinePlayer) { + match = this.getServer().matchPlayer(args[0]); + if (match.size() != 1) { + sender.sendMessage(ChatColor.RED + "Player not found!"); + return false; + } + } + if (match != null) { + auxUser = dataHolder.getUser(match.get(0).getName()); + } else { + auxUser = dataHolder.getUser(args[0]); + } + //VALIDANDO PERMISSAO + permissionResult = permissionHandler.checkFullUserPermission(auxUser, args[1]); + if (permissionResult.resultType.equals(PermissionCheckResult.Type.NOTFOUND)) { + sender.sendMessage(ChatColor.RED + "The player doesn't have access to that permission"); + return false; + } + //PARECE OK + //auxString = permissionHandler.checkUserOnlyPermission(auxUser, args[1]); + if (permissionResult.owner instanceof User) { + if (permissionResult.resultType.equals(PermissionCheckResult.Type.NEGATION)) { + sender.sendMessage(ChatColor.RED + "The user has directly a negation node for that permission."); + } else { + sender.sendMessage(ChatColor.YELLOW + "The user has directly this permission."); + } + sender.sendMessage(ChatColor.YELLOW + "Permission Node: " + permissionResult.accessLevel); + } else if (permissionResult.owner instanceof Group) { + if (permissionResult.resultType.equals(PermissionCheckResult.Type.NEGATION)) { + sender.sendMessage(ChatColor.RED + "The user inherits the a negation permission from group: " + permissionResult.owner.getName()); + } else { + sender.sendMessage(ChatColor.YELLOW + "The user inherits the permission from group: " + permissionResult.owner.getName()); + } + sender.sendMessage(ChatColor.YELLOW + "Permission Node: " + permissionResult.accessLevel); + } + return true; + case mangaddp: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length != 2) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + auxGroup = dataHolder.getGroup(args[0]); + if (auxGroup == null) { + sender.sendMessage(ChatColor.RED + "Group does not exists!"); + return false; + } + //VALIDANDO SUA PERMISSAO + permissionResult = permissionHandler.checkFullUserPermission(senderUser, args[1]); + if (!isConsole && (permissionResult.resultType.equals(PermissionCheckResult.Type.NOTFOUND) + || permissionResult.resultType.equals(PermissionCheckResult.Type.NEGATION))) { + sender.sendMessage(ChatColor.RED + "Can't add a permission you don't have."); + return false; + } + //VALIDANDO PERMISSAO DO DESTINO + permissionResult = permissionHandler.checkGroupOnlyPermission(auxGroup, args[1]); + if (args[1].startsWith("+")) { + if (permissionResult.resultType.equals(PermissionCheckResult.Type.EXCEPTION)) { + sender.sendMessage(ChatColor.RED + "The group already has direct access to that permission."); + sender.sendMessage(ChatColor.RED + "Node: " + permissionResult.accessLevel); + return false; + } + } else if (args[1].startsWith("-")) { + if (permissionResult.resultType.equals(PermissionCheckResult.Type.EXCEPTION)) { + sender.sendMessage(ChatColor.RED + "The group already has an exception for this node."); + sender.sendMessage(ChatColor.RED + "Node: " + permissionResult.accessLevel); + return false; + } else if (permissionResult.resultType.equals(PermissionCheckResult.Type.NEGATION)) { + sender.sendMessage(ChatColor.RED + "The group already has a matching node."); + sender.sendMessage(ChatColor.RED + "Node: " + permissionResult.accessLevel); + return false; + } + } else { + if (permissionResult.resultType.equals(PermissionCheckResult.Type.FOUND)) { + sender.sendMessage(ChatColor.RED + "The user already has direct access to that permission."); + sender.sendMessage(ChatColor.RED + "Node: " + permissionResult.accessLevel); + return false; + } + } + //PARECE OK + auxGroup.addPermission(args[1]); + sender.sendMessage(ChatColor.YELLOW + "You added '" + args[1] + "' to group '" + auxGroup.getName() + "' permissions."); + + return true; + case mangdelp: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length != 2) { + return false; + } + auxGroup = dataHolder.getGroup(args[0]); + if (auxGroup == null) { + sender.sendMessage(ChatColor.RED + "Group does not exists!"); + return false; + } + //VALIDANDO SUA PERMISSAO + permissionResult = permissionHandler.checkFullUserPermission(senderUser, args[1]); + if (!isConsole && (permissionResult.resultType.equals(PermissionCheckResult.Type.NOTFOUND) + || permissionResult.resultType.equals(PermissionCheckResult.Type.NEGATION))) { + sender.sendMessage(ChatColor.RED + "Can't remove a permission you don't have."); + return false; + } + //VALIDANDO PERMISSAO DO DESTINO + permissionResult = permissionHandler.checkGroupOnlyPermission(auxGroup, args[1]); + if (permissionResult.resultType.equals(PermissionCheckResult.Type.NOTFOUND)) { + sender.sendMessage(ChatColor.RED + "The group doesn't have direct access to that permission."); + return false; + } + if (!auxGroup.hasSamePermissionNode(args[1])) { + sender.sendMessage(ChatColor.RED + "This permission node doesn't match any node."); + sender.sendMessage(ChatColor.RED + "But might match node: " + permissionResult.accessLevel); + return false; + } + //PARECE OK + auxGroup.removePermission(args[1]); + sender.sendMessage(ChatColor.YELLOW + "You removed '" + args[1] + "' from group '" + auxGroup.getName() + "' permissions."); + + return true; + case manglistp: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length != 1) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + auxGroup = dataHolder.getGroup(args[0]); + if (auxGroup == null) { + sender.sendMessage(ChatColor.RED + "Group does not exists!"); + return false; + } + //VALIDANDO PERMISSAO + + //PARECE OK + auxString = ""; + for (String perm : auxGroup.getPermissionList()) { + auxString += perm + ", "; + } + if (auxString.lastIndexOf(",") > 0) { + auxString = auxString.substring(0, auxString.lastIndexOf(",")); + sender.sendMessage(ChatColor.YELLOW + "The group '" + auxGroup.getName() + "' has following permissions: " + ChatColor.WHITE + auxString); + auxString = ""; + for (String grp : auxGroup.getInherits()) { + auxString += grp + ", "; + } + if (auxString.lastIndexOf(",") > 0) { + auxString = auxString.substring(0, auxString.lastIndexOf(",")); + sender.sendMessage(ChatColor.YELLOW + "And all permissions from groups: " + auxString); + } + + } else { + sender.sendMessage(ChatColor.YELLOW + "The grpup '" + auxGroup.getName() + "' has no specific permissions."); + auxString = ""; + for (String grp : auxGroup.getInherits()) { + auxString += grp + ", "; + } + if (auxString.lastIndexOf(",") > 0) { + auxString = auxString.substring(0, auxString.lastIndexOf(",")); + sender.sendMessage(ChatColor.YELLOW + "Only all permissions from groups: " + auxString); + } + + } + return true; + case mangcheckp: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length != 2) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + auxGroup = dataHolder.getGroup(args[0]); + if (auxGroup == null) { + sender.sendMessage(ChatColor.RED + "Group does not exists!"); + return false; + } + //VALIDANDO PERMISSAO + permissionResult = permissionHandler.checkGroupPermissionWithInheritance(auxGroup, args[1]); + if (permissionResult.resultType.equals(PermissionCheckResult.Type.NOTFOUND)) { + sender.sendMessage(ChatColor.RED + "The group doesn't have access to that permission"); + return false; + } + //PARECE OK + //auxString = permissionHandler.checkUserOnlyPermission(auxUser, args[1]); + if (permissionResult.owner instanceof Group) { + if (permissionResult.resultType.equals(PermissionCheckResult.Type.NEGATION)) { + sender.sendMessage(ChatColor.RED + "The group inherits the a negation permission from group: " + permissionResult.owner.getName()); + } else { + sender.sendMessage(ChatColor.YELLOW + "The user inherits the permission from group: " + permissionResult.owner.getName()); + } + sender.sendMessage(ChatColor.YELLOW + "Permission Node: " + permissionResult.accessLevel); + + } + return true; + case mangaddi: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length != 2) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + auxGroup = dataHolder.getGroup(args[0]); + if (auxGroup == null) { + sender.sendMessage(ChatColor.RED + "Group 1 does not exists!"); + return false; + } + auxGroup2 = dataHolder.getGroup(args[1]); + if (auxGroup2 == null) { + sender.sendMessage(ChatColor.RED + "Group 2 does not exists!"); + return false; + } + //VALIDANDO PERMISSAO + if (permissionHandler.searchGroupInInheritance(auxGroup, auxGroup2.getName(), null)) { + sender.sendMessage(ChatColor.RED + "Group " + auxGroup.getName() + " already inherits " + auxGroup2.getName() + " (might not be directly)"); + return false; + } + //PARECE OK + auxGroup.addInherits(auxGroup2); + sender.sendMessage(ChatColor.RED + "Group " + auxGroup2.getName() + " is now in " + auxGroup.getName() + " inheritance list."); + + return true; + case mangdeli: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length != 2) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + auxGroup = dataHolder.getGroup(args[0]); + if (auxGroup == null) { + sender.sendMessage(ChatColor.RED + "Group 1 does not exists!"); + return false; + } + auxGroup2 = dataHolder.getGroup(args[1]); + if (auxGroup2 == null) { + sender.sendMessage(ChatColor.RED + "Group 2 does not exists!"); + return false; + } + //VALIDANDO PERMISSAO + if (!permissionHandler.searchGroupInInheritance(auxGroup, auxGroup2.getName(), null)) { + sender.sendMessage(ChatColor.RED + "Group " + auxGroup.getName() + " does not inherits " + auxGroup2.getName() + "."); + return false; + } + if (!auxGroup.getInherits().contains(auxGroup2.getName())) { + sender.sendMessage(ChatColor.RED + "Group " + auxGroup.getName() + " does not inherits " + auxGroup2.getName() + " directly."); + return false; + } + //PARECE OK + auxGroup.removeInherits(auxGroup2.getName()); + sender.sendMessage(ChatColor.RED + "Group " + auxGroup2.getName() + " was removed from " + auxGroup.getName() + " inheritance list."); + + return true; + case manuaddv: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length < 3) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + if (validateOnlinePlayer) { + match = this.getServer().matchPlayer(args[0]); + if (match.size() != 1) { + sender.sendMessage(ChatColor.RED + "Player not found!"); + return false; + } + } + if (match != null) { + auxUser = dataHolder.getUser(match.get(0).getName()); + } else { + auxUser = dataHolder.getUser(args[0]); + } + //VALIDANDO PERMISSAO + //PARECE OK + auxString = ""; + for (int i = 2; i < args.length; i++) { + auxString += args[i]; + if ((i + 1) < args.length) { + auxString += " "; + } + } + auxUser.getVariables().addVar(args[1], Variables.parseVariableValue(auxString)); + sender.sendMessage(ChatColor.YELLOW + "Variable " + ChatColor.GOLD + args[1] + ChatColor.YELLOW + ":'" + ChatColor.GREEN + auxString + ChatColor.YELLOW + "' added to the user " + auxUser.getName()); + return true; + case manudelv: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length != 2) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + if (validateOnlinePlayer) { + match = this.getServer().matchPlayer(args[0]); + if (match.size() != 1) { + sender.sendMessage(ChatColor.RED + "Player not found!"); + return false; + } + } + if (match != null) { + auxUser = dataHolder.getUser(match.get(0).getName()); + } else { + auxUser = dataHolder.getUser(args[0]); + } + //VALIDANDO PERMISSAO + if (!auxUser.getVariables().hasVar(args[1])) { + sender.sendMessage(ChatColor.RED + "The user doesn't have directly that variable!"); + } + //PARECE OK + auxUser.getVariables().removeVar(args[1]); + sender.sendMessage(ChatColor.YELLOW + "Variable " + ChatColor.GOLD + args[1] + ChatColor.YELLOW + " removed from the user " + ChatColor.GREEN + auxUser.getName()); + return true; + case manulistv: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length != 1) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + if (validateOnlinePlayer) { + match = this.getServer().matchPlayer(args[0]); + if (match.size() != 1) { + sender.sendMessage(ChatColor.RED + "Player not found!"); + return false; + } + } + if (match != null) { + auxUser = dataHolder.getUser(match.get(0).getName()); + } else { + auxUser = dataHolder.getUser(args[0]); + } + //VALIDANDO PERMISSAO + //PARECE OK + auxString = ""; + for (String varKey : auxUser.getVariables().getVarKeyList()) { + Object o = auxUser.getVariables().getVarObject(varKey); + auxString += ChatColor.GOLD + varKey + ChatColor.WHITE + ":'" + ChatColor.GREEN + o.toString() + ChatColor.WHITE + "', "; + } + if (auxString.lastIndexOf(",") > 0) { + auxString = auxString.substring(0, auxString.lastIndexOf(",")); + } + sender.sendMessage(ChatColor.YELLOW + "Variables of user " + auxUser.getName() + ": "); + sender.sendMessage(auxString + "."); + sender.sendMessage(ChatColor.YELLOW + "Plus all variables from group: " + auxUser.getGroupName()); + return true; + case manucheckv: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length != 2) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + if (validateOnlinePlayer) { + match = this.getServer().matchPlayer(args[0]); + if (match.size() != 1) { + sender.sendMessage(ChatColor.RED + "Player not found!"); + return false; + } + } + if (match != null) { + auxUser = dataHolder.getUser(match.get(0).getName()); + } else { + auxUser = dataHolder.getUser(args[0]); + } + //VALIDANDO PERMISSAO + auxGroup = auxUser.getGroup(); + auxGroup2 = permissionHandler.nextGroupWithVariable(auxGroup, args[1], null); + + if (!auxUser.getVariables().hasVar(args[1])) { + if (auxGroup2 == null) { + sender.sendMessage(ChatColor.RED + "The user doesn't have access to that variable!"); + } + } + //PARECE OK + if (auxUser.getVariables().hasVar(auxString)) { + sender.sendMessage(ChatColor.YELLOW + "The value of variable '" + ChatColor.GOLD + args[1] + ChatColor.YELLOW + "' is: '" + ChatColor.GREEN + auxUser.getVariables().getVarObject(args[1]).toString() + ChatColor.WHITE + "'"); + sender.sendMessage(ChatColor.YELLOW + "This user own directly the variable"); + } + sender.sendMessage(ChatColor.YELLOW + "The value of variable '" + ChatColor.GOLD + args[1] + ChatColor.YELLOW + "' is: '" + ChatColor.GREEN + auxGroup2.getVariables().getVarObject(args[1]).toString() + ChatColor.WHITE + "'"); + if (!auxGroup.equals(auxGroup2)) { + sender.sendMessage(ChatColor.YELLOW + "And the value was inherited from group: " + ChatColor.GREEN + auxGroup2.getName()); + } + return true; + case mangaddv: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length < 3) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + auxGroup = dataHolder.getGroup(args[0]); + if (auxGroup == null) { + sender.sendMessage(ChatColor.RED + "Group does not exists!"); + return false; + } + //VALIDANDO PERMISSAO + //PARECE OK + auxString = ""; + for (int i = 2; i < args.length; i++) { + auxString += args[i]; + if ((i + 1) < args.length) { + auxString += " "; + } + } + auxGroup.getVariables().addVar(args[1], Variables.parseVariableValue(auxString)); + sender.sendMessage(ChatColor.YELLOW + "Variable " + ChatColor.GOLD + args[1] + ChatColor.YELLOW + ":'" + ChatColor.GREEN + auxString + ChatColor.YELLOW + "' added to the group " + auxGroup.getName()); + + return true; + case mangdelv: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length != 2) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + auxGroup = dataHolder.getGroup(args[0]); + if (auxGroup == null) { + sender.sendMessage(ChatColor.RED + "Group does not exists!"); + return false; + } + //VALIDANDO PERMISSAO + if (!auxGroup.getVariables().hasVar(args[1])) { + sender.sendMessage(ChatColor.RED + "The group doesn't have directly that variable!"); + } + //PARECE OK + auxGroup.getVariables().removeVar(args[1]); + sender.sendMessage(ChatColor.YELLOW + "Variable " + ChatColor.GOLD + args[1] + ChatColor.YELLOW + " removed from the group " + ChatColor.GREEN + auxGroup.getName()); + + return true; + case manglistv: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length != 1) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + auxGroup = dataHolder.getGroup(args[0]); + if (auxGroup == null) { + sender.sendMessage(ChatColor.RED + "Group does not exists!"); + return false; + } + //VALIDANDO PERMISSAO + //PARECE OK + auxString = ""; + for (String varKey : auxGroup.getVariables().getVarKeyList()) { + Object o = auxGroup.getVariables().getVarObject(varKey); + auxString += ChatColor.GOLD + varKey + ChatColor.WHITE + ":'" + ChatColor.GREEN + o.toString() + ChatColor.WHITE + "', "; + } + if (auxString.lastIndexOf(",") > 0) { + auxString = auxString.substring(0, auxString.lastIndexOf(",")); + } + sender.sendMessage(ChatColor.YELLOW + "Variables of group " + auxGroup.getName() + ": "); + sender.sendMessage(auxString + "."); + auxString = ""; + for (String grp : auxGroup.getInherits()) { + auxString += grp + ", "; + } + if (auxString.lastIndexOf(",") > 0) { + auxString = auxString.substring(0, auxString.lastIndexOf(",")); + sender.sendMessage(ChatColor.YELLOW + "Plus all variables from groups: " + auxString); + } + return true; + case mangcheckv: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length != 2) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + auxGroup = dataHolder.getGroup(args[0]); + if (auxGroup == null) { + sender.sendMessage(ChatColor.RED + "Group does not exists!"); + return false; + } + //VALIDANDO PERMISSAO + auxGroup2 = permissionHandler.nextGroupWithVariable(auxGroup, args[1], null); + if (auxGroup2 == null) { + sender.sendMessage(ChatColor.RED + "The group doesn't have access to that variable!"); + } + //PARECE OK + sender.sendMessage(ChatColor.YELLOW + "The value of variable '" + ChatColor.GOLD + args[1] + ChatColor.YELLOW + "' is: '" + ChatColor.GREEN + auxGroup2.getVariables().getVarObject(args[1]).toString() + ChatColor.WHITE + "'"); + if (!auxGroup.equals(auxGroup2)) { + sender.sendMessage(ChatColor.YELLOW + "And the value was inherited from group: " + ChatColor.GREEN + auxGroup2.getName()); + } + return true; + case manwhois: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length != 1) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + if (validateOnlinePlayer) { + match = this.getServer().matchPlayer(args[0]); + if (match.size() != 1) { + sender.sendMessage(ChatColor.RED + "Player not found!"); + return false; + } + } + if (match != null) { + auxUser = dataHolder.getUser(match.get(0).getName()); + } else { + auxUser = dataHolder.getUser(args[0]); + } + //PARECE OK + sender.sendMessage(ChatColor.YELLOW + "Name: " + ChatColor.GREEN + auxUser.getName()); + sender.sendMessage(ChatColor.YELLOW + "Group: " + ChatColor.GREEN + auxUser.getGroup().getName()); + sender.sendMessage(ChatColor.YELLOW + "Overloaded: " + ChatColor.GREEN + dataHolder.isOverloaded(auxUser.getName())); + auxGroup = dataHolder.surpassOverload(auxUser.getName()).getGroup(); + if (!auxGroup.equals(auxUser.getGroup())) { + sender.sendMessage(ChatColor.YELLOW + "Original Group: " + ChatColor.GREEN + auxGroup.getName()); + } + //victim.permissions.add(args[1]); + return true; + //break; + case tempadd: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length != 1) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + if (validateOnlinePlayer) { + match = this.getServer().matchPlayer(args[0]); + if (match.size() != 1) { + sender.sendMessage(ChatColor.RED + "Player not found!"); + return false; + } + } + if (match != null) { + auxUser = dataHolder.getUser(match.get(0).getName()); + } else { + auxUser = dataHolder.getUser(args[0]); + } + //VALIDANDO PERMISSAO + if (!isConsole && (senderGroup != null ? permissionHandler.inGroup(auxUser.getName(), senderGroup.getName()) : false)) { + sender.sendMessage(ChatColor.RED + "Can't modify player with same permissions than you, or higher."); + return false; + } + //PARECE OK + if (overloadedUsers.get(dataHolder.getName().toLowerCase()) == null) { + overloadedUsers.put(dataHolder.getName().toLowerCase(), new ArrayList()); + } + dataHolder.overloadUser(auxUser.getName()); + overloadedUsers.get(dataHolder.getName().toLowerCase()).add(dataHolder.getUser(auxUser.getName())); + sender.sendMessage(ChatColor.YELLOW + "Player overloaded!"); + + return true; + //break; + case tempdel: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length != 1) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + if (validateOnlinePlayer) { + match = this.getServer().matchPlayer(args[0]); + if (match.size() != 1) { + sender.sendMessage(ChatColor.RED + "Player not found!"); + return false; + } + } + if (match != null) { + auxUser = dataHolder.getUser(match.get(0).getName()); + } else { + auxUser = dataHolder.getUser(args[0]); + } + //VALIDANDO PERMISSAO + if (!isConsole && (senderGroup != null ? permissionHandler.inGroup(auxUser.getName(), senderGroup.getName()) : false)) { + sender.sendMessage(ChatColor.RED + "Can't modify player with same permissions than you, or higher."); + return false; + } + //PARECE OK + if (overloadedUsers.get(dataHolder.getName().toLowerCase()) == null) { + overloadedUsers.put(dataHolder.getName().toLowerCase(), new ArrayList()); + } + dataHolder.removeOverload(auxUser.getName()); + if (overloadedUsers.get(dataHolder.getName().toLowerCase()).contains(auxUser)) { + overloadedUsers.get(dataHolder.getName().toLowerCase()).remove(auxUser); + } + sender.sendMessage(ChatColor.YELLOW + "You removed that player overload. He's back to normal!"); + + return true; + //break; + case templist: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //WORKING + auxString = ""; + removeList = new ArrayList(); + count = 0; + for (User u : overloadedUsers.get(dataHolder.getName().toLowerCase())) { + if (!dataHolder.isOverloaded(u.getName())) { + removeList.add(u); + } else { + auxString += u.getName() + ", "; + count++; + } + } + if (count == 0) { + sender.sendMessage(ChatColor.YELLOW + "There is no users in overload mode"); + return true; + } + auxString = auxString.substring(0, auxString.lastIndexOf(",")); + if (overloadedUsers.get(dataHolder.getName().toLowerCase()) == null) { + overloadedUsers.put(dataHolder.getName().toLowerCase(), new ArrayList()); + } + overloadedUsers.get(dataHolder.getName().toLowerCase()).removeAll(removeList); + sender.sendMessage(ChatColor.YELLOW + " " + count + " Users in overload mode: " + ChatColor.WHITE + auxString); + return true; + case tempdelall: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //WORKING + removeList = new ArrayList(); + count = 0; + for (User u : overloadedUsers.get(dataHolder.getName().toLowerCase())) { + if (dataHolder.isOverloaded(u.getName())) { + dataHolder.removeOverload(u.getName()); + count++; + } + } + if (count == 0) { + sender.sendMessage(ChatColor.YELLOW + "There is no users in overload mode"); + return true; + } + if (overloadedUsers.get(dataHolder.getName().toLowerCase()) == null) { + overloadedUsers.put(dataHolder.getName().toLowerCase(), new ArrayList()); + } + overloadedUsers.get(dataHolder.getName().toLowerCase()).clear(); + sender.sendMessage(ChatColor.YELLOW + " " + count + " Users in overload mode. Now they are normal again."); + + return true; + case mansave: + worldsHolder.saveChanges(); + sender.sendMessage(ChatColor.YELLOW + " The changes were saved."); + return true; + case manload: + //THIS CASE DONT NEED SENDER + if (args.length > 0) { + auxString = ""; + for (int i = 0; i < args.length; i++) { + auxString += args[i]; + if ((i + 1) < args.length) { + auxString += " "; + } + } + worldsHolder.loadWorld(auxString); + sender.sendMessage("The request to world '" + auxString + "' was sent."); + return true; + } + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //WORKING + config.load(); + if (args.length > 0) { + auxString = ""; + for (int i = 0; i < args.length; i++) { + auxString += args[i]; + if ((i + 1) < args.length) { + auxString += " "; + } + } + worldsHolder.loadWorld(auxString); + sender.sendMessage("The request to world '" + auxString + "' was sent."); + } else { + worldsHolder.reloadAll(); + sender.sendMessage(ChatColor.YELLOW + " The current world was reloaded."); + } + worldsHolder.mirrorSetUp(); + return true; + case listgroups: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //WORKING + auxString = ""; + for (Group g : dataHolder.getGroupList()) { + auxString += g.getName() + ", "; + } + if (auxString.lastIndexOf(",") > 0) { + auxString = auxString.substring(0, auxString.lastIndexOf(",")); + } + sender.sendMessage(ChatColor.YELLOW + " Groups Available: " + ChatColor.WHITE + auxString); + return true; + case manpromote: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length != 2) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + if (validateOnlinePlayer) { + match = this.getServer().matchPlayer(args[0]); + if (match.size() != 1) { + sender.sendMessage(ChatColor.RED + "Player not found!"); + return false; + } + } + if (match != null) { + auxUser = dataHolder.getUser(match.get(0).getName()); + } else { + auxUser = dataHolder.getUser(args[0]); + } + auxGroup = dataHolder.getGroup(args[1]); + if (auxGroup == null) { + sender.sendMessage(ChatColor.RED + "Group not found!"); + return false; + } + //VALIDANDO PERMISSAO + if (!isConsole && (senderGroup != null ? permissionHandler.inGroup(auxUser.getName(), senderGroup.getName()) : false)) { + sender.sendMessage(ChatColor.RED + "Can't modify player with same permissions than you, or higher."); + return false; + } + if (!isConsole && (permissionHandler.hasGroupInInheritance(auxGroup, senderGroup.getName()))) { + sender.sendMessage(ChatColor.RED + "The destination group can't be the same as yours, or higher."); + return false; + } + if (!isConsole && (!permissionHandler.inGroup(senderUser.getName(), auxUser.getGroupName()) || !permissionHandler.inGroup(senderUser.getName(), auxGroup.getName()))) { + sender.sendMessage(ChatColor.RED + "Can't modify player involving a group that you don't inherit."); + return false; + } + if (!isConsole && (!permissionHandler.hasGroupInInheritance(auxUser.getGroup(), auxGroup.getName()) && !permissionHandler.hasGroupInInheritance(auxGroup, auxUser.getGroupName()))) { + sender.sendMessage(ChatColor.RED + "Can't modify player using groups with different heritage line."); + return false; + } + if (!isConsole && (!permissionHandler.hasGroupInInheritance(auxGroup, auxUser.getGroupName()))) { + sender.sendMessage(ChatColor.RED + "The new group must be a higher rank."); + return false; + } + //PARECE OK + auxUser.setGroup(auxGroup); + sender.sendMessage(ChatColor.YELLOW + "You changed " + auxUser.getName() + " group to " + auxGroup.getName() + "."); + + return true; + //break; + case mandemote: + //VALIDANDO ESTADO DO SENDER + if (dataHolder == null || permissionHandler == null) { + sender.sendMessage(ChatColor.RED + "Couldn't retrieve your world. World selection is needed."); + sender.sendMessage(ChatColor.RED + "Use /manselect "); + return true; + } + //VALIDANDO ARGUMENTOS + if (args.length != 2) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + if (validateOnlinePlayer) { + match = this.getServer().matchPlayer(args[0]); + if (match.size() != 1) { + sender.sendMessage(ChatColor.RED + "Player not found!"); + return false; + } + } + if (match != null) { + auxUser = dataHolder.getUser(match.get(0).getName()); + } else { + auxUser = dataHolder.getUser(args[0]); + } + auxGroup = dataHolder.getGroup(args[1]); + if (auxGroup == null) { + sender.sendMessage(ChatColor.RED + "Group not found!"); + return false; + } + //VALIDANDO PERMISSAO + if (!isConsole && (senderGroup != null ? permissionHandler.inGroup(auxUser.getName(), senderGroup.getName()) : false)) { + sender.sendMessage(ChatColor.RED + "Can't modify player with same permissions than you, or higher."); + return false; + } + if (!isConsole && (permissionHandler.hasGroupInInheritance(auxGroup, senderGroup.getName()))) { + sender.sendMessage(ChatColor.RED + "The destination group can't be the same as yours, or higher."); + return false; + } + if (!isConsole && (!permissionHandler.inGroup(senderUser.getName(), auxUser.getGroupName()) || !permissionHandler.inGroup(senderUser.getName(), auxGroup.getName()))) { + sender.sendMessage(ChatColor.RED + "Can't modify player involving a group that you don' inherit."); + return false; + } + if (!isConsole && (!permissionHandler.hasGroupInInheritance(auxUser.getGroup(), auxGroup.getName()) && !permissionHandler.hasGroupInInheritance(auxGroup, auxUser.getGroupName()))) { + sender.sendMessage(ChatColor.RED + "Can't modify player using groups with different heritage line."); + return false; + } + if (!isConsole && (permissionHandler.hasGroupInInheritance(auxGroup, auxUser.getGroupName()))) { + sender.sendMessage(ChatColor.RED + "The new group must be a lower rank."); + return false; + } + //PARECE OK + auxUser.setGroup(auxGroup); + sender.sendMessage(ChatColor.YELLOW + "You changed " + auxUser.getName() + " group to " + auxGroup.getName() + "."); + + return true; + //break; + case mantogglevalidate: + validateOnlinePlayer = !validateOnlinePlayer; + sender.sendMessage(ChatColor.YELLOW + "Validade if player is online, now set to: " + Boolean.toString(validateOnlinePlayer)); + if (!validateOnlinePlayer) { + sender.sendMessage(ChatColor.GOLD + "From now on you can edit players not connected... BUT:"); + sender.sendMessage(ChatColor.LIGHT_PURPLE + "From now on you should type the whole name of the player, correctly."); + } + return true; + case mantogglesave: + if (scheduler == null) { + enableScheduler(); + sender.sendMessage(ChatColor.YELLOW + "The auto-saving is enabled!"); + } else { + disableScheduler(); + sender.sendMessage(ChatColor.YELLOW + "The auto-saving is disabled!"); + } + return true; + case manworld: + auxString = selectedWorlds.get(sender); + if (auxString != null) { + sender.sendMessage(ChatColor.YELLOW + "You have the world '" + dataHolder.getName() + "' in your selection."); + } else { + if (dataHolder == null) { + sender.sendMessage(ChatColor.YELLOW + "There is no world selected. And no world is available now."); + } else { + sender.sendMessage(ChatColor.YELLOW + "You don't have a world in your selection.."); + sender.sendMessage(ChatColor.YELLOW + "Working with the direct world where your player is."); + sender.sendMessage(ChatColor.YELLOW + "Your world now uses permissions of world name: '" + dataHolder.getName() + "' "); + } + } + return true; + case manselect: + if (args.length < 1) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + sender.sendMessage(ChatColor.YELLOW + "Worlds available: "); + ArrayList worlds = worldsHolder.allWorldsDataList(); + auxString = ""; + for (int i = 0; i < worlds.size(); i++) { + auxString += worlds.get(i).getName(); + if ((i + 1) < worlds.size()) { + auxString += ", "; + } + } + sender.sendMessage(ChatColor.YELLOW + auxString); + return false; + } + auxString = ""; + for (int i = 0; i < args.length; i++) { + if (args[i] == null) { + logger.warning("Bukkit gave invalid arguments array! Cmd: " + cmd.getName() + " args.length: " + args.length); + return false; + } + auxString += args[i]; + if (i < (args.length - 1)) { + auxString += " "; + } + } + dataHolder = worldsHolder.getWorldData(auxString); + permissionHandler = dataHolder.getPermissionsHandler(); + selectedWorlds.put(sender, dataHolder.getName()); + sender.sendMessage(ChatColor.YELLOW + "You have selected world '" + dataHolder.getName() + "'."); + return true; + case manclear: + if (args.length != 0) { + sender.sendMessage(ChatColor.RED + "Review your arguments count!"); + return false; + } + selectedWorlds.remove(sender); + sender.sendMessage(ChatColor.YELLOW + "You have removed your world selection. Working with current world(if possible)."); + return true; + default: + break; + } + } + sender.sendMessage(ChatColor.RED + "You are not allowed to use that command."); + return false; + } + + /** + * @return the config + */ + public GMConfiguration getConfig() { + return config; + } + + /** + * @return the backupFolder + */ + public File getBackupFolder() { + return backupFolder; + } +} diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/DataUnit.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/DataUnit.java new file mode 100644 index 000000000..3eb7491dd --- /dev/null +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/DataUnit.java @@ -0,0 +1,114 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.anjocaido.groupmanager.data; + +import java.util.ArrayList; +import java.util.Collections; +import org.anjocaido.groupmanager.GroupManager; +import org.anjocaido.groupmanager.dataholder.WorldDataHolder; +import org.anjocaido.groupmanager.utils.StringPermissionComparator; + +/** + * + * @author gabrielcouto + */ +public abstract class DataUnit { + + private WorldDataHolder dataSource; + private String name; + private boolean changed; + private ArrayList permissions = new ArrayList(); + + public DataUnit(WorldDataHolder dataSource, String name) { + this.dataSource = dataSource; + this.name = name; + } + + /** + * Every group is matched only by their names and DataSources names. + * @param o + * @return true if they are equal. false if not. + */ + @Override + public boolean equals(Object o) { + if (o instanceof DataUnit) { + DataUnit go = (DataUnit) o; + if (this.getName().equalsIgnoreCase(go.getName()) && this.dataSource.getName().equalsIgnoreCase(go.getDataSource().getName())) { + return true; + } + } + return false; + } + + @Override + public int hashCode() { + int hash = 5; + hash = 71 * hash + (this.name != null ? this.name.toLowerCase().hashCode() : 0); + return hash; + } + + + + + /** + * @return the dataSource + */ + public WorldDataHolder getDataSource() { + return dataSource; + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + public void flagAsChanged() { + GroupManager.logger.finest("DataSource: "+getDataSource().getName()+" - DataUnit: "+getName()+" flagged as changed!"); +// for(StackTraceElement st: Thread.currentThread().getStackTrace()){ +// GroupManager.logger.finest(st.toString()); +// } + changed = true; + } + + public boolean isChanged() { + return changed; + } + + public void flagAsSaved() { + GroupManager.logger.finest("DataSource: "+getDataSource().getName()+" - DataUnit: "+getName()+" flagged as saved!"); + changed = false; + } + + public boolean hasSamePermissionNode(String permission) { + return permissions.contains(permission); + } + + public void addPermission(String permission) { + if (!hasSamePermissionNode(permission)) { + permissions.add(permission); + } + flagAsChanged(); + } + + public boolean removePermission(String permission) { + flagAsChanged(); + return permissions.remove(permission); + } + + /** + * Use this only to list permissions. + * You can't edit the permissions using the returned ArrayList instance + * @return a copy of the permission list + */ + public ArrayList getPermissionList() { + return (ArrayList) permissions.clone(); + } + + public void sortPermissions(){ + Collections.sort(permissions, StringPermissionComparator.getInstance()); + } +} diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/Group.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/Group.java new file mode 100644 index 000000000..c734b208e --- /dev/null +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/Group.java @@ -0,0 +1,122 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.anjocaido.groupmanager.data; + +import org.anjocaido.groupmanager.dataholder.WorldDataHolder; +import java.util.ArrayList; +import java.util.Map; + +/** + * + * @author gabrielcouto + */ +public class Group extends DataUnit implements Cloneable { + + /** + * The group it inherits DIRECTLY! + */ + private ArrayList inherits = new ArrayList(); + /** + *This one holds the fields in INFO node. + * like prefix = 'c' + * or build = false + */ + private GroupVariables variables = new GroupVariables(this); + + /** + * + * @param name + */ + public Group(WorldDataHolder source, String name) { + super(source,name); + } + + /** + * Clone this group + * @return a clone of this group + */ + @Override + public Group clone() { + Group clone = new Group(getDataSource(), this.getName()); + clone.inherits = ((ArrayList) this.getInherits().clone()); + for(String perm: this.getPermissionList()){ + clone.addPermission(perm); + } + clone.variables = ((GroupVariables) variables).clone(clone); + //clone.flagAsChanged(); + return clone; + } + + /** + * Use this to deliver a group from a different dataSource to another + * @param dataSource + * @return + */ + public Group clone(WorldDataHolder dataSource) { + if (dataSource.groupExists(this.getName())) { + return null; + } + Group clone = getDataSource().createGroup(this.getName()); + clone.inherits = ((ArrayList) this.getInherits().clone()); + for(String perm: this.getPermissionList()){ + clone.addPermission(perm); + } + clone.variables = variables.clone(clone); + clone.flagAsChanged(); //use this to make the new dataSource save the new group + return clone; + } + + /** + * a COPY of inherits list + * You can't manage the list by here + * Lol... version 0.6 had a problem because this. + * @return the inherits + */ + public ArrayList getInherits() { + return (ArrayList) inherits.clone(); + } + + /** + * @param inherits the inherits to set + */ + public void addInherits(Group inherit) { + if (!this.getDataSource().groupExists(inherit.getName())) { + getDataSource().addGroup(inherit); + } + if (!inherits.contains(inherit.getName().toLowerCase())) { + inherits.add(inherit.getName().toLowerCase()); + } + flagAsChanged(); + } + + public boolean removeInherits(String inherit) { + if (this.inherits.contains(inherit.toLowerCase())) { + this.inherits.remove(inherit.toLowerCase()); + flagAsChanged(); + return true; + } + return false; + } + + /** + * @return the variables + */ + public GroupVariables getVariables() { + return variables; + } + + /** + * + * @param varList + */ + public void setVariables(Map varList) { + GroupVariables temp = new GroupVariables(this, varList); + variables.clearVars(); + for(String key: temp.getVarKeyList()){ + variables.addVar(key, temp.getVarObject(key)); + } + flagAsChanged(); + } +} diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/GroupVariables.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/GroupVariables.java new file mode 100644 index 000000000..87c34de2b --- /dev/null +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/GroupVariables.java @@ -0,0 +1,87 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.anjocaido.groupmanager.data; + +import java.util.Map; + +/** + * + * @author gabrielcouto + */ +public class GroupVariables extends Variables implements Cloneable { + + private Group owner; + + public GroupVariables(Group owner) { + super(owner); + this.owner = owner; + addVar("prefix", ""); + addVar("suffix", ""); + addVar("build", false); + } + + public GroupVariables(Group owner, Map varList) { + super(owner); + variables = varList; + if (variables.get("prefix") == null) { + variables.put("prefix", ""); + owner.flagAsChanged(); + } + //thisGrp.prefix = infoNode.get("prefix").toString(); + + if (variables.get("suffix") == null) { + variables.put("suffix", ""); + owner.flagAsChanged(); + } + //thisGrp.suffix = infoNode.get("suffix").toString(); + + if (variables.get("build") == null) { + variables.put("build", false); + owner.flagAsChanged(); + } + this.owner = owner; + } + + /** + * A clone of all vars here. + * @return + */ + protected GroupVariables clone(Group newOwner) { + GroupVariables clone = new GroupVariables(newOwner); + for (String key : variables.keySet()) { + clone.variables.put(key, variables.get(key)); + } + newOwner.flagAsChanged(); + return clone; + } + + /** + * Remove a var from the list + * @param name + */ + @Override + public void removeVar(String name) { + try { + this.variables.remove(name); + } catch (Exception e) { + } + if (name.equals("prefix")) { + addVar("prefix", ""); + } else if (name.equals("suffix")) { + addVar("suffix", ""); + } else if (name.equals("build")) { + addVar("build", false); + } + owner.flagAsChanged(); + } + + /** + * @return the owner + */ + @Override + public Group getOwner() { + return owner; + } +} diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/User.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/User.java new file mode 100644 index 000000000..ceecbfa21 --- /dev/null +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/User.java @@ -0,0 +1,187 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.anjocaido.groupmanager.data; + +import com.sun.org.apache.bcel.internal.generic.AALOAD; +import java.util.ArrayList; +import org.anjocaido.groupmanager.dataholder.WorldDataHolder; +import java.util.Map; + +/** + * + * @author gabrielcouto + */ +public class User extends DataUnit implements Cloneable { + + /** + * + */ + private String group = null; + private ArrayList subGroups = new ArrayList(); + /** + *This one holds the fields in INFO node. + * like prefix = 'c' + * or build = false + */ + private UserVariables variables = new UserVariables(this); + + + /** + * + * @param name + */ + public User(WorldDataHolder source, String name) { + super(source,name); + this.group = source.getDefaultGroup().getName(); + } + + /** + * + * @return + */ + @Override + public User clone() { + User clone = new User(getDataSource(), this.getName()); + clone.group = this.group; + for(String perm: this.getPermissionList()){ + clone.addPermission(perm); + } + //clone.variables = this.variables.clone(); + //clone.flagAsChanged(); + return clone; + } + + /** + * Use this to deliver a user from one WorldDataHolder to another + * @param dataSource + * @return null if given dataSource already contains the same user + */ + public User clone(WorldDataHolder dataSource) { + if (dataSource.isUserDeclared(this.getName())) { + return null; + } + User clone = dataSource.createUser(this.getName()); + if (dataSource.getGroup(group) == null) { + clone.setGroup(dataSource.getDefaultGroup()); + } else { + clone.setGroup(this.getGroupName()); + } + for(String perm: this.getPermissionList()){ + clone.addPermission(perm); + } + //clone.variables = this.variables.clone(); + clone.flagAsChanged(); + return clone; + } + + public Group getGroup() { + Group result = getDataSource().getGroup(group); + if (result == null) { + this.setGroup(getDataSource().getDefaultGroup()); + result = getDataSource().getDefaultGroup(); + } + return result; + } + + /** + * @return the group + */ + public String getGroupName() { + Group result = getDataSource().getGroup(group); + if (result == null) { + group = getDataSource().getDefaultGroup().getName(); + } + return group; + } + + /** + * @param group the group to set + */ + @Deprecated + public void setGroup(String group) { + this.group = group; + flagAsChanged(); + } + + /** + * @param group the group to set + */ + public void setGroup(Group group) { + if (!this.getDataSource().groupExists(group.getName())) { + getDataSource().addGroup(group); + } + group = getDataSource().getGroup(group.getName()); + this.group = group.getName(); + flagAsChanged(); + } + + public void addSubGroup(Group subGroup){ + if(this.group.equalsIgnoreCase(subGroup.getName())){ + return; + } + if (!this.getDataSource().groupExists(subGroup.getName())) { + getDataSource().addGroup(subGroup); + } + subGroup = getDataSource().getGroup(subGroup.getName()); + removeSubGroup(subGroup); + subGroups.add(subGroup.getName()); + flagAsChanged(); + } + public int subGroupsSize(){ + return subGroups.size(); + } + public boolean isSubGroupsEmpty(){ + return subGroups.isEmpty(); + } + public boolean containsSubGroup(Group subGroup){ + return subGroups.contains(subGroup.getName()); + } + public boolean removeSubGroup(Group subGroup){ + try{ + if(subGroups.remove(subGroup.getName())){ + flagAsChanged(); + return true; + } + } catch (Exception e){ + + } + return false; + } + public ArrayList subGroupListCopy(){ + ArrayList val = new ArrayList(); + for(String gstr: subGroups){ + Group g = getDataSource().getGroup(gstr); + if(g==null){ + removeSubGroup(g); + continue; + } + val.add(g); + } + return val; + } + public ArrayList subGroupListStringCopy(){ + return (ArrayList) subGroups.clone(); + } + + /** + * @return the variables + */ + public UserVariables getVariables() { + return variables; + } + + /** + * + * @param varList + */ + public void setVariables(Map varList) { + UserVariables temp = new UserVariables(this, varList); + variables.clearVars(); + for(String key: temp.getVarKeyList()){ + variables.addVar(key, temp.getVarObject(key)); + } + flagAsChanged(); + } +} diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/UserVariables.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/UserVariables.java new file mode 100644 index 000000000..45dfc31e7 --- /dev/null +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/UserVariables.java @@ -0,0 +1,45 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package org.anjocaido.groupmanager.data; + +import java.util.Map; + +/** + * + * @author gabrielcouto + */ +public class UserVariables extends Variables{ + private User owner; + public UserVariables(User owner){ + super(owner); + this.owner = owner; + } + public UserVariables(User owner, Map varList) { + super(owner); + this.variables = varList; + this.owner = owner; + } + /** + * A clone of all vars here. + * @return + */ + protected UserVariables clone(User newOwner) { + UserVariables clone = new UserVariables(newOwner); + for (String key : variables.keySet()) { + clone.variables.put(key, variables.get(key)); + } + newOwner.flagAsChanged(); + return clone; + } + /** + * @return the owner + */ + @Override + public User getOwner() { + return owner; + } + +} diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/Variables.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/Variables.java new file mode 100644 index 000000000..31ed0d795 --- /dev/null +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/data/Variables.java @@ -0,0 +1,192 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.anjocaido.groupmanager.data; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + *A class that holds variables of a user/group. + * In groups, it holds the contents of INFO node. + * Like: + * prefix + * suffix + * build + * + * @author gabrielcouto + */ +public abstract class Variables implements Cloneable { + private DataUnit owner; + protected Map variables = new HashMap(); + + public Variables(DataUnit owner){ + this.owner = owner; + } + /** + * Add var to the the INFO node. + * examples: + * addVar("build",true); + * addVar("prefix","c"); + * @param name key name of the var + * @param o the object value of the var + */ + public void addVar(String name, Object o) { + if (o == null) { + return; + } + if (variables.containsKey(name)) { + variables.remove(name); + } + variables.put(name, o); + owner.flagAsChanged(); + } + + /** + * Returns the object inside the var + * @param name + * @return a Object if exists. null if doesn't exists + */ + public Object getVarObject(String name) { + return variables.get(name); + } + + /** + * Get the String value for the given var name + * @param name the var key name + * @return "" if null. or the toString() value of object + */ + public String getVarString(String name) { + Object o = variables.get(name); + try { + return o == null ? "" : o.toString(); + } catch (Exception e) { + return ""; + } + } + + /** + * + * @param name + * @return false if null. or a Boolean.parseBoolean of the string + */ + public Boolean getVarBoolean(String name) { + Object o = variables.get(name); + try { + return o == null ? false : Boolean.parseBoolean(o.toString()); + } catch (Exception e) { + return false; + } + } + + /** + * + * @param name + * @return -1 if null. or a parseInt of the string + */ + public Integer getVarInteger(String name) { + Object o = variables.get(name); + try { + return o == null ? -1 : Integer.parseInt(o.toString()); + } catch (Exception e) { + return -1; + } + } + + /** + * + * @param name + * @return -1 if null. or a parseDouble of the string + */ + public Double getVarDouble(String name) { + Object o = variables.get(name); + try { + return o == null ? -1.0D : Double.parseDouble(o.toString()); + } catch (Exception e) { + return -1.0D; + + + } + } + + /** + * All variable keys this is holding + * @return + */ + public Set getVarKeyList() { + return variables.keySet(); + + + } + + /** + * verify is a var exists + * @param name the key name of the var + * @return true if that var exists + */ + public boolean hasVar(String name) { + return variables.containsKey(name); + + + } + + /** + * Returns the quantity of vars this is holding + * @return the number of vars + */ + public int getSize() { + return variables.size(); + + + } + + /** + * Remove a var from the list + * @param name + */ + public void removeVar(String name) { + try { + variables.remove(name); + } catch (Exception e) { + } + owner.flagAsChanged(); + } + + public static Object parseVariableValue(String value) { + try { + Integer i = Integer.parseInt(value); + return i; + } catch (NumberFormatException e) { + } + try { + Double d = Double.parseDouble(value); + return d; + } catch (NumberFormatException e) { + } + if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes") || value.equalsIgnoreCase("on")) { + return true; + } else if (value.equalsIgnoreCase("false") || value.equalsIgnoreCase("no") || value.equalsIgnoreCase("off")) { + return false; + } + return value; + + } + + public void clearVars(){ + variables.clear(); + owner.flagAsChanged(); + } + + /** + * @return the owner + */ + public DataUnit getOwner() { + return owner; + } + + public boolean isEmpty(){ + return variables.isEmpty(); + } +} diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/OverloadedWorldHolder.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/OverloadedWorldHolder.java new file mode 100644 index 000000000..f735ff5e6 --- /dev/null +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/OverloadedWorldHolder.java @@ -0,0 +1,204 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.anjocaido.groupmanager.dataholder; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import org.anjocaido.groupmanager.data.User; + +/** + * + * @author gabrielcouto + */ +public class OverloadedWorldHolder extends WorldDataHolder { + + /** + * + */ + protected Map overloadedUsers = new HashMap(); + + /** + * + * @param ph + */ + public OverloadedWorldHolder(WorldDataHolder ph) { + super(ph.getName()); + this.f = ph.f; + this.groupsFile = ph.groupsFile; + this.usersFile = ph.usersFile; + this.defaultGroup = ph.defaultGroup; + this.groups = ph.groups; + this.users = ph.users; + } + + /** + * + * @param userName + * @return + */ + @Override + public User getUser(String userName) { + //OVERLOADED CODE + if (overloadedUsers.containsKey(userName.toLowerCase())) { + return overloadedUsers.get(userName.toLowerCase()); + } + //END CODE + if (users.containsKey(userName.toLowerCase())) { + return users.get(userName.toLowerCase()); + } + User newUser = createUser(userName); + haveUsersChanged = true; + return newUser; + } + + /** + * + * @param theUser + */ + @Override + public void addUser(User theUser) { + if (theUser.getDataSource() != this) { + theUser = theUser.clone(this); + } + if (theUser == null) { + return; + } + if ((theUser.getGroup() == null) || (!groups.containsKey(theUser.getGroupName().toLowerCase()))) { + theUser.setGroup(defaultGroup); + } + //OVERLOADED CODE + if (overloadedUsers.containsKey(theUser.getName().toLowerCase())) { + overloadedUsers.remove(theUser.getName().toLowerCase()); + overloadedUsers.put(theUser.getName().toLowerCase(), theUser); + return; + } + //END CODE + removeUser(theUser.getName()); + users.put(theUser.getName().toLowerCase(), theUser); + haveUsersChanged = true; + } + + /** + * + * @param userName + * @return + */ + @Override + public boolean removeUser(String userName) { + //OVERLOADED CODE + if (overloadedUsers.containsKey(userName.toLowerCase())) { + overloadedUsers.remove(userName.toLowerCase()); + return true; + } + //END CODE + if (users.containsKey(userName.toLowerCase())) { + users.remove(userName.toLowerCase()); + haveUsersChanged = true; + return true; + } + return false; + } + + @Override + public boolean removeGroup(String groupName) { + if (groupName.equals(defaultGroup)) { + return false; + } + for (String key : groups.keySet()) { + if (groupName.equalsIgnoreCase(key)) { + groups.remove(key); + for (String userKey : users.keySet()) { + User user = users.get(userKey); + if (user.getGroupName().equalsIgnoreCase(key)) { + user.setGroup(defaultGroup); + } + + } + //OVERLOADED CODE + for (String userKey : overloadedUsers.keySet()) { + User user = overloadedUsers.get(userKey); + if (user.getGroupName().equalsIgnoreCase(key)) { + user.setGroup(defaultGroup); + } + + } + //END OVERLOAD + haveGroupsChanged = true; + return true; + } + } + return false; + } + + /** + * + * @return + */ + @Override + public Collection getUserList() { + Collection overloadedList = new ArrayList(); + Collection normalList = users.values(); + for (User u : normalList) { + if (overloadedUsers.containsKey(u.getName().toLowerCase())) { + overloadedList.add(overloadedUsers.get(u.getName().toLowerCase())); + } else { + overloadedList.add(u); + } + } + return overloadedList; + } + + /** + * + * @param userName + * @return + */ + public boolean isOverloaded(String userName) { + return overloadedUsers.containsKey(userName.toLowerCase()); + } + + /** + * + * @param userName + */ + public void overloadUser(String userName) { + if (!isOverloaded(userName)) { + User theUser = getUser(userName); + theUser = theUser.clone(); + if (overloadedUsers.containsKey(theUser.getName().toLowerCase())) { + overloadedUsers.remove(theUser.getName().toLowerCase()); + } + overloadedUsers.put(theUser.getName().toLowerCase(), theUser); + } + } + + /** + * + * @param userName + */ + public void removeOverload(String userName) { + overloadedUsers.remove(userName.toLowerCase()); + } + + /** + * Gets the user in normal state. Surpassing the overload state. + * It doesn't affect permissions. But it enables plugins change the + * actual user permissions even in overload mode. + * @param userName + * @return + */ + public User surpassOverload(String userName) { + if (!isOverloaded(userName)) { + return getUser(userName); + } + if (users.containsKey(userName.toLowerCase())) { + return users.get(userName.toLowerCase()); + } + User newUser = createUser(userName); + return newUser; + } +} diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/WorldDataHolder.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/WorldDataHolder.java new file mode 100644 index 000000000..96e517abd --- /dev/null +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/WorldDataHolder.java @@ -0,0 +1,939 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.anjocaido.groupmanager.dataholder; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.anjocaido.groupmanager.GroupManager; +import org.anjocaido.groupmanager.data.Group; +import org.anjocaido.groupmanager.data.User; +import org.anjocaido.groupmanager.permissions.AnjoPermissionsHandler; +import org.bukkit.Server; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginManager; +import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.SafeConstructor; +import org.yaml.snakeyaml.reader.UnicodeReader; + +/** + * + * @author gabrielcouto + */ +public class WorldDataHolder { + + /** + * + */ + protected String name; + /** + * The actual groups holder + */ + protected Map groups = new HashMap(); + /** + * The actual users holder + */ + protected Map users = new HashMap(); + /** + * Points to the default group + */ + protected Group defaultGroup = null; + /** + * The file, which this class loads/save data from/to + * @deprecated + */ + @Deprecated + protected File f; + /** + * + */ + protected AnjoPermissionsHandler permissionsHandler; + /** + * + */ + protected File usersFile; + /** + * + */ + protected File groupsFile; + /** + * + */ + protected boolean haveUsersChanged = false; + /** + * + */ + protected boolean haveGroupsChanged = false; + + /** + * Prevent direct instantiation + * @param worldName + */ + protected WorldDataHolder(String worldName) { + name = worldName; + } + + /** + * The main constructor for a new WorldDataHolder + * Please don't set the default group as null + * @param worldName + * @param defaultGroup the default group. its good to start with one + */ + public WorldDataHolder(String worldName, Group defaultGroup) { + this.name = worldName; + groups.put(defaultGroup.getName().toLowerCase(), defaultGroup); + this.defaultGroup = defaultGroup; + } + + /** + * Search for a user. If it doesn't exist, create a new one with + * default group. + * + * @param userName the name of the user + * @return class that manage that user permission + */ + public User getUser(String userName) { + if (users.containsKey(userName.toLowerCase())) { + return users.get(userName.toLowerCase()); + } + User newUser = createUser(userName); + return newUser; + } + + /** + * Add a user to the list. If it already exists, overwrite the old. + * @param theUser the user you want to add to the permission list + */ + public void addUser(User theUser) { + if (theUser.getDataSource() != this) { + theUser = theUser.clone(this); + } + if (theUser == null) { + return; + } + if ((theUser.getGroup() == null)) { + theUser.setGroup(defaultGroup); + } + removeUser(theUser.getName()); + users.put(theUser.getName().toLowerCase(), theUser); + haveUsersChanged = true; + } + + /** + * Removes the user from the list. (he might become a default user) + * @param userName the username from the user to remove + * @return true if it had something to remove + */ + public boolean removeUser(String userName) { + if (users.containsKey(userName.toLowerCase())) { + users.remove(userName.toLowerCase()); + haveUsersChanged = true; + return true; + } + return false; + } + + /** + * + * @param userName + * @return + */ + public boolean isUserDeclared(String userName) { + return users.containsKey(userName.toLowerCase()); + } + + /** + * Change the default group of the file. + * @param group the group you want make default. + */ + public void setDefaultGroup(Group group) { + if (!groups.containsKey(group.getName().toLowerCase()) || (group.getDataSource() != this)) { + addGroup(group); + } + defaultGroup = this.getGroup(group.getName()); + haveGroupsChanged = true; + } + + /** + * Returns the default group of the file + * @return the default group + */ + public Group getDefaultGroup() { + return defaultGroup; + } + + /** + * Returns a group of the given name + * @param groupName the name of the group + * @return a group if it is found. null if not found. + */ + public Group getGroup(String groupName) { + return groups.get(groupName.toLowerCase()); + } + + /** + * Check if a group exists. + * Its the same of getGroup, but check if it is null. + * @param groupName the name of the group + * @return true if exists. false if not. + */ + public boolean groupExists(String groupName) { + return groups.containsKey(groupName.toLowerCase()); + } + + /** + * Add a group to the list + * @param groupToAdd + */ + public void addGroup(Group groupToAdd) { + if (groupToAdd.getDataSource() != this) { + groupToAdd = groupToAdd.clone(this); + } + removeGroup(groupToAdd.getName()); + groups.put(groupToAdd.getName().toLowerCase(), groupToAdd); + haveGroupsChanged = true; + } + + /** + * Remove the group to the list + * @param groupName + * @return true if had something to remove. false the group was default or non-existant + */ + public boolean removeGroup(String groupName) { + if (defaultGroup != null && groupName.equalsIgnoreCase(defaultGroup.getName())) { + return false; + } + if (groups.containsKey(groupName.toLowerCase())) { + groups.remove(groupName.toLowerCase()); + haveGroupsChanged = true; + return true; + } + return false; + + } + + /** + * Creates a new User with the given name + * and adds it to this holder. + * @param userName the username you want + * @return null if user already exists. or new User + */ + public User createUser(String userName) { + if (this.users.containsKey(userName.toLowerCase())) { + return null; + } + User newUser = new User(this, userName); + newUser.setGroup(defaultGroup); + this.addUser(newUser); + haveUsersChanged = true; + return newUser; + } + + /** + * Creates a new Group with the given name + * and adds it to this holder + * @param groupName the groupname you want + * @return null if group already exists. or new Group + */ + public Group createGroup(String groupName) { + if (this.groups.containsKey(groupName.toLowerCase())) { + return null; + } + Group newGroup = new Group(this, groupName); + this.addGroup(newGroup); + haveGroupsChanged = true; + return newGroup; + } + + /** + * + * @return a collection of the groups + */ + public Collection getGroupList() { + return groups.values(); + } + + /** + * + * @return a collection of the users + */ + public Collection getUserList() { + return users.values(); + } + + /** + * reads the file again + */ + public void reload() { + try { + WorldDataHolder ph = load(this.getName(), getGroupsFile(), getUsersFile()); + this.defaultGroup = ph.defaultGroup; + this.groups = ph.groups; + this.users = ph.users; + } catch (Exception ex) { + Logger.getLogger(WorldDataHolder.class.getName()).log(Level.SEVERE, null, ex); + } + } + + /** + * Save by yourself! + * @deprecated + */ + @Deprecated + public void commit() { + writeGroups(this, getGroupsFile()); + writeUsers(this, getUsersFile()); + } + + /** + * Returns a data holder for the given file + * @param worldName + * @param file + * @return + * @throws Exception + * @deprecated + */ + @Deprecated + public static WorldDataHolder load(String worldName, File file) throws Exception { + WorldDataHolder ph = new WorldDataHolder(worldName); + ph.f = file; + final Yaml yaml = new Yaml(new SafeConstructor()); + Map rootDataNode; + if (!file.exists()) { + throw new Exception("The file which should contain permissions does not exist!\n" + file.getPath()); + } + FileInputStream rx = new FileInputStream(file); + try { + rootDataNode = (Map) yaml.load(new UnicodeReader(rx)); + if (rootDataNode == null) { + throw new NullPointerException(); + } + } catch (Exception ex) { + throw new Exception("The following file couldn't pass on Parser.\n" + file.getPath(), ex); + } finally { + rx.close(); + } + Map> inheritance = new HashMap>(); + try { + Map allGroupsNode = (Map) rootDataNode.get("groups"); + for (String groupKey : allGroupsNode.keySet()) { + Map thisGroupNode = (Map) allGroupsNode.get(groupKey); + Group thisGrp = ph.createGroup(groupKey); + if (thisGrp == null) { + throw new IllegalArgumentException("I think this user was declared more than once: " + groupKey); + } + if (thisGroupNode.get("default") == null) { + thisGroupNode.put("default", false); + } + if ((Boolean.parseBoolean(thisGroupNode.get("default").toString()))) { + if (ph.getDefaultGroup() != null) { + GroupManager.logger.warning("The group " + thisGrp.getName() + " is declaring be default where" + ph.getDefaultGroup().getName() + " already was."); + GroupManager.logger.warning("Overriding first request."); + } + ph.setDefaultGroup(thisGrp); + } + + //PERMISSIONS NODE + if (thisGroupNode.get("permissions") == null) { + thisGroupNode.put("permissions", new ArrayList()); + } + if (thisGroupNode.get("permissions") instanceof List) { + for (Object o : ((List) thisGroupNode.get("permissions"))) { + thisGrp.addPermission(o.toString()); + } + } else if (thisGroupNode.get("permissions") instanceof String) { + thisGrp.addPermission((String) thisGroupNode.get("permissions")); + } else { + throw new IllegalArgumentException("Unknown type of permissions node(Should be String or List): " + thisGroupNode.get("permissions").getClass().getName()); + } + + //INFO NODE + Map infoNode = (Map) thisGroupNode.get("info"); + if (infoNode != null) { + thisGrp.setVariables(infoNode); + } + + //END INFO NODE + + Object inheritNode = thisGroupNode.get("inheritance"); + if (inheritNode == null) { + thisGroupNode.put("inheritance", new ArrayList()); + } else if (inheritNode instanceof List) { + List groupsInh = (List) inheritNode; + for (String grp : groupsInh) { + if (inheritance.get(groupKey) == null) { + List thisInherits = new ArrayList(); + inheritance.put(groupKey, thisInherits); + } + inheritance.get(groupKey).add(grp); + + } + } + } + } catch (Exception ex) { + ex.printStackTrace(); + throw new Exception("Your Permissions config file is invalid. See console for details."); + } + if (ph.defaultGroup == null) { + throw new IllegalArgumentException("There was no Default Group declared."); + } + for (String groupKey : inheritance.keySet()) { + List inheritedList = inheritance.get(groupKey); + Group thisGroup = ph.getGroup(groupKey); + for (String inheritedKey : inheritedList) { + Group inheritedGroup = ph.getGroup(inheritedKey); + if (thisGroup != null && inheritedGroup != null) { + thisGroup.addInherits(inheritedGroup); + } + } + } + // Process USERS + Map allUsersNode = (Map) rootDataNode.get("users"); + for (String usersKey : allUsersNode.keySet()) { + Map thisUserNode = (Map) allUsersNode.get(usersKey); + User thisUser = ph.createUser(usersKey); + if (thisUser == null) { + throw new IllegalArgumentException("I think this user was declared more than once: " + usersKey); + } + if (thisUserNode.get("permissions") == null) { + thisUserNode.put("permissions", new ArrayList()); + } + if (thisUserNode.get("permissions") instanceof List) { + for (Object o : ((List) thisUserNode.get("permissions"))) { + thisUser.addPermission(o.toString()); + } + } else if (thisUserNode.get("permissions") instanceof String) { + thisUser.addPermission(thisUserNode.get("permissions").toString()); + } + + + //USER INFO NODE - BETA + + //INFO NODE + Map infoNode = (Map) thisUserNode.get("info"); + if (infoNode != null) { + thisUser.setVariables(infoNode); + } + //END INFO NODE - BETA + + if (thisUserNode.get("group") != null) { + Group hisGroup = ph.getGroup(thisUserNode.get("group").toString()); + if (hisGroup == null) { + throw new IllegalArgumentException("There is no group " + thisUserNode.get("group").toString() + ", as stated for player " + thisUser.getName()); + } + thisUser.setGroup(hisGroup); + } else { + thisUser.setGroup(ph.defaultGroup); + } + } + return ph; + } + + /** + * Returns a data holder for the given file + * @param worldName + * @param groupsFile + * @param usersFile + * @return + * @throws FileNotFoundException + * @throws IOException + */ + public static WorldDataHolder load(String worldName, File groupsFile, File usersFile) throws FileNotFoundException, IOException { + WorldDataHolder ph = new WorldDataHolder(worldName); + ph.groupsFile = groupsFile; + ph.usersFile = usersFile; + + + //READ GROUPS FILE + Yaml yamlGroups = new Yaml(new SafeConstructor()); + Map groupsRootDataNode; + if (!groupsFile.exists()) { + throw new IllegalArgumentException("The file which should contain permissions does not exist!\n" + groupsFile.getPath()); + } + FileInputStream groupsInputStream = new FileInputStream(groupsFile); + try { + groupsRootDataNode = (Map) yamlGroups.load(new UnicodeReader(groupsInputStream)); + if (groupsRootDataNode == null) { + throw new NullPointerException(); + } + } catch (Exception ex) { + throw new IllegalArgumentException("The following file couldn't pass on Parser.\n" + groupsFile.getPath(), ex); + } finally { + groupsInputStream.close(); + } + + //PROCESS GROUPS FILE + Map> inheritance = new HashMap>(); + try { + Map allGroupsNode = (Map) groupsRootDataNode.get("groups"); + for (String groupKey : allGroupsNode.keySet()) { + Map thisGroupNode = (Map) allGroupsNode.get(groupKey); + Group thisGrp = ph.createGroup(groupKey); + if (thisGrp == null) { + throw new IllegalArgumentException("I think this user was declared more than once: " + groupKey); + } + if (thisGroupNode.get("default") == null) { + thisGroupNode.put("default", false); + } + if ((Boolean.parseBoolean(thisGroupNode.get("default").toString()))) { + if (ph.getDefaultGroup() != null) { + GroupManager.logger.warning("The group " + thisGrp.getName() + " is declaring be default where" + ph.getDefaultGroup().getName() + " already was."); + GroupManager.logger.warning("Overriding first request."); + } + ph.setDefaultGroup(thisGrp); + } + + //PERMISSIONS NODE + if (thisGroupNode.get("permissions") == null) { + thisGroupNode.put("permissions", new ArrayList()); + } + if (thisGroupNode.get("permissions") instanceof List) { + for (Object o : ((List) thisGroupNode.get("permissions"))) { + thisGrp.addPermission(o.toString()); + } + } else if (thisGroupNode.get("permissions") instanceof String) { + thisGrp.addPermission((String) thisGroupNode.get("permissions")); + } else { + throw new IllegalArgumentException("Unknown type of permissions node(Should be String or List): " + thisGroupNode.get("permissions").getClass().getName()); + } + + //INFO NODE + Map infoNode = (Map) thisGroupNode.get("info"); + if (infoNode != null) { + thisGrp.setVariables(infoNode); + } + + //END INFO NODE + + Object inheritNode = thisGroupNode.get("inheritance"); + if (inheritNode == null) { + thisGroupNode.put("inheritance", new ArrayList()); + } else if (inheritNode instanceof List) { + List groupsInh = (List) inheritNode; + for (String grp : groupsInh) { + if (inheritance.get(groupKey) == null) { + List thisInherits = new ArrayList(); + inheritance.put(groupKey, thisInherits); + } + inheritance.get(groupKey).add(grp); + + } + } + } + } catch (Exception ex) { + ex.printStackTrace(); + throw new IllegalArgumentException("Your Permissions config file is invalid. See console for details."); + } + if (ph.defaultGroup == null) { + throw new IllegalArgumentException("There was no Default Group declared."); + } + for (String groupKey : inheritance.keySet()) { + List inheritedList = inheritance.get(groupKey); + Group thisGroup = ph.getGroup(groupKey); + for (String inheritedKey : inheritedList) { + Group inheritedGroup = ph.getGroup(inheritedKey); + if (thisGroup != null && inheritedGroup != null) { + thisGroup.addInherits(inheritedGroup); + } + } + } + + + //READ USERS FILE + Yaml yamlUsers = new Yaml(new SafeConstructor()); + Map usersRootDataNode; + if (!groupsFile.exists()) { + throw new IllegalArgumentException("The file which should contain permissions does not exist!\n" + groupsFile.getPath()); + } + FileInputStream usersInputStream = new FileInputStream(usersFile); + try { + usersRootDataNode = (Map) yamlUsers.load(new UnicodeReader(usersInputStream)); + if (usersRootDataNode == null) { + throw new NullPointerException(); + } + } catch (Exception ex) { + throw new IllegalArgumentException("The following file couldn't pass on Parser.\n" + groupsFile.getPath(), ex); + } finally { + usersInputStream.close(); + } + + // PROCESS USERS FILE + Map allUsersNode = (Map) usersRootDataNode.get("users"); + for (String usersKey : allUsersNode.keySet()) { + Map thisUserNode = (Map) allUsersNode.get(usersKey); + User thisUser = ph.createUser(usersKey); + if (thisUser == null) { + throw new IllegalArgumentException("I think this user was declared more than once: " + usersKey); + } + if (thisUserNode.get("permissions") == null) { + thisUserNode.put("permissions", new ArrayList()); + } + if (thisUserNode.get("permissions") instanceof List) { + for (Object o : ((List) thisUserNode.get("permissions"))) { + thisUser.addPermission(o.toString()); + } + } else if (thisUserNode.get("permissions") instanceof String) { + thisUser.addPermission(thisUserNode.get("permissions").toString()); + } + + //SUBGROUPS LOADING + if (thisUserNode.get("subgroups") == null) { + thisUserNode.put("subgroups", new ArrayList()); + } + if (thisUserNode.get("subgroups") instanceof List) { + for (Object o : ((List) thisUserNode.get("subgroups"))) { + Group subGrp = ph.getGroup(o.toString()); + if (subGrp != null) { + thisUser.addSubGroup(subGrp); + } else { + GroupManager.logger.warning("Subgroup " + o.toString() + " not found for user " + thisUser.getName() + ". Ignoring entry."); + } + } + } else if (thisUserNode.get("subgroups") instanceof String) { + Group subGrp = ph.getGroup(thisUserNode.get("subgroups").toString()); + if (subGrp != null) { + thisUser.addSubGroup(subGrp); + } else { + GroupManager.logger.warning("Subgroup " + thisUserNode.get("subgroups").toString() + " not found for user " + thisUser.getName() + ". Ignoring entry."); + } + } + + + //USER INFO NODE - BETA + + //INFO NODE + Map infoNode = (Map) thisUserNode.get("info"); + if (infoNode != null) { + thisUser.setVariables(infoNode); + } + //END INFO NODE - BETA + + if (thisUserNode.get("group") != null) { + Group hisGroup = ph.getGroup(thisUserNode.get("group").toString()); + if (hisGroup == null) { + throw new IllegalArgumentException("There is no group " + thisUserNode.get("group").toString() + ", as stated for player " + thisUser.getName()); + } + thisUser.setGroup(hisGroup); + } else { + thisUser.setGroup(ph.defaultGroup); + } + } + return ph; + } + + /** + * Write a dataHolder in a specified file + * @param ph + * @param file + * @deprecated + */ + @Deprecated + public static void write(WorldDataHolder ph, File file) { + Map root = new HashMap(); + + Map pluginMap = new HashMap(); + root.put("plugin", pluginMap); + + Map permissionsMap = new HashMap(); + pluginMap.put("permissions", permissionsMap); + + permissionsMap.put("system", "default"); + + Map groupsMap = new HashMap(); + root.put("groups", groupsMap); + for (String groupKey : ph.groups.keySet()) { + Group group = ph.groups.get(groupKey); + + Map aGroupMap = new HashMap(); + groupsMap.put(group.getName(), aGroupMap); + + aGroupMap.put("default", group.equals(ph.defaultGroup)); + + Map infoMap = new HashMap(); + aGroupMap.put("info", infoMap); + + for (String infoKey : group.getVariables().getVarKeyList()) { + infoMap.put(infoKey, group.getVariables().getVarObject(infoKey)); + } + + aGroupMap.put("inheritance", group.getInherits()); + + aGroupMap.put("permissions", group.getPermissionList()); + } + + Map usersMap = new HashMap(); + root.put("users", usersMap); + for (String userKey : ph.users.keySet()) { + User user = ph.users.get(userKey); + if ((user.getGroup() == null || user.getGroup().equals(ph.defaultGroup)) && user.getPermissionList().isEmpty()) { + continue; + } + + Map aUserMap = new HashMap(); + usersMap.put(user.getName(), aUserMap); + + if (user.getGroup() == null) { + aUserMap.put("group", ph.defaultGroup.getName()); + } else { + aUserMap.put("group", user.getGroup().getName()); + } + //USER INFO NODE - BETA + if (user.getVariables().getSize() > 0) { + Map infoMap = new HashMap(); + aUserMap.put("info", infoMap); + + for (String infoKey : user.getVariables().getVarKeyList()) { + infoMap.put(infoKey, user.getVariables().getVarObject(infoKey)); + } + } + //END USER INFO NODE - BETA + + aUserMap.put("permissions", user.getPermissionList()); + } + DumperOptions opt = new DumperOptions(); + opt.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + final Yaml yaml = new Yaml(opt); + + FileWriter tx = null; + try { + tx = new FileWriter(file, false); + tx.write(yaml.dump(root)); + tx.flush(); + } catch (Exception e) { + } finally { + try { + tx.close(); + } catch (IOException ex) { + } + } + } + + /** + * Write a dataHolder in a specified file + * @param ph + * @param groupsFile + */ + public static void writeGroups(WorldDataHolder ph, File groupsFile) { + Map root = new HashMap(); + + Map groupsMap = new HashMap(); + root.put("groups", groupsMap); + for (String groupKey : ph.groups.keySet()) { + Group group = ph.groups.get(groupKey); + + Map aGroupMap = new HashMap(); + groupsMap.put(group.getName(), aGroupMap); + + if (ph.defaultGroup == null) { + GroupManager.logger.severe("There is no default group for world: " + ph.getName()); + } + aGroupMap.put("default", group.equals(ph.defaultGroup)); + + Map infoMap = new HashMap(); + aGroupMap.put("info", infoMap); + + for (String infoKey : group.getVariables().getVarKeyList()) { + infoMap.put(infoKey, group.getVariables().getVarObject(infoKey)); + } + + aGroupMap.put("inheritance", group.getInherits()); + + aGroupMap.put("permissions", group.getPermissionList()); + } + + DumperOptions opt = new DumperOptions(); + opt.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + final Yaml yaml = new Yaml(opt); + + FileWriter tx = null; + try { + tx = new FileWriter(groupsFile, false); + tx.write(yaml.dump(root)); + tx.flush(); + } catch (Exception e) { + } finally { + try { + tx.close(); + } catch (IOException ex) { + } + } + } + + /** + * Write a dataHolder in a specified file + * @param ph + * @param usersFile + */ + public static void writeUsers(WorldDataHolder ph, File usersFile) { + Map root = new HashMap(); + + Map usersMap = new HashMap(); + root.put("users", usersMap); + for (String userKey : ph.users.keySet()) { + User user = ph.users.get(userKey); + if ((user.getGroup() == null || user.getGroup().equals(ph.defaultGroup)) && user.getPermissionList().isEmpty() && user.getVariables().isEmpty() && user.isSubGroupsEmpty()) { + continue; + } + + Map aUserMap = new HashMap(); + usersMap.put(user.getName(), aUserMap); + + if (user.getGroup() == null) { + aUserMap.put("group", ph.defaultGroup.getName()); + } else { + aUserMap.put("group", user.getGroup().getName()); + } + //USER INFO NODE - BETA + if (user.getVariables().getSize() > 0) { + Map infoMap = new HashMap(); + aUserMap.put("info", infoMap); + for (String infoKey : user.getVariables().getVarKeyList()) { + infoMap.put(infoKey, user.getVariables().getVarObject(infoKey)); + } + } + //END USER INFO NODE - BETA + aUserMap.put("permissions", user.getPermissionList()); + + //SUBGROUPS NODE - BETA + aUserMap.put("subgroups", user.subGroupListStringCopy()); + //END SUBGROUPS NODE - BETA + } + DumperOptions opt = new DumperOptions(); + opt.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + final Yaml yaml = new Yaml(opt); + + FileWriter tx = null; + try { + tx = new FileWriter(usersFile, false); + tx.write(yaml.dump(root)); + tx.flush(); + } catch (Exception e) { + } finally { + try { + tx.close(); + } catch (IOException ex) { + } + } + } + + /** + * Don't use this. Unless you want to make this plugin to interact with original Nijikokun Permissions + * This method is supposed to make the original one reload the file, and propagate the changes made here. + * + * Prefer to use the AnjoCaido's fake version of Nijikokun's Permission plugin. + * The AnjoCaido's Permission can propagate the changes made on this plugin instantly, + * without need to save the file. + * + * @param server the server that holds the plugin + * @deprecated it is not used anymore... unless if you use original Permissions + */ + @Deprecated + public static void reloadOldPlugins(Server server) { + // Only reload permissions + PluginManager pm = server.getPluginManager(); + Plugin[] plugins = pm.getPlugins(); + for (int i = 0; i < plugins.length; i++) { + plugins[i].getConfiguration().load(); + try { + plugins[i].getClass().getMethod("setupPermissions").invoke(plugins[i]); + } catch (Exception ex) { + continue; + } + } + } + + /** + * @return the permissionsHandler + */ + public AnjoPermissionsHandler getPermissionsHandler() { + if (permissionsHandler == null) { + permissionsHandler = new AnjoPermissionsHandler(this); + } + return permissionsHandler; + } + + /** + * + * @return + */ + public boolean haveUsersChanged() { + if (haveUsersChanged) { + return true; + } + for (User u : users.values()) { + if (u.isChanged()) { + return true; + } + } + return false; + } + + /** + * + * @return + */ + public boolean haveGroupsChanged() { + if (haveGroupsChanged) { + return true; + } + for (Group g : groups.values()) { + if (g.isChanged()) { + return true; + } + } + return false; + } + + /** + * + */ + public void removeUsersChangedFlag() { + haveUsersChanged = false; + for (User u : users.values()) { + u.flagAsSaved(); + } + } + + /** + * + */ + public void removeGroupsChangedFlag() { + haveGroupsChanged = false; + for (Group g : groups.values()) { + g.flagAsSaved(); + } + } + + /** + * @return the usersFile + */ + public File getUsersFile() { + return usersFile; + } + + /** + * @return the groupsFile + */ + public File getGroupsFile() { + return groupsFile; + } + + /** + * @return the name + */ + public String getName() { + return name; + } +} diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/worlds/WorldsHolder.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/worlds/WorldsHolder.java new file mode 100644 index 000000000..83073c10b --- /dev/null +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/worlds/WorldsHolder.java @@ -0,0 +1,423 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.anjocaido.groupmanager.dataholder.worlds; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.anjocaido.groupmanager.GroupManager; +import org.anjocaido.groupmanager.dataholder.WorldDataHolder; +import org.anjocaido.groupmanager.dataholder.OverloadedWorldHolder; +import org.anjocaido.groupmanager.permissions.AnjoPermissionsHandler; +import org.anjocaido.groupmanager.utils.Tasks; +import org.bukkit.entity.Player; + +/** + * + * @author gabrielcouto + */ +public class WorldsHolder { + + /** + * Map with instances of loaded worlds. + */ + private Map worldsData = new HashMap(); + /** + * Map of mirrors: + * The key is the mirror. + * The object is the mirrored. + * + * Mirror shows the same data of mirrored. + */ + private Map mirrors = new HashMap(); + private OverloadedWorldHolder defaultWorld; + private String serverDefaultWorldName; + private GroupManager plugin; + private File worldsFolder; + + /** + * + * @param plugin + */ + public WorldsHolder(GroupManager plugin) { + this.plugin = plugin; + verifyFirstRun(); + initialLoad(); + if (defaultWorld == null) { + throw new IllegalStateException("There is no default group! OMG!"); + } + } + + private void initialLoad() { + initialWorldLoading(); + mirrorSetUp(); + } + private void initialWorldLoading(){ + //LOAD EVERY WORLD POSSIBLE + loadWorld(serverDefaultWorldName); + defaultWorld = worldsData.get(serverDefaultWorldName); + + for (File folder : worldsFolder.listFiles()) { + if (folder.getName().equalsIgnoreCase(serverDefaultWorldName)) { + continue; + } + if (folder.isDirectory()) { + loadWorld(folder.getName()); + } + } + } + public void mirrorSetUp(){ + mirrors.clear(); + Map mirrorsMap = plugin.getConfig().getMirrorsMap(); + if (mirrorsMap != null) { + for (String source : mirrorsMap.keySet()) { + if (mirrorsMap.get(source) instanceof ArrayList) { + ArrayList mirrorList = (ArrayList) mirrorsMap.get(source); + for (Object o : mirrorList) { + try { + mirrors.remove(o.toString().toLowerCase()); + } catch (Exception e) { + } + mirrors.put(o.toString().toLowerCase(), getWorldData(source).getName()); + } + } else if (mirrorsMap.get(source) instanceof Object) { + String aMirror = mirrorsMap.get(source).toString(); + mirrors.put(aMirror.toLowerCase(), getWorldData(source).getName()); + } + } + } + } + + /** + * + */ + public void reloadAll() { + ArrayList alreadyDone = new ArrayList(); + for (WorldDataHolder w : worldsData.values()) { + if (alreadyDone.contains(w)) { + continue; + } + w.reload(); + alreadyDone.add(w); + } + } + + /** + * + * @param worldName + */ + public void reloadWorld(String worldName) { + getWorldData(worldName).reload(); + } + + /** + * + */ + public void saveChanges() { + ArrayList alreadyDone = new ArrayList(); + for (OverloadedWorldHolder w : worldsData.values()) { + if (alreadyDone.contains(w)) { + continue; + } + Tasks.removeOldFiles(plugin.getBackupFolder()); + if (w == null) { + GroupManager.logger.severe("WHAT HAPPENED?"); + continue; + } + if (w.haveGroupsChanged()) { + String groupsFolderName = w.getGroupsFile().getParentFile().getName(); + File backupGroups = new File(plugin.getBackupFolder(), "bkp_" + w.getName() + "_g_" + Tasks.getDateString() + ".yml"); + try { + Tasks.copy(w.getGroupsFile(), backupGroups); + } catch (IOException ex) { + GroupManager.logger.log(Level.SEVERE, null, ex); + } + WorldDataHolder.writeGroups(w, w.getGroupsFile()); + w.removeGroupsChangedFlag(); + } + if (w.haveUsersChanged()) { + File backupUsers = new File(plugin.getBackupFolder(), "bkp_" + w.getName() + "_u_" + Tasks.getDateString() + ".yml"); + try { + Tasks.copy(w.getUsersFile(), backupUsers); + } catch (IOException ex) { + GroupManager.logger.log(Level.SEVERE, null, ex); + } + WorldDataHolder.writeUsers(w, w.getUsersFile()); + w.removeUsersChangedFlag(); + } + alreadyDone.add(w); + } + } + + /** + * Returns the dataHolder for the given world. + * If the world is not on the worlds list, returns the default world + * holder. + * + * (WHEN A WORLD IS CONFIGURED TO MIRROR, IT WILL BE ON THE LIST, BUT + * POINTING TO ANOTHER WORLD HOLDER) + * + * Mirrors prevails original data. + * + * @param worldName + * @return + */ + public OverloadedWorldHolder getWorldData(String worldName) { + OverloadedWorldHolder data = worldsData.get(worldName.toLowerCase()); + if (mirrors.containsKey(worldName.toLowerCase())) { + String realOne = mirrors.get(worldName.toLowerCase()); + data = worldsData.get(realOne.toLowerCase()); + } + if (data == null) { + GroupManager.logger.finest("Requested world " + worldName + " not found or badly mirrored. Returning default world..."); + data = getDefaultWorld(); + } + return data; + } + + /** + * Do a matching of playerName, if it s found only one player, do + * getWorldData(player) + * @param playerName + * @return null if matching returned no player, or more than one. + */ + public OverloadedWorldHolder getWorldDataByPlayerName(String playerName) { + List matchPlayer = plugin.getServer().matchPlayer(playerName); + if (matchPlayer.size() == 1) { + return getWorldData(matchPlayer.get(0)); + } + return null; + } + + /** + * Retrieves the field p.getWorld().getName() and do + * getWorld(worldName) + * @param p + * @return + */ + public OverloadedWorldHolder getWorldData(Player p) { + return getWorldData(p.getWorld().getName()); + } + + /** + * It does getWorld(worldName).getPermissionsHandler() + * @param worldName + * @return + */ + public AnjoPermissionsHandler getWorldPermissions(String worldName) { + return getWorldData(worldName).getPermissionsHandler(); + } + + /** + *It does getWorldData(p).getPermission + * @param p + * @return + */ + public AnjoPermissionsHandler getWorldPermissions(Player p) { + return getWorldData(p).getPermissionsHandler(); + } + + /** + * Id does getWorldDataByPlayerName(playerName). + * If it doesnt return null, it will return result.getPermissionsHandler() + * @param playerName + * @return null if the player matching gone wrong. + */ + public AnjoPermissionsHandler getWorldPermissionsByPlayerName(String playerName) { + WorldDataHolder dh = getWorldDataByPlayerName(playerName); + if (dh != null) { + return dh.getPermissionsHandler(); + } + return null; + } + + private void verifyFirstRun() { + worldsFolder = new File(plugin.getDataFolder(), "worlds"); + if (!worldsFolder.exists()) { + worldsFolder.mkdirs(); + } + Properties server = new Properties(); + try { + server.load(new FileInputStream(new File("server.properties"))); + } catch (IOException ex) { + GroupManager.logger.log(Level.SEVERE, null, ex); + } + serverDefaultWorldName = server.getProperty("level-name").toLowerCase(); + File defaultWorldFolder = new File(worldsFolder, serverDefaultWorldName); + if (!defaultWorldFolder.exists()) { + defaultWorldFolder.mkdirs(); + } + if (defaultWorldFolder.exists()) { + File groupsFile = new File(defaultWorldFolder, "groups.yml"); + File usersFile = new File(defaultWorldFolder, "users.yml"); + File oldDataFile = new File(plugin.getDataFolder(), "data.yml"); + if (!groupsFile.exists()) { + if (oldDataFile.exists()) { + try { + Tasks.copy(oldDataFile, groupsFile); + } catch (IOException ex) { + GroupManager.logger.log(Level.SEVERE, null, ex); + } + } else { + InputStream template = plugin.getResourceAsStream("groups.yml"); + try { + Tasks.copy(template, groupsFile); + } catch (IOException ex) { + GroupManager.logger.log(Level.SEVERE, null, ex); + } + } + } + if (!usersFile.exists()) { + if (oldDataFile.exists()) { + try { + Tasks.copy(oldDataFile, usersFile); + } catch (IOException ex) { + GroupManager.logger.log(Level.SEVERE, null, ex); + } + } else { + InputStream template = plugin.getResourceAsStream("users.yml"); + try { + Tasks.copy(template, usersFile); + } catch (IOException ex) { + GroupManager.logger.log(Level.SEVERE, null, ex); + } + } + } + try { + if (oldDataFile.exists()) { + oldDataFile.renameTo(new File(plugin.getDataFolder(), "NOT_USED_ANYMORE_data.yml")); + } + } catch (Exception ex) { + } + } + } + + /** + * Copies the specified world data to another world + * @param fromWorld + * @param toWorld + * @return + */ + public boolean cloneWorld(String fromWorld, String toWorld) { + File fromWorldFolder = new File(worldsFolder, fromWorld); + File toWorldFolder = new File(worldsFolder, toWorld); + if (toWorldFolder.exists() || !fromWorldFolder.exists()) { + return false; + } + File fromWorldGroups = new File(fromWorldFolder, "groups.yml"); + File fromWorldUsers = new File(fromWorldFolder, "users.yml"); + if (!fromWorldGroups.exists() || !fromWorldUsers.exists()) { + return false; + } + File toWorldGroups = new File(toWorldFolder, "groups.yml"); + File toWorldUsers = new File(toWorldFolder, "users.yml"); + toWorldFolder.mkdirs(); + try { + Tasks.copy(fromWorldGroups, toWorldGroups); + Tasks.copy(fromWorldUsers, toWorldUsers); + } catch (IOException ex) { + Logger.getLogger(WorldsHolder.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + return true; + } + + /** + * Load a world from file. + * If it already been loaded, summon reload method from dataHolder. + * @param worldName + */ + public void loadWorld(String worldName) { + if (worldsData.containsKey(worldName.toLowerCase())) { + worldsData.get(worldName.toLowerCase()).reload(); + return; + } + GroupManager.logger.finest("Trying to load world " + worldName + "..."); + File thisWorldFolder = new File(worldsFolder, worldName); + if (thisWorldFolder.exists() && thisWorldFolder.isDirectory()) { + File groupsFile = new File(thisWorldFolder, "groups.yml"); + File usersFile = new File(thisWorldFolder, "users.yml"); + if (!groupsFile.exists()) { + throw new IllegalArgumentException("Groups file for world '" + worldName + "' doesnt exist: " + groupsFile.getPath()); + } + if (!usersFile.exists()) { + throw new IllegalArgumentException("Users file for world '" + worldName + "' doesnt exist: " + usersFile.getPath()); + } + try { + OverloadedWorldHolder thisWorldData = new OverloadedWorldHolder(WorldDataHolder.load(worldName, groupsFile, usersFile)); + if (thisWorldData != null) { + GroupManager.logger.finest("Successful load of world " + worldName + "..."); + worldsData.put(worldName.toLowerCase(), thisWorldData); + return; + } + } catch (FileNotFoundException ex) { + GroupManager.logger.log(Level.SEVERE, null, ex); + return; + } catch (IOException ex) { + GroupManager.logger.log(Level.SEVERE, null, ex); + return; + } + GroupManager.logger.severe("Failed to load world " + worldName + "..."); + } + } + + /** + * Tells if the such world has been mapped. + * + * It will return true if world is a mirror. + * + * @param worldName + * @return true if world is loaded or mirrored. false if not listed + */ + public boolean isInList(String worldName) { + if (worldsData.containsKey(worldName.toLowerCase()) || mirrors.containsKey(worldName.toLowerCase())) { + return true; + } + return false; + } + + /** + * Verify if world has it's own file permissions. + * + * @param worldName + * @return true if it has its own holder. false if not. + */ + public boolean hasOwnData(String worldName) { + if (worldsData.containsKey(worldName.toLowerCase())) { + return true; + } + return false; + } + + /** + * @return the defaultWorld + */ + public OverloadedWorldHolder getDefaultWorld() { + return defaultWorld; + } + + /** + * Returns all physically loaded worlds. + * @return + */ + public ArrayList allWorldsDataList() { + ArrayList list = new ArrayList(); + for (OverloadedWorldHolder data : worldsData.values()) { + if (!list.contains(data)) { + list.add(data); + } + } + return list; + } +} diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/permissions/AnjoPermissionsHandler.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/permissions/AnjoPermissionsHandler.java new file mode 100644 index 000000000..ca223da81 --- /dev/null +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/permissions/AnjoPermissionsHandler.java @@ -0,0 +1,856 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.anjocaido.groupmanager.permissions; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.StringTokenizer; +import org.anjocaido.groupmanager.GroupManager; +import org.anjocaido.groupmanager.data.Group; +import org.anjocaido.groupmanager.dataholder.WorldDataHolder; +import org.anjocaido.groupmanager.data.User; +import org.anjocaido.groupmanager.utils.PermissionCheckResult; +import org.bukkit.entity.Player; + +/** + * Everything here maintains the model created by Nijikokun + * + * But implemented to use GroupManager system. Which provides instant changes, + * without file access. + * + * It holds permissions only for one single world. + * + * @author gabrielcouto + */ +public class AnjoPermissionsHandler extends PermissionsReaderInterface { + + WorldDataHolder ph = null; + + /** + * It needs a WorldDataHolder to work with. + * @param holder + */ + public AnjoPermissionsHandler(WorldDataHolder holder) { + ph = holder; + } + + /** + * A short name method, for permission method. + * @param player + * @param permission + * @return + */ + @Override + public boolean has(Player player, String permission) { + return permission(player, permission); + } + + /** + * Checks if a player can use that permission node. + * @param player + * @param permission + * @return + */ + @Override + public boolean permission(Player player, String permission) { + return checkUserPermission(ph.getUser(player.getName()), permission); + } + + /** + * Returns the name of the group of that player name. + * @param userName + * @return + */ + @Override + public String getGroup(String userName) { + return ph.getUser(userName).getGroup().getName(); + } + + /** + * Verify if player is in suck group. + * It will check it's groups inheritance. + * + * So if you have a group Admin > Moderator + * + * And verify the player 'MyAdmin', which is Admin, it will return true for both + * Admin or Moderator groups. + * + * Mas if you haave a player 'MyModerator', which is Moderator, + * it will give false if you pass Admin in group parameter. + * + * @param name + * @param group + * @return + */ + @Override + public boolean inGroup(String name, String group) { + if (hasGroupInInheritance(ph.getUser(name).getGroup(), group)) { + return true; + } + for (Group subGroup : ph.getUser(name).subGroupListCopy()) { + if (hasGroupInInheritance(subGroup, group)) { + return true; + } + } + return false; + } + + /** + * Returns the String prefix for the given group + * @param groupName + * @return empty string if found none. + */ + @Override + public String getGroupPrefix(String groupName) { + Group g = ph.getGroup(groupName); + if (g == null) { + return null; + } + return g.getVariables().getVarString("prefix"); + } + + /** + * Return the suffix for the given group name + * @param groupName + * @return + */ + @Override + public String getGroupSuffix(String groupName) { + Group g = ph.getGroup(groupName); + if (g == null) { + return null; + } + return g.getVariables().getVarString("suffix"); + } + + /** + * + * @param groupName + * @return + */ + @Override + public boolean canGroupBuild(String groupName) { + Group g = ph.getGroup(groupName); + if (g == null) { + return false; + } + return g.getVariables().getVarBoolean("build"); + } + + /** + * It returns a string variable value, set in the INFO node of the group. + * It will harvest inheritance for value. + * @param groupName + * @param variable + * @return null if no group with that variable is found. + */ + @Override + public String getGroupPermissionString(String groupName, String variable) { + Group start = ph.getGroup(groupName); + if (start == null) { + return null; + } + Group result = nextGroupWithVariable(start, variable); + if (result == null) { + return null; + } + return result.getVariables().getVarString(variable); + } + + /** + * It returns a Integer variable value + * It will harvest inheritance for value. + * @param groupName + * @param variable + * @return -1 if none found or not parseable. + */ + @Override + public int getGroupPermissionInteger(String groupName, String variable) { + Group start = ph.getGroup(groupName); + if (start == null) { + return -1; + } + Group result = nextGroupWithVariable(start, variable); + if (result == null) { + return -1; + } + return result.getVariables().getVarInteger(variable); + } + + /** + * Returns a boolean for given variable in INFO node. + * It will harvest inheritance for value. + * @param group + * @param variable + * @return false if not found/not parseable. + */ + @Override + public boolean getGroupPermissionBoolean(String group, String variable) { + Group start = ph.getGroup(group); + if (start == null) { + return false; + } + Group result = nextGroupWithVariable(start, variable); + if (result == null) { + return false; + } + return result.getVariables().getVarBoolean(variable); + } + + /** + * Returns a double value for the given variable name in INFO node. + * It will harvest inheritance for value. + * @param group + * @param variable + * @return -1 if not found / not parseable. + */ + @Override + public double getGroupPermissionDouble(String group, String variable) { + Group start = ph.getGroup(group); + if (start == null) { + return -1; + } + Group result = nextGroupWithVariable(start, variable); + if (result == null) { + return -1; + } + return result.getVariables().getVarDouble(variable); + } + + /** + * Returns the variable value of the user, in INFO node. + * @param user + * @param variable + * @return + */ + @Override + public String getUserPermissionString(String user, String variable) { + User auser = ph.getUser(user); + if (auser == null) { + return ""; + } + return auser.getVariables().getVarString(variable); + } + + /** + * Returns the variable value of the user, in INFO node. + * @param user + * @param variable + * @return + */ + @Override + public int getUserPermissionInteger(String user, String variable) { + User auser = ph.getUser(user); + if (auser == null) { + return -1; + } + return auser.getVariables().getVarInteger(variable); + } + + /** + * Returns the variable value of the user, in INFO node. + * @param user + * @param variable + * @return + */ + @Override + public boolean getUserPermissionBoolean(String user, String variable) { + User auser = ph.getUser(user); + if (auser == null) { + return false; + } + return auser.getVariables().getVarBoolean(variable); + } + + /** + * Returns the variable value of the user, in INFO node. + * @param user + * @param variable + * @return + */ + @Override + public double getUserPermissionDouble(String user, String variable) { + User auser = ph.getUser(user); + if (auser == null) { + return -1; + } + return auser.getVariables().getVarDouble(variable); + } + + /** + * Returns the variable value of the user, in INFO node. + * If not found, it will search for his Group variables. + * It will harvest the inheritance. + * @param user + * @param variable + * @return empty string if not found + */ + @Override + public String getPermissionString(String user, String variable) { + User auser = ph.getUser(user); + if (auser == null) { + return ""; + } + if (auser.getVariables().hasVar(variable)) { + return auser.getVariables().getVarString(variable); + } + Group start = auser.getGroup(); + if (start == null) { + return ""; + } + Group result = nextGroupWithVariable(start, variable); + if (result == null) { + return ""; + } + return result.getVariables().getVarString(variable); + //return getUserPermissionString(user, variable); + } + + /** + * Returns the variable value of the user, in INFO node. + * If not found, it will search for his Group variables. + * It will harvest the inheritance. + * @param user + * @param variable + * @return -1 if not found + */ + @Override + public int getPermissionInteger(String user, String variable) { + User auser = ph.getUser(user); + if (auser == null) { + return -1; + } + if (auser.getVariables().hasVar(variable)) { + return auser.getVariables().getVarInteger(variable); + } + Group start = auser.getGroup(); + if (start == null) { + return -1; + } + Group result = nextGroupWithVariable(start, variable); + if (result == null) { + return -1; + } + return result.getVariables().getVarInteger(variable); + //return getUserPermissionInteger(string, string1); + } + + /** + * Returns the variable value of the user, in INFO node. + * If not found, it will search for his Group variables. + * It will harvest the inheritance. + * @param user + * @param variable + * @return false if not found or not parseable to true. + */ + @Override + public boolean getPermissionBoolean(String user, String variable) { + User auser = ph.getUser(user); + if (auser == null) { + return false; + } + if (auser.getVariables().hasVar(variable)) { + return auser.getVariables().getVarBoolean(variable); + } + Group start = auser.getGroup(); + if (start == null) { + return false; + } + Group result = nextGroupWithVariable(start, variable); + if (result == null) { + return false; + } + return result.getVariables().getVarBoolean(variable); + //return getUserPermissionBoolean(user, string1); + } + + /** + * Returns the variable value of the user, in INFO node. + * If not found, it will search for his Group variables. + * It will harvest the inheritance. + * @param user + * @param variable + * @return -1 if not found. + */ + @Override + public double getPermissionDouble(String user, String variable) { + User auser = ph.getUser(user); + if (auser == null) { + return -1.0D; + } + if (auser.getVariables().hasVar(variable)) { + return auser.getVariables().getVarDouble(variable); + } + Group start = auser.getGroup(); + if (start == null) { + return -1.0D; + } + Group result = nextGroupWithVariable(start, variable); + if (result == null) { + return -1.0D; + } + return result.getVariables().getVarDouble(variable); + //return getUserPermissionDouble(string, string1); + } + + /** + * Does not include User's group permission + * @param user + * @param permission + * @return + */ + public PermissionCheckResult checkUserOnlyPermission(User user, String permission) { + user.sortPermissions(); + PermissionCheckResult result = new PermissionCheckResult(); + result.askedPermission = permission; + result.owner = user; + for (String access : user.getPermissionList()) { + if (comparePermissionString(access, permission)) { + result.accessLevel = access; + if (access.startsWith("-")) { + result.resultType = PermissionCheckResult.Type.NEGATION; + } else if (access.startsWith("+")) { + result.resultType = PermissionCheckResult.Type.EXCEPTION; + } else { + result.resultType = PermissionCheckResult.Type.FOUND; + } + return result; + } + } + result.resultType = PermissionCheckResult.Type.NOTFOUND; + return result; + } + + /** + * Returns the node responsible for that permission. + * Does not include User's group permission. + * @param group + * @param permission + * @return the node if permission is found. if not found, return null + */ + public PermissionCheckResult checkGroupOnlyPermission(Group group, String permission) { + group.sortPermissions(); + PermissionCheckResult result = new PermissionCheckResult(); + result.owner = group; + result.askedPermission = permission; + for (String access : group.getPermissionList()) { + if (comparePermissionString(access, permission)) { + result.accessLevel = access; + if (access.startsWith("-")) { + result.resultType = PermissionCheckResult.Type.NEGATION; + } else if (access.startsWith("+")) { + result.resultType = PermissionCheckResult.Type.EXCEPTION; + } else { + result.resultType = PermissionCheckResult.Type.FOUND; + } + return result; + } + } + result.resultType = PermissionCheckResult.Type.NOTFOUND; + return result; + } + + /** + * Check permissions, including it's group and inheritance. + * @param user + * @param permission + * @return true if permission was found. false if not, or was negated. + */ + public boolean checkUserPermission(User user, String permission) { + PermissionCheckResult result = checkFullUserPermission(user, permission); + if (result.resultType.equals(PermissionCheckResult.Type.EXCEPTION) + || result.resultType.equals(PermissionCheckResult.Type.FOUND)) { + return true; + } + return false; + } + + /** + * Do what checkUserPermission did before. But now returning a PermissionCheckResult. + * @param user + * @param targetPermission + * @return + */ + public PermissionCheckResult checkFullUserPermission(User user, String targetPermission) { + PermissionCheckResult result = new PermissionCheckResult(); + result.askedPermission = targetPermission; + result.resultType = PermissionCheckResult.Type.NOTFOUND; + + if (user == null || targetPermission == null) { + return result; + } + + PermissionCheckResult resultUser = checkUserOnlyPermission(user, targetPermission); + if (!resultUser.resultType.equals(PermissionCheckResult.Type.NOTFOUND)) { + return resultUser; + + } + + //IT ONLY CHECKS GROUPS PERMISSIONS IF RESULT FOR USER IS NOT FOUND + PermissionCheckResult resultGroup = checkGroupPermissionWithInheritance(user.getGroup(), targetPermission); + if (!resultGroup.resultType.equals(PermissionCheckResult.Type.NOTFOUND)) { + return resultGroup; + } + + //SUBGROUPS CHECK + for (Group subGroup : user.subGroupListCopy()) { + PermissionCheckResult resultSubGroup = checkGroupPermissionWithInheritance(subGroup, targetPermission); + if (!resultSubGroup.resultType.equals(PermissionCheckResult.Type.NOTFOUND)) { + return resultSubGroup; + } + } + + //THEN IT RETURNS A NOT FOUND + return result; + } + + /** + * Verifies if a given group has a variable. Including it's inheritance. + * + * it redirects to the other method now. This one was deprecated, and will + * be gone in a future release. + * + * @param start + * @param variable + * @param alreadyChecked + * @return returns the closest inherited group with the variable. + * @deprecated use now nextGroupWithVariable(Group start, String targetVariable) + */ + @Deprecated + public Group nextGroupWithVariable(Group start, String variable, List alreadyChecked) { + return nextGroupWithVariable(start, variable); + } + + /** + * Returns the next group, including inheritance, which contains that + * variable name. + * + * It does Breadth-first search + * + * @param start the starting group to look for + * @param targetVariable the variable name + * @return The group if found. Null if not. + */ + public Group nextGroupWithVariable(Group start, String targetVariable) { + if (start == null || targetVariable == null) { + return null; + } + LinkedList stack = new LinkedList(); + ArrayList alreadyVisited = new ArrayList(); + stack.push(start); + alreadyVisited.add(start); + while (!stack.isEmpty()) { + Group now = stack.pop(); + if (now.getVariables().hasVar(targetVariable)) { + return now; + } + for (String sonName : now.getInherits()) { + Group son = ph.getGroup(sonName); + if (son != null && !alreadyVisited.contains(son)) { + stack.push(son); + alreadyVisited.add(son); + } + } + } + return null; + } + + /** + * Check if given group inherits another group. + * + * redirected to the other method. this is deprecated now. and will be gone + * in the future releases. + * + * @param start The group to start the search. + * @param askedGroup Name of the group you're looking for + * @param alreadyChecked groups to ignore(pass null on it, please) + * @return true if it inherits the group. + * @deprecated prefer using hasGroupInInheritance(Group start, String askedGroup) + */ + @Deprecated + public boolean searchGroupInInheritance(Group start, String askedGroup, List alreadyChecked) { + return hasGroupInInheritance(start, askedGroup); + } + + /** + * Check if given group inherits another group. + * + * It does Breadth-first search + * + * @param start The group to start the search. + * @param askedGroup Name of the group you're looking for + * @return true if it inherits the group. + */ + public boolean hasGroupInInheritance(Group start, String askedGroup) { + if (start == null || askedGroup == null) { + return false; + } + LinkedList stack = new LinkedList(); + ArrayList alreadyVisited = new ArrayList(); + stack.push(start); + alreadyVisited.add(start); + while (!stack.isEmpty()) { + Group now = stack.pop(); + if (now.getName().equalsIgnoreCase(askedGroup)) { + return true; + } + for (String sonName : now.getInherits()) { + Group son = ph.getGroup(sonName); + if (son != null && !alreadyVisited.contains(son)) { + stack.push(son); + alreadyVisited.add(son); + } + } + } + return false; + } + + /** + * Check if the group has given permission. Including it's inheritance + * @param start + * @param permission + * @param alreadyChecked + * @return true if PermissionCheckResult is EXCEPTION or FOUND + * @deprecated use the other checkGroupPermissionWithInheritance for everything + */ + @Deprecated + public boolean checkGroupPermissionWithInheritance(Group start, String permission, List alreadyChecked) { + PermissionCheckResult result = checkGroupPermissionWithInheritance(start, permission); + if (result.resultType.equals(result.resultType.EXCEPTION) + || result.resultType.equals(result.resultType.FOUND)) { + return true; + } + return false; + } + + /** + * Returns the result of permission check. Including inheritance. + * If found anything, the PermissionCheckResult that retuns will + * include the Group name, and the result type. + * Result types will be EXCEPTION, NEGATION, FOUND. + * + * If returned type NOTFOUND, the owner will be null, + * and ownerType too. + * + * It does Breadth-first search + * + * @param start + * @param targetPermission + * @return + */ + public PermissionCheckResult checkGroupPermissionWithInheritance(Group start, String targetPermission) { + if (start == null || targetPermission == null) { + return null; + } + LinkedList stack = new LinkedList(); + List alreadyVisited = new ArrayList(); + stack.push(start); + alreadyVisited.add(start); + while (!stack.isEmpty()) { + Group now = stack.pop(); + PermissionCheckResult resultNow = checkGroupOnlyPermission(now, targetPermission); + if (!resultNow.resultType.equals(PermissionCheckResult.Type.NOTFOUND)) { + return resultNow; + } + for (String sonName : now.getInherits()) { + Group son = ph.getGroup(sonName); + if (son != null && !alreadyVisited.contains(son)) { + stack.push(son); + alreadyVisited.add(son); + } + } + } + PermissionCheckResult result = new PermissionCheckResult(); + result.askedPermission = targetPermission; + result.resultType = PermissionCheckResult.Type.NOTFOUND; + return result; + } + + /** + * It uses checkGroupPermissionWithInheritance + * and cast the owner to Group type if result type was EXCEPTION or FOUND. + * + * @param start + * @param permission + * @param alreadyChecked + * @return the group that passed on test. null if no group passed. + * @deprecated use checkGroupPermissionWithInheritance for everything now. + */ + @Deprecated + public Group nextGroupWithPermission(Group start, String permission, List alreadyChecked) { + PermissionCheckResult result = checkGroupPermissionWithInheritance(start, permission); + if (result.resultType.equals(result.resultType.EXCEPTION) + || result.resultType.equals(result.resultType.FOUND)) { + return (Group) checkGroupPermissionWithInheritance(start, permission).owner; + } + return null; + } + + /** + * Return whole list of names of groups in a inheritance chain. Including a + * starting group. + * + * it now redirects to the other method. but get away from this one, + * it will disappear in a future release. + * + * @param start + * @param alreadyChecked + * @return the group that passed on test. null if no group passed. + * @deprecated use the other method with same name, instead + */ + @Deprecated + public ArrayList listAllGroupsInherited(Group start, ArrayList alreadyChecked) { + return listAllGroupsInherited(start); + } + + /** + * Return whole list of names of groups in a inheritance chain. Including a + * starting group. + * + * It does Breadth-first search. So closer groups will appear first in list. + * + * @param start + * @return the group that passed on test. null if no group passed. + */ + public ArrayList listAllGroupsInherited(Group start) { + if (start == null) { + return null; + } + LinkedList stack = new LinkedList(); + ArrayList alreadyVisited = new ArrayList(); + stack.push(start); + alreadyVisited.add(start.getName()); + while (!stack.isEmpty()) { + Group now = stack.pop(); + for (String sonName : now.getInherits()) { + Group son = ph.getGroup(sonName); + if (son != null && !alreadyVisited.contains(son.getName())) { + stack.push(son); + alreadyVisited.add(son.getName()); + } + } + } + return alreadyVisited; + } + + /** + * Compare a user permission like 'myplugin.*' against a full plugin + * permission name, like 'myplugin.dosomething'. + * As the example above, will return true. + * + * Please sort permissions before sending them here. So negative tokens + * get priority. + * + * You must test if it start with negative outside this method. It will + * only tell if the nodes are matching or not. + * + * Every '-' or '+' in the beginning is ignored. It will match only + * node names. + * + * @param userAcessLevel + * @param fullPermissionName + * @return true if found a matching token. false if not. + */ + public boolean comparePermissionString(String userAcessLevel, String fullPermissionName) { + if (userAcessLevel == null || fullPermissionName == null) { + return false; + } + GroupManager.logger.finest("COMPARING " + userAcessLevel + " WITH " + fullPermissionName); + + if (userAcessLevel.startsWith("+")) { + userAcessLevel = userAcessLevel.substring(1); + } else if (userAcessLevel.startsWith("-")) { + userAcessLevel = userAcessLevel.substring(1); + } + + if (fullPermissionName.startsWith("+")) { + fullPermissionName = fullPermissionName.substring(1); + } else if (fullPermissionName.startsWith("-")) { + fullPermissionName = fullPermissionName.substring(1); + } + + + StringTokenizer levelATokenizer = new StringTokenizer(userAcessLevel, "."); + StringTokenizer levelBTokenizer = new StringTokenizer(fullPermissionName, "."); + while (levelATokenizer.hasMoreTokens() && levelBTokenizer.hasMoreTokens()) { + String levelA = levelATokenizer.nextToken(); + String levelB = levelBTokenizer.nextToken(); + GroupManager.logger.finest("ROUND " + levelA + " AGAINST " + levelB); + if (levelA.contains("*")) { + GroupManager.logger.finest("WIN"); + return true; + } + if (levelA.equalsIgnoreCase(levelB)) { + if (!levelATokenizer.hasMoreTokens() && !levelBTokenizer.hasMoreTokens()) { + GroupManager.logger.finest("WIN"); + return true; + } + GroupManager.logger.finest("NEXT"); + continue; + } else { + GroupManager.logger.finest("FAIL"); + return false; + } + + } + GroupManager.logger.finest("FAIL"); + return false; + } + + /** + * Returns a list of all groups. + * + * Including subgroups. + * @param userName + * @return + */ + public String[] getGroups(String userName) { + ArrayList allGroups = listAllGroupsInherited(ph.getUser(userName).getGroup()); + for(Group subg: ph.getUser(userName).subGroupListCopy()){ + allGroups.addAll(listAllGroupsInherited(subg)); + } + String[] arr = new String[allGroups.size()]; + return allGroups.toArray(arr); + } + + /** + * A Breadth-first search thru inheritance model. + * + * Just a model to copy and paste. + * This will guarantee the closer groups will be checked first. + * @param start + * @param targerPermission + * @return + */ + private Group breadthFirstSearch(Group start, String targerPermission) { + if (start == null || targerPermission == null) { + return null; + } + LinkedList stack = new LinkedList(); + ArrayList alreadyVisited = new ArrayList(); + stack.push(start); + alreadyVisited.add(start); + while (!stack.isEmpty()) { + Group now = stack.pop(); + PermissionCheckResult resultNow = checkGroupOnlyPermission(now, targerPermission); + if (resultNow.resultType.equals(PermissionCheckResult.Type.EXCEPTION) + || resultNow.resultType.equals(PermissionCheckResult.Type.FOUND)) { + return now; + } + if (resultNow.resultType.equals(PermissionCheckResult.Type.NEGATION)) { + return null; + } + for (String sonName : now.getInherits()) { + Group son = ph.getGroup(sonName); + if (son != null && !alreadyVisited.contains(son)) { + stack.push(son); + alreadyVisited.add(son); + } + } + } + return null; + } +} diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/permissions/PermissionsReaderInterface.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/permissions/PermissionsReaderInterface.java new file mode 100644 index 000000000..90194cddd --- /dev/null +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/permissions/PermissionsReaderInterface.java @@ -0,0 +1,163 @@ +package org.anjocaido.groupmanager.permissions; + +import org.bukkit.entity.Player; + +/** + * Made by Nijikokun. Changed by Gabriel Couto + * + * This class is intended to *read* permissions from a single world. + * + * @author Nijikokun + * @author Gabriel Couto + */ +public abstract class PermissionsReaderInterface { + + + /** + * + * @param player + * @param string + * @return + */ + public abstract boolean has(Player player, String string); + + /** + * + * @param player + * @param string + * @return + */ + public abstract boolean permission(Player player, String string); + + /** + * + * @param string + * @return + */ + public abstract String getGroup(String string); + + /** + * + * @param string + * @param string1 + * @return + */ + public abstract boolean inGroup(String string, String string1); + + /** + * + * @param string + * @return + */ + public abstract String getGroupPrefix(String string); + + /** + * + * @param string + * @return + */ + public abstract String getGroupSuffix(String string); + + /** + * + * @param string + * @return + */ + public abstract boolean canGroupBuild(String string); + + /** + * + * @param string + * @param string1 + * @return + */ + public abstract String getGroupPermissionString(String string, String string1); + + /** + * + * @param string + * @param string1 + * @return + */ + public abstract int getGroupPermissionInteger(String string, String string1); + + /** + * + * @param string + * @param string1 + * @return + */ + public abstract boolean getGroupPermissionBoolean(String string, String string1); + + /** + * + * @param string + * @param string1 + * @return + */ + public abstract double getGroupPermissionDouble(String string, String string1); + + /** + * + * @param string + * @param string1 + * @return + */ + public abstract String getUserPermissionString(String string, String string1); + + /** + * + * @param string + * @param string1 + * @return + */ + public abstract int getUserPermissionInteger(String string, String string1); + + /** + * + * @param string + * @param string1 + * @return + */ + public abstract boolean getUserPermissionBoolean(String string, String string1); + + /** + * + * @param string + * @param string1 + * @return + */ + public abstract double getUserPermissionDouble(String string, String string1); + + /** + * + * @param string + * @param string1 + * @return + */ + public abstract String getPermissionString(String string, String string1); + + /** + * + * @param string + * @param string1 + * @return + */ + public abstract int getPermissionInteger(String string, String string1); + + /** + * + * @param string + * @param string1 + * @return + */ + public abstract boolean getPermissionBoolean(String string, String string1); + + /** + * + * @param string + * @param string1 + * @return + */ + public abstract double getPermissionDouble(String string, String string1); +} diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/utils/GMLoggerHandler.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/utils/GMLoggerHandler.java new file mode 100644 index 000000000..87b6806ab --- /dev/null +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/utils/GMLoggerHandler.java @@ -0,0 +1,26 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.anjocaido.groupmanager.utils; + +import java.util.logging.ConsoleHandler; +import java.util.logging.Level; +import java.util.logging.LogRecord; + +/** + * + * @author gabrielcouto + */ +public class GMLoggerHandler extends ConsoleHandler { + + @Override + public void publish(LogRecord record) { + String message = "GroupManager - " + record.getLevel() + " - " + record.getMessage(); + if (record.getLevel().equals(Level.SEVERE) || record.getLevel().equals(Level.WARNING)) { + System.err.println(message); + } else { + System.out.println(message); + } + } +} diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/utils/GroupManagerPermissions.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/utils/GroupManagerPermissions.java new file mode 100644 index 000000000..781f2753c --- /dev/null +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/utils/GroupManagerPermissions.java @@ -0,0 +1,51 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.anjocaido.groupmanager.utils; + +/** + * Just a list of commands for this plugin + * @author gabrielcouto + */ +public enum GroupManagerPermissions { + manuadd, + manudel, + manuaddsub, + manudelsub, + mangadd, + mangdel, + manuaddp, + manudelp, + manulistp, + manucheckp, + mangaddp, + mangdelp, + manglistp, + mangcheckp, + mangaddi, + mangdeli, + manuaddv, + manudelv, + manulistv, + manucheckv, + mangaddv, + mangdelv, + manglistv, + mangcheckv, + manwhois, + tempadd, + tempdel, + templist, + tempdelall, + mansave, + manload, + listgroups, + manpromote, + mandemote, + mantogglevalidate, + mantogglesave, + manworld, + manselect, + manclear +} diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/utils/PermissionCheckResult.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/utils/PermissionCheckResult.java new file mode 100644 index 000000000..3ee6fdf30 --- /dev/null +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/utils/PermissionCheckResult.java @@ -0,0 +1,66 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.anjocaido.groupmanager.utils; + +import org.anjocaido.groupmanager.data.DataUnit; + +/** + * + * @author gabrielcouto + */ +public class PermissionCheckResult { + /** + * It should be the owner of the access level found. + * + * Use instanceof to find the owner type + */ + public DataUnit owner; + /** + * The permission node found in the DataUnit. + */ + public String accessLevel; + /** + * The full name of the permission you are looking for + */ + public String askedPermission; + /** + * The result conclusion of the search. + * It determines if the owner can do, or not. + * + * It even determines if it has an owner. + */ + public Type resultType = Type.NOTFOUND; + + /** + * The type of result the search can give. + */ + public enum Type { + + /** + * If found a matching node starting with '+'. + * It means the user CAN do the permission. + */ + EXCEPTION, + /** + * If found a matching node starting with '-'. + * It means the user CANNOT do the permission. + */ + NEGATION, + /** + * If just found a common matching node. + * IT means the user CAN do the permission. + */ + FOUND, + /** + * If no matchin node was found. + * It means the user CANNOT do the permission. + * + * owner field and accessLevel field should not be considered, + * when type is + * NOTFOUND + */ + NOTFOUND + } +} diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/utils/StringPermissionComparator.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/utils/StringPermissionComparator.java new file mode 100644 index 000000000..2e192118d --- /dev/null +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/utils/StringPermissionComparator.java @@ -0,0 +1,50 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package org.anjocaido.groupmanager.utils; + +import java.util.Comparator; + +/** + * + * @author gabrielcouto + */ +public class StringPermissionComparator implements Comparator { + + @Override + public int compare(String permA, String permB) { + boolean ap = permA.startsWith("+"); + boolean bp = permB.startsWith("+"); + boolean am = permA.startsWith("-"); + boolean bm = permB.startsWith("-"); + if(ap&&bp){ + return 0; + } + if(ap&&!bp){ + return -1; + } + if(!ap&&bp){ + return 1; + } + if(am&&bm){ + return 0; + } + if(am&&!bm){ + return -1; + } + if(!am&&bm){ + return 1; + } + return permA.compareToIgnoreCase(permB); + } + private static StringPermissionComparator instance; + public static StringPermissionComparator getInstance(){ + if(instance==null){ + instance = new StringPermissionComparator(); + } + return instance; + } + +} diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/utils/Tasks.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/utils/Tasks.java new file mode 100644 index 000000000..64bdb6209 --- /dev/null +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/utils/Tasks.java @@ -0,0 +1,111 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.anjocaido.groupmanager.utils; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.GregorianCalendar; +import java.util.List; +import org.anjocaido.groupmanager.data.Group; + +/** + * + * @author gabrielcouto + */ +public abstract class Tasks { + + public static void copy(InputStream src, File dst) throws IOException { + InputStream in = src; + OutputStream out = new FileOutputStream(dst); + + // Transfer bytes from in to out + byte[] buf = new byte[1024]; + int len; + while ((len = in.read(buf)) > 0) { + out.write(buf, 0, len); + } + out.close(); + try { + in.close(); + } catch (Exception e) { + } + } + + public static void copy(File src, File dst) throws IOException { + InputStream in = new FileInputStream(src); + copy(in, dst); + } + + public static void removeOldFiles(File folder) { + if (folder.isDirectory()) { + long oldTime = System.currentTimeMillis() - 86400000L; + for (File olds : folder.listFiles()) { + if (olds.isFile()) { + if (olds.lastModified() < oldTime) { + try { + olds.delete(); + } catch (Exception e) { + } + } + } + } + } + } + + public static String getDateString() { + GregorianCalendar now = new GregorianCalendar(); + String date = ""; + date += now.get(GregorianCalendar.DAY_OF_MONTH); + date += "-"; + date += now.get(GregorianCalendar.HOUR); + date += "-"; + date += now.get(GregorianCalendar.MINUTE); + return date; + } + public static String getStringListInString(List list){ + if(list==null){ + return ""; + } + String result=""; + for(int i=0;i list){ + if(list==null){ + return ""; + } + String result=""; + for(int i=0;i + permission: groupmanager.manuadd + manudel: + description: Remove any user specific configuration. Make him default group. + usage: / + permission: groupmanager.manudel + manuaddsub: + description: Add a group to a player's subgroup list. + usage: / + permission: groupmanager.manuaddsub + manudelsub: + description: Remove a group to a player's subgroup list. + usage: / + permission: groupmanager.manudelsub + mangadd: + description: Add group to the system. + usage: / + permission: groupmanager.mangadd + mangdel: + description: Removes group from the system(all it's users become default) + usage: / + permission: groupmanager.mangdel + manuaddp: + description: Add permission diretly to the player. + usage: / + permission: groupmanager.manuaddp + manudelp: + description: Removes permission diretly from the player. + usage: / + permission: groupmanager.manudelp + manulistp: + description: List all permissions from a player. + usage: / + permission: groupmanager.manulistp + manucheckp: + description: Verify if user has a permission, and where it comes from. + usage: / + permission: groupmanager.manucheckp + mangaddp: + description: Add permission to a group. + usage: / + permission: groupmanager.mangaddp + mangdelp: + description: Removes permission from a group. + usage: / + permission: groupmanager.mangdelp + manglistp: + description: Lists all permissions from a group. + usage: / + permission: groupmanager.manglistp + mangcheckp: + description: Check if group has a permission, and where it comes from. + usage: / + permission: groupmanager.mangcheckp + mangaddi: + description: Add a group to another group inheritance list. + usage: / + permission: groupmanager.mangaddi + mangdeli: + description: Remove a group from another group inheritance list. + usage: / + permission: groupmanager.mangdeli + manuaddv: + description: Add, or replaces, a variable to a user (like prefix or suffix). + usage: / + permission: groupmanager.manuaddv + manudelv: + description: Remove a variable from a user. + usage: / + permission: groupmanager.manudelv + manulistv: + description: List variables a user has (like prefix or suffix). + usage: / + permission: groupmanager.manulistv + manucheckv: + description: Verify a value of a variable of user, and where it comes from. + usage: / + permission: groupmanager.manucheckv + mangaddv: + description: Add, or replaces, a variable to a group (like prefix or suffix). + usage: / + permission: groupmanager.mangaddv + mangdelv: + description: Remove a variable from a group. + usage: / + permission: groupmanager.mangdelv + manglistv: + description: List variables a group has (like prefix or suffix). + usage: / + permission: groupmanager.manglistv + mangcheckv: + description: Verify a value of a variable of group, and where it comes from. + usage: / + permission: groupmanager.mangckeckv + manwhois: + description: Tell the group that user belongs. + usage: / + permission: groupmanager.manwhois + tempadd: + description: Creates a temporary permission copy for that user. + usage: / + permission: groupmanager.tempadd + tempdel: + description: Remove the temporary permission copy for player. + usage: / + permission: groupmanager.tempdel + templist: + description: List players in overload-permissions mode made by /tempadd. + usage: / + permission: groupmanager.templist + tempdelall: + description: Remove all overrides made by command /tempadd. + usage: / + permission: groupmanager.tempdelall + mansave: + description: Save all permissions on file. + usage: / + permission: groupmanager.mansave + manload: + description: Reload current world and config.yml. Or load given world. + usage: / [world] + permission: groupmanager.manload + listgroups: + description: List the groups available. + usage: / + permission: groupmanager.listgroups + manpromote: + description: Promote a player in the same heritage line to a higher rank. + usage: / + permission: groupmanager.manpromote + mandemote: + description: Demote a player in the same heritage line to a lower rank. + usage: / + permission: groupmanager.mandemote + mantogglevalidate: + description: Toggle on/off the validating if player is online. + usage: / + permission: groupmanager.mantogglevalidate + mantogglesave: + description: Toggle on/ff the autosave. + usage: / + permission: groupmanager.mantogglesave + manworld: + description: Prints the selected world name + usage: / + permission: groupmanager.manworld + manselect: + description: Select a world to work with next commands. + usage: / + permission: groupmanager.manselect + manclear: + description: Clear world selection. Next commands will work on your world. + usage: / + permission: groupmanager.manclear \ No newline at end of file diff --git a/EssentialsGroupManager/src/users.yml b/EssentialsGroupManager/src/users.yml new file mode 100644 index 000000000..5645c5d23 --- /dev/null +++ b/EssentialsGroupManager/src/users.yml @@ -0,0 +1,59 @@ +users: + aMiner: + subgroups: + - Miner + permissions: [] + group: BlueFaction + info: + prefix: '&d' + suffix: Miner + gmcouto: + subgroups: [] + permissions: [] + group: SemiAdmin + tempRailer: + subgroups: + - Miner + - Railer + permissions: [] + group: BlueFaction + info: + prefix: '&d' + suffix: Miner + anjocaido: + subgroups: [] + permissions: [] + group: Admin + info: + prefix: '&c' + suffix: King + aFarmer: + subgroups: + - Farmer + permissions: [] + group: RedFaction + info: + prefix: '&d' + suffix: Farmer + zenexer: + subgroups: [] + permissions: + - essentials.god + group: Moderator + Teste: + subgroups: + - Miner + - Railer + - SuperCart + - Fighter + - FlyingMan + permissions: [] + group: BlueFaction + aHealer: + subgroups: + - Healer + permissions: [] + group: RedFaction + info: + prefix: '&d' + suffix: Healer diff --git a/EssentialsProtect/MANIFEST.MF b/EssentialsProtect/MANIFEST.MF new file mode 100644 index 000000000..b43aa699e --- /dev/null +++ b/EssentialsProtect/MANIFEST.MF @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 +Class-Path: ../lib/mysql.jar ../lib/sqlite.jar diff --git a/EssentialsProtect/build.xml b/EssentialsProtect/build.xml new file mode 100644 index 000000000..e5e614e3e --- /dev/null +++ b/EssentialsProtect/build.xml @@ -0,0 +1,86 @@ + + ]> + + + + + + + + + + Builds, tests, and runs the project EssentialsProtect. + + + + + + + + + + + + + + diff --git a/EssentialsProtect/nbproject/build-impl.xml b/EssentialsProtect/nbproject/build-impl.xml new file mode 100644 index 000000000..d284d9279 --- /dev/null +++ b/EssentialsProtect/nbproject/build-impl.xml @@ -0,0 +1,1072 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + + + + + + java -cp "${run.classpath.with.dist.jar}" ${main.class} + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + + + + + + + + Must select one file in the IDE or set profile.class + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + 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 applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/EssentialsProtect/nbproject/genfiles.properties b/EssentialsProtect/nbproject/genfiles.properties new file mode 100644 index 000000000..3f48945cc --- /dev/null +++ b/EssentialsProtect/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=ff207988 +build.xml.script.CRC32=1ed11cc3 +build.xml.stylesheet.CRC32=28e38971@1.38.3.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=40644caa +nbproject/build-impl.xml.script.CRC32=1d86f3b0 +nbproject/build-impl.xml.stylesheet.CRC32=19debb58@1.42.1.45 diff --git a/EssentialsProtect/nbproject/private/private.properties b/EssentialsProtect/nbproject/private/private.properties new file mode 100644 index 000000000..94183418a --- /dev/null +++ b/EssentialsProtect/nbproject/private/private.properties @@ -0,0 +1 @@ +user.properties.file=C:\\Users\\Paul\\.netbeans\\7.0beta2\\build.properties diff --git a/EssentialsProtect/nbproject/project.properties b/EssentialsProtect/nbproject/project.properties new file mode 100644 index 000000000..3f2895ed5 --- /dev/null +++ b/EssentialsProtect/nbproject/project.properties @@ -0,0 +1,91 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.title=EssentialsProtect +application.vendor=devhome +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/original-EssentialsProtect.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +file.reference.c3p0-0.9.1.2.jar=..\\lib\\c3p0-0.9.1.2.jar +file.reference.craftbukkit-0.0.1-SNAPSHOT.jar=..\\lib\\craftbukkit-0.0.1-SNAPSHOT.jar +file.reference.mysql.jar=..\\lib\\mysql.jar +file.reference.sqlite.jar=..\\lib\\sqlite.jar +includes=** +jar.archive.disabled=${jnlp.enabled} +jar.compress=false +jar.index=${jnlp.enabled} +javac.classpath=\ + ${reference.Essentials.jar}:\ + ${file.reference.mysql.jar}:\ + ${file.reference.sqlite.jar}:\ + ${file.reference.craftbukkit-0.0.1-SNAPSHOT.jar}:\ + ${file.reference.c3p0-0.9.1.2.jar} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.5 +javac.target=1.5 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir}:\ + ${libs.junit.classpath}:\ + ${libs.junit_4.classpath} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +jnlp.codebase.type=no.codebase +jnlp.descriptor=application +jnlp.enabled=false +jnlp.mixed.code=defaut +jnlp.offline-allowed=false +jnlp.signed=false +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +platform.active=default_platform +project.Essentials=../Essentials +reference.Essentials.jar=${project.Essentials}/dist/Essentials.jar +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project +# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value +# or test-sys-prop.name=value to set system properties for unit tests): +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/EssentialsProtect/nbproject/project.xml b/EssentialsProtect/nbproject/project.xml new file mode 100644 index 000000000..821d66672 --- /dev/null +++ b/EssentialsProtect/nbproject/project.xml @@ -0,0 +1,28 @@ + + + org.netbeans.modules.java.j2seproject + + + EssentialsProtect + + + + + + + + + ../lib\nblibraries.properties + + + + Essentials + jar + + jar + clean + jar + + + + diff --git a/EssentialsProtect/src/README.TXT b/EssentialsProtect/src/README.TXT new file mode 100644 index 000000000..4bb1b5c05 --- /dev/null +++ b/EssentialsProtect/src/README.TXT @@ -0,0 +1,30 @@ +EssentialsProtect: + +REQUIRED : Essentials.jar. Also sqlite.jar, mysql.jar in the bukkit lib folder. + +Config Settings in plugins/Essentials/config.yml + +protect: + datatype: 'sqlite' type of db, options sqlite or mysql + username: 'root' mysql username + pasword: 'root' mysql password + mysqlDb: 'jdbc:mysql://localhost:3306/minecraft' mysql database location + protectSigns: true + protectRails: true + protectBlockBelow: true + preventBlockOnRail: false prevents block placement on protected rails + +On startup creates a sqlite database under /plugins/essentials called EssentialsProtect.db + +Permissions: + +"essentials.protect" - allows protection +"essentials.protect.admin" can delete protected blocks / query protection by right clicking a protected item. + +Usage: + +Place a sign or rail and they (plus optionally the block below) will be protected. Only the owners and those with admin permissions can destroy. + + + + diff --git a/EssentialsProtect/src/com/earth2me/essentials/protect/EssentialsProtect.java b/EssentialsProtect/src/com/earth2me/essentials/protect/EssentialsProtect.java new file mode 100644 index 000000000..d6869519b --- /dev/null +++ b/EssentialsProtect/src/com/earth2me/essentials/protect/EssentialsProtect.java @@ -0,0 +1,154 @@ +package com.earth2me.essentials.protect; + +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.IConf; +import com.earth2me.essentials.User; +import com.earth2me.essentials.protect.data.IProtectedBlock; +import com.earth2me.essentials.protect.data.ProtectedBlockMemory; +import com.earth2me.essentials.protect.data.ProtectedBlockMySQL; +import com.earth2me.essentials.protect.data.ProtectedBlockSQLite; +import java.beans.PropertyVetoException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.Event.Priority; +import org.bukkit.event.Event.Type; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.java.JavaPlugin; + + +public class EssentialsProtect extends JavaPlugin implements IConf +{ + private EssentialsProtectBlockListener blockListener = null; + private EssentialsProtectPlayerListener playerListener = null; + private EssentialsProtectEntityListener entityListener = null; + public static final String AUTHORS = Essentials.AUTHORS; + private static final Logger logger = Logger.getLogger("Minecraft"); + public static HashMap genSettings = null; + public static HashMap dataSettings = null; + public static HashMap guardSettings = null; + public static HashMap playerSettings = null; + public static ArrayList usageList = null; + public static ArrayList blackListPlace = null; + public static ArrayList breakBlackList = null; + public static ArrayList onPlaceAlert = null; + public static ArrayList onUseAlert = null; + public static ArrayList onBreakAlert = null; + + private IProtectedBlock storage = null; + private static EssentialsProtect instance = null; + + public EssentialsProtect() + { + } + + public void onEnable() + { + PluginManager pm = this.getServer().getPluginManager(); + Essentials ess = (Essentials)pm.getPlugin("Essentials"); + if (!ess.isEnabled()) { + pm.enablePlugin(ess); + } + + instance = this; + reloadConfig(); + + playerListener = new EssentialsProtectPlayerListener(this); + blockListener = new EssentialsProtectBlockListener(this); + entityListener = new EssentialsProtectEntityListener(this); + pm.registerEvent(Type.PLAYER_PICKUP_ITEM, playerListener, Priority.Low, this); + pm.registerEvent(Type.PLAYER_INTERACT, playerListener, Priority.Low, this); + pm.registerEvent(Type.BLOCK_PLACE, blockListener, Priority.Highest, this); + pm.registerEvent(Type.BLOCK_FROMTO, blockListener, Priority.Highest, this); + pm.registerEvent(Type.BLOCK_IGNITE, blockListener, Priority.Highest, this); + pm.registerEvent(Type.BLOCK_BURN, blockListener, Priority.Highest, this); + pm.registerEvent(Type.ENTITY_EXPLODE, entityListener, Priority.Highest, this); + pm.registerEvent(Type.ENTITY_DAMAGE, entityListener, Priority.Highest, this); + pm.registerEvent(Type.BLOCK_BREAK, blockListener, Priority.Highest, this); + pm.registerEvent(Type.CREATURE_SPAWN, entityListener, Priority.Highest, this); + + if (!this.getDescription().getVersion().equals(Essentials.getStatic().getDescription().getVersion())) { + logger.log(Level.WARNING, "Version mismatch! Please update all Essentials jars to the same version."); + } + logger.info("Loaded " + this.getDescription().getName() + " build " + this.getDescription().getVersion() + " maintained by " + AUTHORS); + } + + public static boolean checkProtectionItems(ArrayList itemList, int id) + { + return !itemList.isEmpty() && itemList.contains(String.valueOf(id)); + } + + @Override + public void onDisable() + { + genSettings.clear(); + dataSettings.clear(); + + blockListener = null; + playerListener = null; + entityListener = null; + genSettings = null; + dataSettings = null; + guardSettings = null; + playerSettings = null; + usageList = null; + blackListPlace = null; + onPlaceAlert = null; + onUseAlert = null; + onBreakAlert = null; + } + + public void alert(User user, String item, String type) + { + Location loc = user.getLocation(); + for (Player p : this.getServer().getOnlinePlayers()) + { + User alertUser = User.get(p); + if (alertUser.isAuthorized("essentials.protect.alerts")) + alertUser.sendMessage(ChatColor.DARK_AQUA + "[" + user.getName() + "] " + ChatColor.WHITE + type + ChatColor.GOLD + item + " at: " + formatCoords(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())); + } + } + + public static String formatCoords(int x, int y, int z) + { + return x + "," + y + "," + z; + } + + public void reloadConfig() { + dataSettings = Essentials.getSettings().getEpDBSettings(); + genSettings = Essentials.getSettings().getEpSettings(); + guardSettings = Essentials.getSettings().getEpGuardSettings(); + usageList = Essentials.getSettings().epBlackListUsage(); + blackListPlace = Essentials.getSettings().epBlackListPlacement(); + breakBlackList = Essentials.getSettings().epBlockBreakingBlacklist(); + onPlaceAlert = Essentials.getSettings().getEpAlertOnPlacement(); + onUseAlert = Essentials.getSettings().getEpAlertOnUse(); + onBreakAlert = Essentials.getSettings().getEpAlertOnBreak(); + playerSettings = Essentials.getSettings().getEpPlayerSettings(); + + if (dataSettings.get("protect.datatype").equals("mysql")) { + try { + storage = new ProtectedBlockMySQL(dataSettings.get("protect.mysqlDb"), dataSettings.get("protect.username"), dataSettings.get("protect.password")); + } catch (PropertyVetoException ex) { + logger.log(Level.SEVERE, null, ex); + } + } else { + try { + storage = new ProtectedBlockSQLite("jdbc:sqlite:plugins/Essentials/EssentialsProtect.db"); + } catch (PropertyVetoException ex) { + logger.log(Level.SEVERE, null, ex); + } + } + if (genSettings.get("protect.memstore")) { + storage = new ProtectedBlockMemory(storage); + } + } + + public static IProtectedBlock getStorage() { + return EssentialsProtect.instance.storage; + } +} diff --git a/EssentialsProtect/src/com/earth2me/essentials/protect/EssentialsProtectBlockListener.java b/EssentialsProtect/src/com/earth2me/essentials/protect/EssentialsProtectBlockListener.java new file mode 100644 index 000000000..2028edf42 --- /dev/null +++ b/EssentialsProtect/src/com/earth2me/essentials/protect/EssentialsProtectBlockListener.java @@ -0,0 +1,272 @@ +package com.earth2me.essentials.protect; + +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import java.util.ArrayList; +import java.util.List; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockBurnEvent; +import org.bukkit.event.block.BlockFromToEvent; +import org.bukkit.event.block.BlockIgniteEvent; +import org.bukkit.event.block.BlockListener; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.inventory.ItemStack; + + +public class EssentialsProtectBlockListener extends BlockListener +{ + private EssentialsProtect parent; + + public EssentialsProtectBlockListener(EssentialsProtect parent) + { + Essentials.loadClasses(); + this.parent = parent; + } + + @Override + public void onBlockPlace(BlockPlaceEvent event) + { + if (event.isCancelled()) return; + ItemStack item = event.getItemInHand(); + User user = User.get(event.getPlayer()); + + if (EssentialsProtect.playerSettings.get("protect.disable.build") && !user.canBuild()) + { + event.setCancelled(true); + return; + } + + int id = event.getBlockPlaced().getTypeId(); + + if (EssentialsProtect.checkProtectionItems(EssentialsProtect.blackListPlace, id) && !user.isAuthorized("essentials.protect.exemptplacement")) + { + event.setCancelled(true); + return; + } + + if (!EssentialsProtect.onPlaceAlert.isEmpty() && EssentialsProtect.onPlaceAlert.contains(String.valueOf(item.getTypeId()))) + { + parent.alert(user, item.getType().toString(), "placed: "); + } + + Block blockPlaced = event.getBlockPlaced(); + Block below = blockPlaced.getFace(BlockFace.DOWN); + if (below.getType() == Material.RAILS) { + if (EssentialsProtect.genSettings.get("protect.protect.prevent.block-on-rail")) + { + if (EssentialsProtect.getStorage().isProtected(below, user.getName())) { + event.setCancelled(true); + return; + } + } + } + + List protect = new ArrayList(); + if (blockPlaced.getType() == Material.RAILS) { + if (EssentialsProtect.genSettings.get("protect.protect.rails")) + { + if (user.isAuthorized("essentials.protect")) + { + protect.add(blockPlaced); + if (EssentialsProtect.genSettings.get("protect.protect.block-below")) + { + protect.add(blockPlaced.getFace(BlockFace.DOWN)); + } + } + } + } + if (blockPlaced.getType() == Material.SIGN_POST || blockPlaced.getType() == Material.WALL_SIGN) { + if (EssentialsProtect.genSettings.get("protect.protect.signs")) + { + if (user.isAuthorized("essentials.protect")) + { + protect.add(blockPlaced); + if (EssentialsProtect.genSettings.get("protect.protect.block-below")) + { + protect.add(event.getBlockAgainst()); + } + } + } + } + for (Block block : protect) { + EssentialsProtect.getStorage().protectBlock(block, user.getName()); + } + } + + @Override + public void onBlockIgnite(BlockIgniteEvent event) + { + Block block = event.getBlock(); + if (block.getType() == Material.RAILS && EssentialsProtect.genSettings.get("protect.protect.rails")) + { + event.setCancelled(true); + return; + } + if ((block.getType() == Material.WALL_SIGN || block.getType() == Material.SIGN_POST) && EssentialsProtect.genSettings.get("protect.protect.signs")) + { + event.setCancelled(true); + return; + } + if ((event.getCause().equals(BlockIgniteEvent.IgniteCause.SPREAD))) + { + event.setCancelled(EssentialsProtect.guardSettings.get("protect.prevent.fire-spread")); + return; + } + + if (event.getCause().equals(BlockIgniteEvent.IgniteCause.FLINT_AND_STEEL)) + { + event.setCancelled(EssentialsProtect.guardSettings.get("protect.prevent.flint-fire")); + return; + } + + if (event.getCause().equals(BlockIgniteEvent.IgniteCause.LAVA)) + { + event.setCancelled(EssentialsProtect.guardSettings.get("protect.prevent.lava-fire-spread")); + return; + } + } + + @Override + public void onBlockFromTo(BlockFromToEvent event) + { + if (event.isCancelled()) return; + Block block = event.getBlock(); + Block toBlock = event.getToBlock(); + if (toBlock.getType() == Material.RAILS && EssentialsProtect.genSettings.get("protect.protect.rails")) + { + event.setCancelled(true); + return; + } + if ((toBlock.getType() == Material.WALL_SIGN || toBlock.getType() == Material.SIGN_POST) && EssentialsProtect.genSettings.get("protect.protect.signs")) + { + event.setCancelled(true); + return; + } + if (block.getType() == Material.WATER || block.getType() == Material.STATIONARY_WATER) + { + event.setCancelled(EssentialsProtect.guardSettings.get("protect.prevent.water-flow")); + return; + } + + if (block.getType() == Material.LAVA || block.getType() == Material.STATIONARY_LAVA) + { + event.setCancelled(EssentialsProtect.guardSettings.get("protect.prevent.lava-flow")); + return; + } + + if (block.getType() == Material.AIR) + { + event.setCancelled(EssentialsProtect.guardSettings.get("protect.prevent.water-bucket-flow")); + return; + } + } + + @Override + public void onBlockBurn(BlockBurnEvent event) + { + Block block = event.getBlock(); + if (block.getType() == Material.RAILS && EssentialsProtect.genSettings.get("protect.protect.rails")) + { + event.setCancelled(true); + return; + } + if ((block.getType() == Material.WALL_SIGN || block.getType() == Material.SIGN_POST) && EssentialsProtect.genSettings.get("protect.protect.signs")) + { + event.setCancelled(true); + return; + } + if (EssentialsProtect.guardSettings.get("protect.prevent.fire-spread")) + { + event.setCancelled(true); + return; + } + } + + @Override + public void onBlockBreak(BlockBreakEvent event) + { + if (event.isCancelled()) return; + User user = User.get(event.getPlayer()); + Block block = event.getBlock(); + if (EssentialsProtect.playerSettings.get("protect.disable.build") && !user.canBuild()) + { + event.setCancelled(true); + return; + } + + if(EssentialsProtect.breakBlackList.contains(String.valueOf(block.getTypeId())) && !user.isAuthorized("essentials.protect.exemptbreak")) + { + event.setCancelled(true); + return; + } + + if (!EssentialsProtect.onBreakAlert.isEmpty() && EssentialsProtect.onBreakAlert.contains(String.valueOf(block.getTypeId()))) + { + parent.alert(user, block.getType().toString(), "broke: "); + } + + if (user.isAuthorized("essentials.protect.admin")) + { + if (block.getType() == Material.WALL_SIGN || block.getType() == Material.SIGN_POST || block.getType() == Material.RAILS) + { + EssentialsProtect.getStorage().unprotectBlock(block); + if (block.getType() == Material.RAILS || block.getType() == Material.SIGN_POST) { + Block below = block.getFace(BlockFace.DOWN); + EssentialsProtect.getStorage().unprotectBlock(below); + } else { + BlockFace[] faces = new BlockFace[] { + BlockFace.NORTH, + BlockFace.EAST, + BlockFace.SOUTH, + BlockFace.WEST + }; + for (BlockFace blockFace : faces) { + Block against = block.getFace(blockFace); + EssentialsProtect.getStorage().unprotectBlock(against); + } + } + } + else + { + EssentialsProtect.getStorage().unprotectBlock(block); + } + return; + } + else + { + + boolean isProtected = EssentialsProtect.getStorage().isProtected(block, user.getName()); + if (!isProtected) { + if (block.getType() == Material.WALL_SIGN || block.getType() == Material.SIGN_POST || block.getType() == Material.RAILS) + { + EssentialsProtect.getStorage().unprotectBlock(block); + if (block.getType() == Material.RAILS || block.getType() == Material.SIGN_POST) { + Block below = block.getFace(BlockFace.DOWN); + EssentialsProtect.getStorage().unprotectBlock(below); + } else { + BlockFace[] faces = new BlockFace[] { + BlockFace.NORTH, + BlockFace.EAST, + BlockFace.SOUTH, + BlockFace.WEST + }; + for (BlockFace blockFace : faces) { + Block against = block.getFace(blockFace); + EssentialsProtect.getStorage().unprotectBlock(against); + } + } + } + else + { + EssentialsProtect.getStorage().unprotectBlock(block); + } + } + event.setCancelled(true); + return; + } + } +} diff --git a/EssentialsProtect/src/com/earth2me/essentials/protect/EssentialsProtectData.java b/EssentialsProtect/src/com/earth2me/essentials/protect/EssentialsProtectData.java new file mode 100644 index 000000000..76b36d810 --- /dev/null +++ b/EssentialsProtect/src/com/earth2me/essentials/protect/EssentialsProtectData.java @@ -0,0 +1,533 @@ +package com.earth2me.essentials.protect; + +import com.earth2me.essentials.Essentials; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.bukkit.block.Block; + + +public class EssentialsProtectData +{ + private static final Logger logger = Logger.getLogger("Minecraft"); + private static final String mysqlDriver = "com.mysql.jdbc.Driver"; + private static String mysqlUsername; + private static String mysqlPassword; + private static String mysqlDatabase; + private static String dataType; + private static final String sqlite = "jdbc:sqlite:plugins/Essentials/EssentialsProtect.db"; + private static final String mysqlTable; + private static final String sqliteTable; + private static final String insertQuery; + private static final String countByLocationQuery; + private static final String countByPlayerLocationQuery; + private static final String playerByLocationQuery; + private static final String deleteByLocationQuery; + + static + { + mysqlTable = EssentialsProtectSqlProperties.EssentialsProtect; + sqliteTable = EssentialsProtectSqlProperties.EssentialsProtect_sqlite; + insertQuery = EssentialsProtectSqlProperties.Insert; + countByLocationQuery = EssentialsProtectSqlProperties.CountByLocation; + countByPlayerLocationQuery = EssentialsProtectSqlProperties.CountByPLayerLocation; + playerByLocationQuery = EssentialsProtectSqlProperties.PlayerByLocation; + deleteByLocationQuery = EssentialsProtectSqlProperties.DeleteByLocation; + mysqlUsername = EssentialsProtect.dataSettings.get("protect.username"); + mysqlPassword = EssentialsProtect.dataSettings.get("protect.password"); + mysqlDatabase = EssentialsProtect.dataSettings.get("protect.mysqlDb"); + dataType = EssentialsProtect.dataSettings.get("protect.datatype"); + } + + public EssentialsProtectData() + { + } + + public static String formatCoords(int x, int y, int z) + { + return x + "," + y + "," + z; + } + + public void insertProtectionIntoDb(String worldname, String playerName, int x, int y, int z) + { + Connection conn = null; + PreparedStatement ps = null; + ResultSet rs = null; + try + { + if (dataType.contentEquals("mysql")) + { + Class.forName(mysqlDriver); + conn = DriverManager.getConnection(mysqlDatabase, mysqlUsername, mysqlPassword); + } + else + { + Class.forName("org.sqlite.JDBC"); + conn = DriverManager.getConnection(sqlite); + } + ps = conn.prepareStatement(insertQuery); + ps.setString(1, worldname); + ps.setString(2, playerName); + ps.setInt(3, x); + ps.setInt(4, y); + ps.setInt(5, z); + ps.executeUpdate(); + + } + catch (SQLException ex) + { + logger.log(Level.SEVERE, "[EssentialsProtect] Unable to add protection into SQL", ex); + } + catch (ClassNotFoundException e) + { + // TODO Auto-generated catch block + logger.log(Level.SEVERE, "[EssentialsProtect] Class not found", e); + } + finally + { + try + { + if (ps != null) + { + ps.close(); + } + if (rs != null) + { + rs.close(); + } + if (conn != null) + { + conn.close(); + } + } + catch (SQLException ex) + { + logger.log(Level.SEVERE, "[EssentialsProtect] Could not close connection to SQL", ex); + } + } + } + + public boolean canDestroy(String worldName, String playerName, Block block) + { + int x = block.getX(); + int y = block.getY(); + int z = block.getZ(); + + int rowCount = 0; + Connection conn = null; + PreparedStatement ps = null; + ResultSet rs = null; + try + { + if (dataType.contentEquals("mysql")) + { + Class.forName(mysqlDriver); + conn = DriverManager.getConnection(mysqlDatabase, mysqlUsername, mysqlPassword); + } + else + { + Class.forName("org.sqlite.JDBC"); + conn = DriverManager.getConnection(sqlite); + } + conn.setAutoCommit(false); + ps = conn.prepareStatement(countByLocationQuery); + ps.setString(1, worldName); + ps.setInt(2, x); + ps.setInt(3, y); + ps.setInt(4, z); + rs = ps.executeQuery(); + rs.next(); + rowCount = rs.getInt(1); + rs.close(); + ps.close(); + + if (rowCount == 0) + { + return true; + } + else + { + ps = conn.prepareStatement(countByPlayerLocationQuery); + ps.setString(1, worldName); + ps.setString(2, playerName); + ps.setInt(3, x); + ps.setInt(4, y); + ps.setInt(5, z); + rs = ps.executeQuery(); + rs.next(); + rowCount = rs.getInt(1); + + if (rowCount == 0) + { + return false; + } + + } + + } + catch (SQLException ex) + { + logger.log(Level.SEVERE, "[EssentialsProtect] Unable to query Protection", ex); + } + catch (Throwable e) + { + logger.log(Level.SEVERE, "[EssentialsProtect] Unable to query Protection", e); + } + finally + { + try + { + if (ps != null) + { + ps.close(); + } + if (rs != null) + { + rs.close(); + } + if (conn != null) + { + conn.close(); + } + } + catch (SQLException ex) + { + logger.log(Level.SEVERE, "[EssentialsProtection] Could not close connection to SQL", ex); + } + } + return true; + } + + @SuppressWarnings("CallToThreadDumpStack") + public static void createSqlTable() + { + Connection conn = null; + Statement st = null; + + try + { + if (dataType.contentEquals("mysql")) + { + Class.forName(mysqlDriver); + conn = DriverManager.getConnection(mysqlDatabase, mysqlUsername, mysqlPassword); + } + else + { + Class.forName("org.sqlite.JDBC"); + conn = DriverManager.getConnection(sqlite); + } + + st = conn.createStatement(); + st.executeUpdate(dataType.contentEquals("mysql") ? mysqlTable : sqliteTable); + } + catch (SQLException s) + { + logger.log(Level.SEVERE, "[EssentialsProtect] Could not create table for " + dataType, s); + + } + catch (ClassNotFoundException ex) + { + logger.log(Level.SEVERE, "[EssentialsProtect] Could not find driver for " + dataType, ex); + + } + catch (Throwable e) + { + logger.log(Level.SEVERE, "[EssentialsProtect] Unexpected error occured whilst creating table ", e); + } + finally + { + try + { + if (conn != null && !conn.isClosed()) + { + try + { + conn.close(); + } + catch (SQLException e) + { + logger.log(Level.SEVERE, "[EssentialsProtect] Unexpected error occured whilst closing the connection", e); + } + } + } + catch (SQLException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + public String getBlockOwner(String worldName, String playerName, Block block) + { + String returnPlayerName = null; + int x = block.getX(); + int y = block.getY(); + int z = block.getZ(); + + Connection conn = null; + PreparedStatement ps = null; + ResultSet rs = null; + try + { + if (dataType.contentEquals("mysql")) + { + Class.forName(mysqlDriver); + conn = DriverManager.getConnection(mysqlDatabase, mysqlUsername, mysqlPassword); + } + else + { + Class.forName("org.sqlite.JDBC"); + conn = DriverManager.getConnection(sqlite); + } + conn.setAutoCommit(false); + ps = conn.prepareStatement(playerByLocationQuery); + + ps.setString(1, worldName); + ps.setInt(2, x); + ps.setInt(3, y); + ps.setInt(4, z); + rs = ps.executeQuery(); + while (rs.next()) + { + returnPlayerName = rs.getString("playerName"); + } + rs.close(); + ps.close(); + + } + catch (SQLException ex) + { + logger.log(Level.SEVERE, "[EssentialsProtect] Unable to query EssentialsProtection", ex); + } + catch (Throwable e) + { + logger.log(Level.SEVERE, "[EssentialsProtect] Unable to query EssentialsProtection", e); + } + finally + { + try + { + if (ps != null) + { + ps.close(); + } + if (rs != null) + { + rs.close(); + } + if (conn != null) + { + conn.close(); + } + } + catch (SQLException ex) + { + logger.log(Level.SEVERE, "[EssentialsProtection] Could not close connection to SQL", ex); + } + + } + return returnPlayerName; + } + + + public void removeProtectionFromDB(Block block) + { + try + { + Connection conn = null; + if (dataType.contentEquals("mysql")) + { + Class.forName(mysqlDriver); + conn = DriverManager.getConnection(mysqlDatabase, mysqlUsername, + mysqlPassword); + } + else + { + Class.forName("org.sqlite.JDBC"); + conn = DriverManager.getConnection(sqlite); + } + PreparedStatement ps = null; + try + { + ps = conn.prepareStatement(deleteByLocationQuery); + ps.setString(1, block.getWorld().getName()); + ps.setInt(2, block.getX()); + ps.setInt(3, block.getY()); + ps.setInt(4, block.getZ()); + ps.executeUpdate(); + + } + catch (SQLException ex) + { + logger.log(Level.WARNING, + "[EssentialsProtect] Could not delete block data from database", + ex); + } + finally + { + if (conn != null && !conn.isClosed()) + { + conn.close(); + } + if (ps != null) + { + ps.close(); + } + } + + } + catch (Throwable e) + { + logger.log(Level.SEVERE, " [EssentialsProtect] Exception occured whilst trying to delete data from sql", e); + } + + } + + public void removeProtectionFromDB(Block block, boolean removeBelow) + { + try + { + Connection conn = null; + if (dataType.contentEquals("mysql")) + { + Class.forName(mysqlDriver); + conn = DriverManager.getConnection(mysqlDatabase, mysqlUsername, mysqlPassword); + } + else + { + Class.forName("org.sqlite.JDBC"); + conn = DriverManager.getConnection(sqlite); + } + PreparedStatement ps = null; + try + { + ps = conn.prepareStatement(deleteByLocationQuery); + ps.setString(1, block.getWorld().getName()); + ps.setInt(2, block.getX()); + ps.setInt(3, block.getY()); + ps.setInt(4, block.getZ()); + ps.executeUpdate(); + if (removeBelow) + { + ps = conn.prepareStatement(deleteByLocationQuery); + ps.setString(1, block.getWorld().getName()); + ps.setInt(2, block.getX()); + ps.setInt(3, block.getY() - 1); + ps.setInt(4, block.getZ()); + ps.executeUpdate(); + } + + } + catch (SQLException ex) + { + logger.log(Level.WARNING, "[EssentialsProtect] Could not delete block data from database", ex); + } + finally + { + if (conn != null && !conn.isClosed()) + { + conn.close(); + } + if (ps != null) + { + ps.close(); + } + } + + } + catch (Throwable e) + { + logger.log(Level.SEVERE, "[EssentialsProtect] Exception occured whilst trying to delete data from sql", e); + } + + } + + public boolean isBlockAboveProtectedRail(Block block) + { + Connection conn = null; + PreparedStatement ps = null; + ResultSet rs = null; + if (block.getTypeId() == 66) + { + try + { + if (dataType.contentEquals("mysql")) + { + Class.forName(mysqlDriver); + conn = DriverManager.getConnection(mysqlDatabase, mysqlUsername, mysqlPassword); + } + else + { + Class.forName("org.sqlite.JDBC"); + conn = DriverManager.getConnection(sqlite); + } + int rowCount = 0; + conn.setAutoCommit(false); + ps = conn.prepareStatement(countByLocationQuery); + ps.setString(1, block.getWorld().getName()); + ps.setInt(2, block.getX()); + ps.setInt(3, block.getY()); + ps.setInt(4, block.getZ()); + rs = ps.executeQuery(); + rs.next(); + rowCount = rs.getInt(1); + rs.close(); + ps.close(); + + if (rowCount == 0) + { + + return false; + } + else + { + return true; + } + } + catch (SQLException s) + { + logger.log(Level.SEVERE, "[EssentialsProtect] Could not query protection", s); + + } + catch (ClassNotFoundException ex) + { + logger.log(Level.SEVERE, "[EssentialsProtect] Could not find driver for " + dataType, ex); + + } + catch (Throwable e) + { + logger.log(Level.SEVERE, "[EssentialsProtect] Unexpected error occured whilst creating table", e); + } + finally + { + try + { + if (conn != null && !conn.isClosed()) + { + try + { + conn.close(); + } + catch (SQLException e) + { + logger.log(Level.SEVERE, "[EssentialsProtect] Unexpected error occured whilst closing the connection", e); + } + + } + } + catch (SQLException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + return false; + } +} diff --git a/EssentialsProtect/src/com/earth2me/essentials/protect/EssentialsProtectEntityListener.java b/EssentialsProtect/src/com/earth2me/essentials/protect/EssentialsProtectEntityListener.java new file mode 100644 index 000000000..97b5c59e5 --- /dev/null +++ b/EssentialsProtect/src/com/earth2me/essentials/protect/EssentialsProtectEntityListener.java @@ -0,0 +1,197 @@ +package com.earth2me.essentials.protect; + +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import net.minecraft.server.ChunkPosition; +import net.minecraft.server.Packet60Explosion; +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.Creeper; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Monster; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.entity.EntityDamageByBlockEvent; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageByProjectileEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.entity.EntityListener; + + +public class EssentialsProtectEntityListener extends EntityListener +{ + private EssentialsProtect parent; + + public EssentialsProtectEntityListener(EssentialsProtect parent) + { + Essentials.loadClasses(); + this.parent = parent; + } + + @Override + public void onEntityDamage(EntityDamageEvent event) + { + if (event.isCancelled()) return; + if (event instanceof EntityDamageByBlockEvent) + { + DamageCause cause = event.getCause(); + + if (EssentialsProtect.playerSettings.get("protect.disable.contactdmg") && cause == DamageCause.CONTACT) + { + event.setCancelled(true); + return; + } + if (EssentialsProtect.playerSettings.get("protect.disable.lavadmg") && cause == DamageCause.LAVA) + { + event.setCancelled(true); + return; + } + if (EssentialsProtect.guardSettings.get("protect.prevent.tnt-explosion") && cause == DamageCause.BLOCK_EXPLOSION) + { + event.setCancelled(true); + return; + } + } + + if (event instanceof EntityDamageByEntityEvent) + { + EntityDamageByEntityEvent edEvent = (EntityDamageByEntityEvent)event; + Entity eAttack = edEvent.getDamager(); + Entity eDefend = edEvent.getEntity(); + + // PVP Settings + if (eDefend instanceof Player && eAttack instanceof Player) + { + if (EssentialsProtect.playerSettings.get("protect.disable.pvp")) + { + User defender = User.get(eDefend); + User attacker = User.get(eAttack); + + if (!defender.isAuthorized("essentials.protect.pvp") || !attacker.isAuthorized("essentials.protect.pvp")) + { + event.setCancelled(true); + return; + } + } + } + //Creeper explode prevention + if (eAttack != null && eAttack instanceof Monster) + { + if (eAttack instanceof Creeper && EssentialsProtect.guardSettings.get("protect.prevent.creeper-explosion")) + { + event.setCancelled(true); + return; + } + + if (eAttack instanceof Creeper && EssentialsProtect.guardSettings.get("protect.prevent.creeper-playerdamage")) + { + event.setCancelled(true); + return; + } + } + } + + if (event instanceof EntityDamageByProjectileEvent) + { + if (event.getEntity() instanceof Player) + { + event.setCancelled(EssentialsProtect.playerSettings.get("protect.disable.projectiles")); + return; + } + } + + DamageCause cause = event.getCause(); + Entity casualty = event.getEntity(); + if (casualty instanceof Player) + { + if (EssentialsProtect.playerSettings.get("protect.disable.fall") && cause == DamageCause.FALL) + { + event.setCancelled(true); + return; + } + + if (EssentialsProtect.playerSettings.get("protect.disable.suffocate") && cause == DamageCause.SUFFOCATION) + { + event.setCancelled(true); + return; + } + if (EssentialsProtect.playerSettings.get("protect.disable.firedmg") && (cause == DamageCause.FIRE + || cause == DamageCause.FIRE_TICK)) + { + event.setCancelled(true); + return; + } + if (EssentialsProtect.playerSettings.get("protect.disable.drown") && cause == DamageCause.DROWNING) + { + event.setCancelled(true); + return; + } + } + } + + @Override + public void onEntityExplode(EntityExplodeEvent event) + { + if (event.isCancelled()) return; + if (event.getEntity() instanceof LivingEntity) + { + //Nicccccccccce plaaacccccccccce.. + int maxHeight = Essentials.getSettings().getEpCreeperMaxHeight(); + if ( EssentialsProtect.guardSettings.get("protect.prevent.creeper-explosion") || + EssentialsProtect.guardSettings.get("protect.prevent.creeper-blockdamage") || + (maxHeight >= 0 && event.getLocation().getBlockY() > maxHeight)) + { + HashSet set = new HashSet(event.blockList().size()); + Player[] players = parent.getServer().getOnlinePlayers(); + List blocksUnderPlayers = new ArrayList(players.length); + Location loc = event.getLocation(); + for (Player player : players) { + if (player.getWorld().equals(loc.getWorld())) { + blocksUnderPlayers.add( + new ChunkPosition( + player.getLocation().getBlockX(), + player.getLocation().getBlockY() - 1, + player.getLocation().getBlockZ())); + } + } + for (Block block : event.blockList()) { + ChunkPosition cp = new ChunkPosition(block.getX(), block.getY(), block.getZ()); + if (!blocksUnderPlayers.contains(cp)) { + set.add(cp); + } + } + + ((CraftServer)parent.getServer()).getServer().f.a(loc.getX(), loc.getY(), loc.getZ(), 64.0D, + new Packet60Explosion(loc.getX(), loc.getY(), loc.getZ(), 3.0f, set)); + event.setCancelled(true); + return; + } + } + else + { //OH NOES TNT + if (EssentialsProtect.guardSettings.get("protect.prevent.tnt-explosion")) + { + event.setCancelled(true); + return; + } + } + } + + @Override + public void onCreatureSpawn(CreatureSpawnEvent event) { + String creatureName = event.getCreatureType().toString().toLowerCase(); + if (creatureName == null || creatureName.isEmpty()) { + return; + } + if (EssentialsProtect.guardSettings.get("protect.prevent.spawn."+creatureName)) { + event.setCancelled(true); + } + } +} diff --git a/EssentialsProtect/src/com/earth2me/essentials/protect/EssentialsProtectPlayerListener.java b/EssentialsProtect/src/com/earth2me/essentials/protect/EssentialsProtectPlayerListener.java new file mode 100644 index 000000000..2497a733d --- /dev/null +++ b/EssentialsProtect/src/com/earth2me/essentials/protect/EssentialsProtectPlayerListener.java @@ -0,0 +1,70 @@ +package com.earth2me.essentials.protect; + +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import org.bukkit.ChatColor; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerListener; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.inventory.ItemStack; + + +public class EssentialsProtectPlayerListener extends PlayerListener +{ + private EssentialsProtect parent; + + public EssentialsProtectPlayerListener(EssentialsProtect parent) + { + Essentials.loadClasses(); + this.parent = parent; + } + + @Override + public void onPlayerInteract(PlayerInteractEvent event) + { + if (event.isCancelled()) return; + User user = User.get(event.getPlayer()); + + if (EssentialsProtect.playerSettings.get("protect.disable.build") && !user.canBuild()) + { + event.setCancelled(true); + return; + } + + if (user.isAuthorized("essentials.protect.admin")) + { + StringBuilder sb = new StringBuilder(); + boolean first = true; + for (String owner : EssentialsProtect.getStorage().getOwners(event.getClickedBlock())) { + if (!first) { + sb.append(", "); + } + first = false; + sb.append(owner); + } + String ownerNames = sb.toString(); + if (ownerNames != null) + { + user.sendMessage(ChatColor.GOLD + "[EssentialsProtect] Protection owners: " + ownerNames); + } + } + } + + @Override + public void onPlayerPickupItem(PlayerPickupItemEvent event) + { + if(event.isCancelled()) return; + ItemStack item = event.getItem().getItemStack(); + User user = User.get(event.getPlayer()); + if (EssentialsProtect.checkProtectionItems(EssentialsProtect.usageList, item.getTypeId()) && !user.isAuthorized("essentials.protect.exemptusage")) + { + event.setCancelled(true); + return; + } + + if (EssentialsProtect.onUseAlert.contains(String.valueOf(item.getTypeId()))) + { + parent.alert(user, item.getType().toString(), "used: "); + } + } +} diff --git a/EssentialsProtect/src/com/earth2me/essentials/protect/EssentialsProtectRegions.java b/EssentialsProtect/src/com/earth2me/essentials/protect/EssentialsProtectRegions.java new file mode 100644 index 000000000..6a640f3e1 --- /dev/null +++ b/EssentialsProtect/src/com/earth2me/essentials/protect/EssentialsProtectRegions.java @@ -0,0 +1,5 @@ +package com.earth2me.essentials.protect; + +public class EssentialsProtectRegions { + +} diff --git a/EssentialsProtect/src/com/earth2me/essentials/protect/EssentialsProtectSqlProperties.java b/EssentialsProtect/src/com/earth2me/essentials/protect/EssentialsProtectSqlProperties.java new file mode 100644 index 000000000..30b2a7032 --- /dev/null +++ b/EssentialsProtect/src/com/earth2me/essentials/protect/EssentialsProtectSqlProperties.java @@ -0,0 +1,12 @@ +package com.earth2me.essentials.protect; + +public class EssentialsProtectSqlProperties { + + public static String EssentialsProtect="CREATE TABLE IF NOT EXISTS `EssentialsProtect` (`id` int(11) NOT NULL AUTO_INCREMENT, `worldName` varchar(150) NOT NULL, `playerName` varchar(150) NOT NULL, `x` int(11) NOT NULL, `y` int(11) NOT NULL, `z` int(11) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=205 DEFAULT CHARSET=latin1"; + public static String EssentialsProtect_sqlite = "CREATE TABLE IF NOT EXISTS EssentialsProtect (id INTEGER PRIMARY KEY, worldName TEXT ,playerName TEXT, x NUMERIC, y NUMERIC, z NUMERIC)"; + public static String CountByLocation="SELECT COUNT(*) from EssentialsProtect where worldName = ? and x = ? and y = ? and z = ? limit 10"; + public static String CountByPLayerLocation="SELECT COUNT(*) from EssentialsProtect where worldName = ? and playerName =? and x = ? and y = ? and z = ? limit 10"; + public static String DeleteByLocation="DELETE FROM EssentialsProtect WHERE worldName=? and x=? and y=? and z=?"; + public static String Insert="INSERT INTO EssentialsProtect (worldName, playerName, x, y, z) VALUES (?,?,?,?,?)"; + public static String PlayerByLocation="SELECT playerName FROM EssentialsProtect WHERE worldname = ? and x = ? and y = ? and z = ? LIMIT 10"; +} diff --git a/EssentialsProtect/src/com/earth2me/essentials/protect/data/IProtectedBlock.java b/EssentialsProtect/src/com/earth2me/essentials/protect/data/IProtectedBlock.java new file mode 100644 index 000000000..28b7e425b --- /dev/null +++ b/EssentialsProtect/src/com/earth2me/essentials/protect/data/IProtectedBlock.java @@ -0,0 +1,15 @@ +package com.earth2me.essentials.protect.data; + +import java.util.List; +import java.util.Set; +import org.bukkit.block.Block; + +public interface IProtectedBlock { + public void clearProtections(); + public void importProtections(List blocks); + public List exportProtections(); + public void protectBlock(Block block, String playerName); + public boolean isProtected(Block block, String playerName); + public List getOwners(Block block); + public int unprotectBlock(Block block); +} diff --git a/EssentialsProtect/src/com/earth2me/essentials/protect/data/OwnedBlock.java b/EssentialsProtect/src/com/earth2me/essentials/protect/data/OwnedBlock.java new file mode 100644 index 000000000..b9b036798 --- /dev/null +++ b/EssentialsProtect/src/com/earth2me/essentials/protect/data/OwnedBlock.java @@ -0,0 +1,9 @@ +package com.earth2me.essentials.protect.data; + +public class OwnedBlock { + int x; + int y; + int z; + String world; + String playerName; +} diff --git a/EssentialsProtect/src/com/earth2me/essentials/protect/data/ProtectedBlockJDBC.java b/EssentialsProtect/src/com/earth2me/essentials/protect/data/ProtectedBlockJDBC.java new file mode 100644 index 000000000..dec0231b9 --- /dev/null +++ b/EssentialsProtect/src/com/earth2me/essentials/protect/data/ProtectedBlockJDBC.java @@ -0,0 +1,292 @@ +package com.earth2me.essentials.protect.data; + +import com.mchange.v2.c3p0.ComboPooledDataSource; +import java.beans.PropertyVetoException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.bukkit.block.Block; + +public abstract class ProtectedBlockJDBC implements IProtectedBlock { + protected static final Logger logger = Logger.getLogger("Minecraft"); + protected ComboPooledDataSource cpds; + + protected abstract PreparedStatement getStatementCreateTable(Connection conn) throws SQLException; + protected abstract PreparedStatement getStatementDeleteAll(Connection conn) throws SQLException; + protected abstract PreparedStatement getStatementInsert(Connection conn, String world, int x, int y, int z, String playerName) throws SQLException; + protected abstract PreparedStatement getStatementPlayerCountByLocation(Connection conn, String world, int x, int y, int z, String playerName) throws SQLException; + protected abstract PreparedStatement getStatementPlayersByLocation(Connection conn, String name, int x, int y, int z) throws SQLException; + protected abstract PreparedStatement getStatementDeleteByLocation(Connection conn, String world, int x, int y, int z) throws SQLException; + protected abstract PreparedStatement getStatementAllBlocks(Connection conn) throws SQLException; + + public ProtectedBlockJDBC(String driver, String url) throws PropertyVetoException { + this(driver, url, null, null); + } + + public ProtectedBlockJDBC(String driver, String url, String username, String password) throws PropertyVetoException { + cpds = new ComboPooledDataSource(); + cpds.setDriverClass(driver); + cpds.setJdbcUrl(url); + if (username != null) { + cpds.setUser(username); + cpds.setPassword(password); + } + cpds.setMaxStatements(20); + createAndConvertTable(); + } + + + private void createAndConvertTable() { + Connection conn = null; + PreparedStatement ps = null; + try { + conn = cpds.getConnection(); + ps = getStatementCreateTable(conn); + ps.execute(); + } catch (SQLException ex) { + logger.log(Level.SEVERE, null, ex); + } finally { + if (ps != null) { + try { + ps.close(); + } catch (SQLException ex) { + logger.log(Level.SEVERE, null, ex); + } + } + if (conn != null) { + try { + conn.close(); + } catch (SQLException ex) { + logger.log(Level.SEVERE, null, ex); + } + } + } + } + + public void clearProtections() { + Connection conn = null; + PreparedStatement ps = null; + try { + conn = cpds.getConnection(); + ps = getStatementDeleteAll(conn); + ps.executeUpdate(); + } catch (SQLException ex) { + logger.log(Level.SEVERE, null, ex); + } finally { + if (ps != null) { + try { + ps.close(); + } catch (SQLException ex) { + logger.log(Level.SEVERE, null, ex); + } + } + if (conn != null) { + try { + conn.close(); + } catch (SQLException ex) { + logger.log(Level.SEVERE, null, ex); + } + } + } + } + + public void importProtections(List blocks) { + for (OwnedBlock ownedBlock : blocks) { + if (ownedBlock.playerName == null) { + continue; + } + protectBlock(ownedBlock.world, ownedBlock.x, ownedBlock.y, ownedBlock.z, ownedBlock.playerName); + } + } + + public List exportProtections() { + Connection conn = null; + PreparedStatement ps = null; + ResultSet rs = null; + List blocks = new ArrayList(); + try { + conn = cpds.getConnection(); + ps = getStatementAllBlocks(conn); + rs = ps.executeQuery(); + while (rs.next()) { + OwnedBlock ob = new OwnedBlock(); + ob.world = rs.getString(1); + ob.x = rs.getInt(2); + ob.y = rs.getInt(3); + ob.z = rs.getInt(4); + ob.playerName = rs.getString(5); + blocks.add(ob); + } + return blocks; + } catch (SQLException ex) { + logger.log(Level.SEVERE, null, ex); + return blocks; + } finally { + if (rs != null) { + try { + rs.close(); + } catch (SQLException ex) { + logger.log(Level.SEVERE, null, ex); + } + } + if (ps != null) { + try { + ps.close(); + } catch (SQLException ex) { + logger.log(Level.SEVERE, null, ex); + } + } + if (conn != null) { + try { + conn.close(); + } catch (SQLException ex) { + logger.log(Level.SEVERE, null, ex); + } + } + } + } + + public void protectBlock(Block block, String playerName) { + protectBlock(block.getWorld().getName(), block.getX(), block.getY(), block.getZ(), playerName); + } + + private void protectBlock(String world, int x, int y, int z, String playerName) { + Connection conn = null; + PreparedStatement ps = null; + try { + conn = cpds.getConnection(); + ps = getStatementInsert(conn, world, x, y, z, playerName); + ps.executeUpdate(); + } catch (SQLException ex) { + logger.log(Level.SEVERE, null, ex); + } finally { + if (ps != null) { + try { + ps.close(); + } catch (SQLException ex) { + logger.log(Level.SEVERE, null, ex); + } + } + if (conn != null) { + try { + conn.close(); + } catch (SQLException ex) { + logger.log(Level.SEVERE, null, ex); + } + } + } + } + + public boolean isProtected(Block block, String playerName) { + Connection conn = null; + PreparedStatement ps = null; + ResultSet rs = null; + try { + conn = cpds.getConnection(); + ps = getStatementPlayerCountByLocation(conn, block.getWorld().getName(), block.getX(), block.getY(), block.getZ(), playerName); + rs = ps.executeQuery(); + rs.next(); + return rs.getInt(1) > 0 && rs.getInt(2) == 0; + } catch (SQLException ex) { + logger.log(Level.SEVERE, null, ex); + return true; + } finally { + if (rs != null) { + try { + rs.close(); + } catch (SQLException ex) { + logger.log(Level.SEVERE, null, ex); + } + } + if (ps != null) { + try { + ps.close(); + } catch (SQLException ex) { + logger.log(Level.SEVERE, null, ex); + } + } + if (conn != null) { + try { + conn.close(); + } catch (SQLException ex) { + logger.log(Level.SEVERE, null, ex); + } + } + } + } + + public List getOwners(Block block) { + Connection conn = null; + PreparedStatement ps = null; + ResultSet rs = null; + List owners = new ArrayList(); + try { + conn = cpds.getConnection(); + ps = getStatementPlayersByLocation(conn, block.getWorld().getName(), block.getX(), block.getY(), block.getZ()); + rs = ps.executeQuery(); + while (rs.next()) { + owners.add(rs.getString(1)); + } + return owners; + } catch (SQLException ex) { + logger.log(Level.SEVERE, null, ex); + return owners; + } finally { + if (rs != null) { + try { + rs.close(); + } catch (SQLException ex) { + logger.log(Level.SEVERE, null, ex); + } + } + if (ps != null) { + try { + ps.close(); + } catch (SQLException ex) { + logger.log(Level.SEVERE, null, ex); + } + } + if (conn != null) { + try { + conn.close(); + } catch (SQLException ex) { + logger.log(Level.SEVERE, null, ex); + } + } + } + } + + public int unprotectBlock(Block block) { + Connection conn = null; + PreparedStatement ps = null; + try { + conn = cpds.getConnection(); + ps = getStatementDeleteByLocation(conn, block.getWorld().getName(), block.getX(), block.getY(), block.getZ()); + return ps.executeUpdate(); + } catch (SQLException ex) { + logger.log(Level.SEVERE, null, ex); + return 0; + } finally { + if (ps != null) { + try { + ps.close(); + } catch (SQLException ex) { + logger.log(Level.SEVERE, null, ex); + } + } + if (conn != null) { + try { + conn.close(); + } catch (SQLException ex) { + logger.log(Level.SEVERE, null, ex); + } + } + } + } + +} diff --git a/EssentialsProtect/src/com/earth2me/essentials/protect/data/ProtectedBlockMemory.java b/EssentialsProtect/src/com/earth2me/essentials/protect/data/ProtectedBlockMemory.java new file mode 100644 index 000000000..53dee66d2 --- /dev/null +++ b/EssentialsProtect/src/com/earth2me/essentials/protect/data/ProtectedBlockMemory.java @@ -0,0 +1,205 @@ +package com.earth2me.essentials.protect.data; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map.Entry; +import java.util.Set; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.plugin.Plugin; + +public class ProtectedBlockMemory implements IProtectedBlock { + + List worlds = new ArrayList(); + List playerNames = new ArrayList(); + IProtectedBlock storage; + Plugin plugin; + + class ProtectedLocation { + + int x; + int y; + int z; + int w; + + private ProtectedLocation(Block block, int worldId) { + this.x = block.getX(); + this.y = block.getY(); + this.z = block.getZ(); + this.w = worldId; + } + + private ProtectedLocation(OwnedBlock ownedBlock, int worldId) { + this.x = ownedBlock.x; + this.y = ownedBlock.y; + this.z = ownedBlock.z; + this.w = worldId; + } + + @Override + public boolean equals(Object o) { + if (o instanceof ProtectedLocation) { + ProtectedLocation pl = (ProtectedLocation) o; + return x == pl.x && y == pl.y && z == pl.z && w == pl.w; + } + return false; + } + + @Override + public int hashCode() { + return x ^ y ^ z ^ w; + } + } + + class ProtectedBy { + + private int playerId = -1; + private Set playerIds; + + private ProtectedBy() { + } + + private void add(int playerId) { + if (this.playerId == -1 || this.playerId == playerId) { + this.playerId = playerId; + } else { + if (playerIds == null) { + playerIds = new HashSet(4); + playerIds.add(this.playerId); + } + playerIds.add(playerId); + } + } + + private boolean contains(int playerId) { + if (playerIds == null) { + return this.playerId == playerId; + } + return playerIds.contains(playerId); + } + + private List getPlayers(List playerNames) { + if (playerIds == null) { + List list = new ArrayList(2); + list.add(playerNames.get(playerId)); + return list; + } + List list = new ArrayList(playerIds.size()); + for (Integer integer : playerIds) { + list.add(playerNames.get(integer)); + } + return list; + } + + private int size() { + if (playerIds == null) { + return 1; + } + return playerIds.size(); + } + } + HashMap blocks = new HashMap(); + + public ProtectedBlockMemory(IProtectedBlock storage) { + this.storage = storage; + importProtections(storage.exportProtections()); + } + + public void clearProtections() { + blocks.clear(); + } + + public final void importProtections(List blocks) { + for (OwnedBlock ownedBlock : blocks) { + ProtectedLocation pl = new ProtectedLocation(ownedBlock, getWorldId(ownedBlock.world)); + if (ownedBlock.playerName == null) { + continue; + } + protectBlock(pl, ownedBlock.playerName); + } + } + + public List exportProtections() { + List blockList = new ArrayList(blocks.size()); + for (Entry entry : blocks.entrySet()) { + for (String name : entry.getValue().getPlayers(playerNames)) { + OwnedBlock ob = new OwnedBlock(); + ob.x = entry.getKey().x; + ob.y = entry.getKey().y; + ob.z = entry.getKey().z; + ob.world = worlds.get(entry.getKey().w); + ob.playerName = name; + blockList.add(ob); + } + } + return blockList; + } + + public void protectBlock(final Block block, final String playerName) { + ProtectedLocation pl = new ProtectedLocation(block, getWorldId(block.getWorld())); + protectBlock(pl, playerName); + plugin.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, new Runnable() { + public void run() { + storage.protectBlock(block, playerName); + } + }); + } + + private void protectBlock(ProtectedLocation pl, String playerName) { + int playerId = getPlayerId(playerName); + ProtectedBy pb = blocks.get(pl); + if (pb == null) { + pb = new ProtectedBy(); + blocks.put(pl, pb); + } + pb.add(playerId); + } + + public boolean isProtected(Block block, String playerName) { + int playerId = getPlayerId(playerName); + ProtectedLocation pl = new ProtectedLocation(block, getWorldId(block.getWorld())); + ProtectedBy pb = blocks.get(pl); + return !pb.contains(playerId); + } + + public List getOwners(Block block) { + ProtectedLocation pl = new ProtectedLocation(block, getWorldId(block.getWorld())); + ProtectedBy pb = blocks.get(pl); + return pb.getPlayers(playerNames); + } + + public int unprotectBlock(final Block block) { + ProtectedLocation pl = new ProtectedLocation(block, getWorldId(block.getWorld())); + ProtectedBy pb = blocks.remove(pl); + plugin.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, new Runnable() { + public void run() { + storage.unprotectBlock(block); + } + }); + return pb.size(); + } + + private int getPlayerId(String playername) { + int id = playerNames.indexOf(playername); + if (id < 0) { + playerNames.add(playername); + id = playerNames.indexOf(playername); + } + return id; + } + + private int getWorldId(World world) { + return getWorldId(world.getName()); + } + + private int getWorldId(String name) { + int id = worlds.indexOf(name); + if (id < 0) { + worlds.add(name); + id = worlds.indexOf(name); + } + return id; + } +} diff --git a/EssentialsProtect/src/com/earth2me/essentials/protect/data/ProtectedBlockMySQL.java b/EssentialsProtect/src/com/earth2me/essentials/protect/data/ProtectedBlockMySQL.java new file mode 100644 index 000000000..8824f4040 --- /dev/null +++ b/EssentialsProtect/src/com/earth2me/essentials/protect/data/ProtectedBlockMySQL.java @@ -0,0 +1,89 @@ +package com.earth2me.essentials.protect.data; + +import java.beans.PropertyVetoException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +public class ProtectedBlockMySQL extends ProtectedBlockJDBC { + + public ProtectedBlockMySQL(String url, String username, String password) throws PropertyVetoException { + super("com.mysql.jdbc.Driver", url, username, password); + } + + private static final String QueryCreateTable = + "CREATE TABLE IF NOT EXISTS `EssentialsProtectedBlocks` (" + + "`worldName` varchar(150) NOT NULL," + + "`x` int(11) NOT NULL, `y` int(11) NOT NULL, `z` int(11) NOT NULL," + + "`playerName` varchar(150) NOT NULL," + + ") ENGINE=MyISAM DEFAULT CHARSET=utf8"; + + @Override + protected PreparedStatement getStatementCreateTable(Connection conn) throws SQLException { + return conn.prepareStatement(QueryCreateTable); + } + private static final String QueryDeleteAll = "DELETE FROM EssentialsProtectedBlocks;"; + + @Override + protected PreparedStatement getStatementDeleteAll(Connection conn) throws SQLException { + return conn.prepareStatement(QueryDeleteAll); + } + private static final String QueryInsert = + "INSERT INTO EssentialsProtectedBlocks (worldName, x, y, z, playerName) VALUES (?, ?, ?, ?, ?);"; + + @Override + protected PreparedStatement getStatementInsert(Connection conn, String world, int x, int y, int z, String playerName) throws SQLException { + PreparedStatement ps = conn.prepareStatement(QueryInsert); + ps.setString(1, world); + ps.setInt(2, x); + ps.setInt(3, y); + ps.setInt(4, z); + ps.setString(5, playerName); + return ps; + } + private static final String QueryCountByPlayer = + "SELECT COUNT(playerName), SUM(playerName = ?) FROM EssentialsProtectedBlocks " + + "WHERE worldName = ? AND x = ? AND y = ? AND z = ? GROUP BY x;"; + + @Override + protected PreparedStatement getStatementPlayerCountByLocation(Connection conn, String world, int x, int y, int z, String playerName) throws SQLException { + PreparedStatement ps = conn.prepareStatement(QueryCountByPlayer); + ps.setString(1, playerName); + ps.setString(2, world); + ps.setInt(3, x); + ps.setInt(4, y); + ps.setInt(5, z); + return ps; + } + private static final String QueryPlayersByLocation = + "SELECT playerName FROM EssentialsProtectedBlocks WHERE worldname = ? AND x = ? AND y = ? AND z = ?;"; + + @Override + protected PreparedStatement getStatementPlayersByLocation(Connection conn, String world, int x, int y, int z) throws SQLException { + PreparedStatement ps = conn.prepareStatement(QueryPlayersByLocation); + ps.setString(1, world); + ps.setInt(2, x); + ps.setInt(3, y); + ps.setInt(4, z); + return ps; + } + private static final String QueryDeleteByLocation = + "DELETE FROM EssentialsProtectedBlocks WHERE worldName = ? AND x = ? AND y = ? AND z = ?;"; + + @Override + protected PreparedStatement getStatementDeleteByLocation(Connection conn, String world, int x, int y, int z) throws SQLException { + PreparedStatement ps = conn.prepareStatement(QueryDeleteByLocation); + ps.setString(1, world); + ps.setInt(2, x); + ps.setInt(3, y); + ps.setInt(4, z); + return ps; + } + private static final String QueryAllBlocks = + "SELECT worldName, x, y, z, playerName FROM EssentialsProtectedBlocks;"; + + @Override + protected PreparedStatement getStatementAllBlocks(Connection conn) throws SQLException { + return conn.prepareStatement(QueryAllBlocks); + } +} diff --git a/EssentialsProtect/src/com/earth2me/essentials/protect/data/ProtectedBlockSQLite.java b/EssentialsProtect/src/com/earth2me/essentials/protect/data/ProtectedBlockSQLite.java new file mode 100644 index 000000000..ff96a8952 --- /dev/null +++ b/EssentialsProtect/src/com/earth2me/essentials/protect/data/ProtectedBlockSQLite.java @@ -0,0 +1,87 @@ +package com.earth2me.essentials.protect.data; + +import java.beans.PropertyVetoException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +public class ProtectedBlockSQLite extends ProtectedBlockJDBC { + + public ProtectedBlockSQLite(String url) throws PropertyVetoException { + super("org.sqlite.JDBC", url); + } + + private static final String QueryCreateTable = + "CREATE TABLE IF NOT EXISTS EssentialsProtect (" + + "worldName TEXT ,playerName TEXT, " + + "x NUMERIC, y NUMERIC, z NUMERIC)"; + + @Override + protected PreparedStatement getStatementCreateTable(Connection conn) throws SQLException { + return conn.prepareStatement(QueryCreateTable); + } + private static final String QueryDeleteAll = "DELETE FROM EssentialsProtectedBlocks;"; + + @Override + protected PreparedStatement getStatementDeleteAll(Connection conn) throws SQLException { + return conn.prepareStatement(QueryDeleteAll); + } + private static final String QueryInsert = + "INSERT INTO EssentialsProtectedBlocks (worldName, x, y, z, playerName) VALUES (?, ?, ?, ?, ?);"; + + @Override + protected PreparedStatement getStatementInsert(Connection conn, String world, int x, int y, int z, String playerName) throws SQLException { + PreparedStatement ps = conn.prepareStatement(QueryInsert); + ps.setString(1, world); + ps.setInt(2, x); + ps.setInt(3, y); + ps.setInt(4, z); + ps.setString(5, playerName); + return ps; + } + private static final String QueryPlayerCountByLocation = + "SELECT COUNT(playerName), SUM(playerName = ?) FROM EssentialsProtectedBlocks " + + "WHERE worldName = ? AND x = ? AND y = ? AND z = ? GROUP BY x;"; + + @Override + protected PreparedStatement getStatementPlayerCountByLocation(Connection conn, String world, int x, int y, int z, String playerName) throws SQLException { + PreparedStatement ps = conn.prepareStatement(QueryPlayerCountByLocation); + ps.setString(1, playerName); + ps.setString(2, world); + ps.setInt(3, x); + ps.setInt(4, y); + ps.setInt(5, z); + return ps; + } + private static final String QueryPlayersByLocation = + "SELECT playerName FROM EssentialsProtectedBlocks WHERE worldname = ? AND x = ? AND y = ? AND z = ?;"; + + @Override + protected PreparedStatement getStatementPlayersByLocation(Connection conn, String world, int x, int y, int z) throws SQLException { + PreparedStatement ps = conn.prepareStatement(QueryPlayersByLocation); + ps.setString(1, world); + ps.setInt(2, x); + ps.setInt(3, y); + ps.setInt(4, z); + return ps; + } + private static final String QueryDeleteByLocation = + "DELETE FROM EssentialsProtectedBlocks WHERE worldName = ? AND x = ? AND y = ? AND z = ?;"; + + @Override + protected PreparedStatement getStatementDeleteByLocation(Connection conn, String world, int x, int y, int z) throws SQLException { + PreparedStatement ps = conn.prepareStatement(QueryDeleteByLocation); + ps.setString(1, world); + ps.setInt(2, x); + ps.setInt(3, y); + ps.setInt(4, z); + return ps; + } + private static final String QueryAllBlocks = + "SELECT worldName, x, y, z, playerName FROM EssentialsProtectedBlocks;"; + + @Override + protected PreparedStatement getStatementAllBlocks(Connection conn) throws SQLException { + return conn.prepareStatement(QueryAllBlocks); + } +} diff --git a/EssentialsProtect/src/plugin.yml b/EssentialsProtect/src/plugin.yml new file mode 100644 index 000000000..c6f7830c1 --- /dev/null +++ b/EssentialsProtect/src/plugin.yml @@ -0,0 +1,8 @@ +# This determines the command prefix when there are conflicts (/name:home, /name:help, etc.) +name: EssentialsProtect +main: com.earth2me.essentials.protect.EssentialsProtect +# Note to developers: This next line cannot change, or the automatic versioning system will break. +version: TeamCity +website: http://www.earth2me.net:8001/ +description: Provides protection for various parts of the world. +authors: [Zenexer, ementalo, Aelux, Brettflan, KimKandor, snowleo] \ No newline at end of file diff --git a/EssentialsSpawn/build.xml b/EssentialsSpawn/build.xml new file mode 100644 index 000000000..7dfcbb707 --- /dev/null +++ b/EssentialsSpawn/build.xml @@ -0,0 +1,76 @@ + + ]> + + + + + + + + + + Builds, tests, and runs the project EssentialsSpawn. + + &buildinc; + + diff --git a/EssentialsSpawn/nbproject/build-impl.xml b/EssentialsSpawn/nbproject/build-impl.xml new file mode 100644 index 000000000..d343051e5 --- /dev/null +++ b/EssentialsSpawn/nbproject/build-impl.xml @@ -0,0 +1,1072 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + + + + + + java -cp "${run.classpath.with.dist.jar}" ${main.class} + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + + + + + + + + Must select one file in the IDE or set profile.class + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + 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 applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/EssentialsSpawn/nbproject/genfiles.properties b/EssentialsSpawn/nbproject/genfiles.properties new file mode 100644 index 000000000..790af6977 --- /dev/null +++ b/EssentialsSpawn/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=45238b6c +build.xml.script.CRC32=46e3642f +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=e7b96939 +nbproject/build-impl.xml.script.CRC32=c9db80de +nbproject/build-impl.xml.stylesheet.CRC32=19debb58@1.42.1.45 diff --git a/EssentialsSpawn/nbproject/private/private.properties b/EssentialsSpawn/nbproject/private/private.properties new file mode 100644 index 000000000..94183418a --- /dev/null +++ b/EssentialsSpawn/nbproject/private/private.properties @@ -0,0 +1 @@ +user.properties.file=C:\\Users\\Paul\\.netbeans\\7.0beta2\\build.properties diff --git a/EssentialsSpawn/nbproject/project.properties b/EssentialsSpawn/nbproject/project.properties new file mode 100644 index 000000000..1c4af9a9a --- /dev/null +++ b/EssentialsSpawn/nbproject/project.properties @@ -0,0 +1,76 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.title=EssentialsSpawn +application.vendor=Paul +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/EssentialsSpawn.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +file.reference.craftbukkit-0.0.1-SNAPSHOT.jar=..\\lib\\craftbukkit-0.0.1-SNAPSHOT.jar +includes=** +jar.compress=false +javac.classpath=\ + ${reference.Essentials.jar}:\ + ${file.reference.craftbukkit-0.0.1-SNAPSHOT.jar} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.5 +javac.target=1.5 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir}:\ + ${libs.junit.classpath}:\ + ${libs.junit_4.classpath} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +meta.inf.dir=${src.dir}/META-INF +platform.active=default_platform +project.Essentials=../Essentials +reference.Essentials.jar=${project.Essentials}/dist/Essentials.jar +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project +# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value +# or test-sys-prop.name=value to set system properties for unit tests): +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/EssentialsSpawn/nbproject/project.xml b/EssentialsSpawn/nbproject/project.xml new file mode 100644 index 000000000..8de247766 --- /dev/null +++ b/EssentialsSpawn/nbproject/project.xml @@ -0,0 +1,28 @@ + + + org.netbeans.modules.java.j2seproject + + + EssentialsSpawn + + + + + + + + + ../lib\nblibraries.properties + + + + Essentials + jar + + jar + clean + jar + + + + diff --git a/EssentialsSpawn/src/com/earth2me/essentials/spawn/Commandsetspawn.java b/EssentialsSpawn/src/com/earth2me/essentials/spawn/Commandsetspawn.java new file mode 100644 index 000000000..e64985737 --- /dev/null +++ b/EssentialsSpawn/src/com/earth2me/essentials/spawn/Commandsetspawn.java @@ -0,0 +1,24 @@ +package com.earth2me.essentials.spawn; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import com.earth2me.essentials.commands.EssentialsCommand; + + +public class Commandsetspawn extends EssentialsCommand +{ + public Commandsetspawn() + { + super("setspawn"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + user.charge(this); + String group = args.length > 0 ? getFinalArg(args, 0) : "default"; + parent.spawn.setSpawn(user.getLocation(), group); + user.sendMessage("§7Spawn location set for group \"" + group + "\"."); + } +} diff --git a/EssentialsSpawn/src/com/earth2me/essentials/spawn/Commandspawn.java b/EssentialsSpawn/src/com/earth2me/essentials/spawn/Commandspawn.java new file mode 100644 index 000000000..c26cc9e37 --- /dev/null +++ b/EssentialsSpawn/src/com/earth2me/essentials/spawn/Commandspawn.java @@ -0,0 +1,23 @@ +package com.earth2me.essentials.spawn; + +import org.bukkit.Server; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import com.earth2me.essentials.commands.EssentialsCommand; + + +public class Commandspawn extends EssentialsCommand +{ + public Commandspawn() + { + super("spawn"); + } + + @Override + public void run(Server server, Essentials parent, User user, String commandLabel, String[] args) throws Exception + { + user.canAfford(this); + user.teleportCooldown(); + user.respawn(Essentials.getStatic().spawn, this.getName()); + } +} diff --git a/EssentialsSpawn/src/com/earth2me/essentials/spawn/EssentialsSpawn.java b/EssentialsSpawn/src/com/earth2me/essentials/spawn/EssentialsSpawn.java new file mode 100644 index 000000000..54e6bd198 --- /dev/null +++ b/EssentialsSpawn/src/com/earth2me/essentials/spawn/EssentialsSpawn.java @@ -0,0 +1,65 @@ +package com.earth2me.essentials.spawn; + +import java.io.*; +import java.util.logging.*; +import com.earth2me.essentials.*; +import org.bukkit.command.*; +import org.bukkit.event.Event.Priority; +import org.bukkit.event.Event.Type; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.java.*; + + +public class EssentialsSpawn extends JavaPlugin +{ + public static final String AUTHORS = Essentials.AUTHORS; + private static final Logger logger = Logger.getLogger("Minecraft"); + + public EssentialsSpawn() throws IOException + { + + } + + @SuppressWarnings("LoggerStringConcat") + public void onEnable() + { + Plugin p = this.getServer().getPluginManager().getPlugin("Essentials"); + if (p != null) { + if (!this.getServer().getPluginManager().isPluginEnabled(p)) { + this.getServer().getPluginManager().enablePlugin(p); + } + } + EssentialsSpawnPlayerListener playerListener = new EssentialsSpawnPlayerListener(); + getServer().getPluginManager().registerEvent(Type.PLAYER_RESPAWN, playerListener, Priority.Low, this); + getServer().getPluginManager().registerEvent(Type.PLAYER_JOIN, playerListener, Priority.Low, this); + + if (!this.getDescription().getVersion().equals(Essentials.getStatic().getDescription().getVersion())) { + logger.log(Level.WARNING, "Version mismatch! Please update all Essentials jars to the same version."); + } + logger.info("Loaded " + this.getDescription().getName() + " build " + this.getDescription().getVersion() + " maintained by " + AUTHORS); + } + + public void onDisable() + { + } + + @SuppressWarnings( + { + "LoggerStringConcat", "CallToThreadDumpStack" + }) + @Override + public boolean onCommand(CommandSender sender, Command command, String commandLabel, String[] args) + { + try + { + Essentials.loadClasses(); + Essentials.previewCommand(sender, command, commandLabel, args); + return EssentialsSpawnWorker.onCommand(sender, command, commandLabel, args); + } + catch (Throwable ex) + { + ex.printStackTrace(); + return true; + } + } +} diff --git a/EssentialsSpawn/src/com/earth2me/essentials/spawn/EssentialsSpawnPlayerListener.java b/EssentialsSpawn/src/com/earth2me/essentials/spawn/EssentialsSpawnPlayerListener.java new file mode 100644 index 000000000..697939daa --- /dev/null +++ b/EssentialsSpawn/src/com/earth2me/essentials/spawn/EssentialsSpawnPlayerListener.java @@ -0,0 +1,51 @@ +package com.earth2me.essentials.spawn; + +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerListener; +import org.bukkit.event.player.PlayerRespawnEvent; + + +public class EssentialsSpawnPlayerListener extends PlayerListener +{ + @Override + public void onPlayerRespawn(PlayerRespawnEvent event) + { + Essentials.loadClasses(); + User user = User.get(event.getPlayer()); + + try + { + if (Essentials.getSettings().getRespawnAtHome()) + { + event.setRespawnLocation(user.getHome()); + return; + } + } + catch (Throwable ex) + { + } + event.setRespawnLocation(Essentials.getStatic().spawn.getSpawn(user.getGroup())); + } + + @Override + public void onPlayerJoin(PlayerJoinEvent event) + { + Essentials.loadClasses(); + User user = User.get(event.getPlayer()); + + if (!user.isNew()) return; + user.clearNewFlag(); + try { + user.teleportToNow(Essentials.getStatic().spawn.getSpawn(Essentials.getSettings().getNewbieSpawn())); + } catch (Exception ex) { + Logger.getLogger("Minecraft").log(Level.WARNING, "Failed to teleport new player", ex); + } + + if (Essentials.getSettings().getAnnounceNewPlayers()) + Essentials.getStatic().getServer().broadcastMessage(Essentials.getSettings().getAnnounceNewPlayerFormat(user)); + } +} diff --git a/EssentialsSpawn/src/com/earth2me/essentials/spawn/EssentialsSpawnWorker.java b/EssentialsSpawn/src/com/earth2me/essentials/spawn/EssentialsSpawnWorker.java new file mode 100644 index 000000000..d6e34db55 --- /dev/null +++ b/EssentialsSpawn/src/com/earth2me/essentials/spawn/EssentialsSpawnWorker.java @@ -0,0 +1,56 @@ +package com.earth2me.essentials.spawn; + +import java.util.logging.*; +import com.earth2me.essentials.*; +import com.earth2me.essentials.commands.IEssentialsCommand; +import org.bukkit.command.*; + + +public class EssentialsSpawnWorker +{ + private static final Logger logger = Logger.getLogger("Minecraft"); + + @SuppressWarnings( + { + "LoggerStringConcat", "CallToThreadDumpStack" + }) + public static boolean onCommand(CommandSender sender, Command command, String commandLabel, String[] args) + { + User user = User.get(sender); + + IEssentialsCommand cmd; + try + { + cmd = (IEssentialsCommand)EssentialsSpawn.class.getClassLoader().loadClass("com.earth2me.essentials.spawn.Command" + command.getName()).newInstance(); + } + catch (Exception ex) + { + sender.sendMessage("§cThat command is improperly loaded."); + ex.printStackTrace(); + return true; + } + + // Check authorization + if (user != null && !user.isAuthorized(cmd)) + { + logger.warning(user.getName() + " was denied access to command."); + user.sendMessage("§cYou do not have access to that command."); + return true; + } + + // Run the command + try + { + if (user == null) + cmd.run(Essentials.getStatic().getServer(), Essentials.getStatic(), sender, commandLabel, command, args); + else + cmd.run(Essentials.getStatic().getServer(), Essentials.getStatic(), user, commandLabel, command, args); + return true; + } + catch (Exception ex) + { + sender.sendMessage((user == null ? "" : "§c") + "Error: " + ex.getMessage()); + return true; + } + } +} diff --git a/EssentialsSpawn/src/plugin.yml b/EssentialsSpawn/src/plugin.yml new file mode 100644 index 000000000..de4e39b15 --- /dev/null +++ b/EssentialsSpawn/src/plugin.yml @@ -0,0 +1,15 @@ +# This determines the command prefix when there are conflicts (/name:home, /name:help, etc.) +name: EssentialsSpawn +main: com.earth2me.essentials.spawn.EssentialsSpawn +# Note to developers: This next line cannot change, or the automatic versioning system will break. +version: TeamCity +website: http://www.earth2me.net:8001/ +description: Provides spawn control commands, utilizing Essentials. +authors: [Zenexer, ementalo, Aelux, Brettflan, KimKandor, snowleo] +commands: + setspawn: + description: Set the spawnpoint to your current position. + usage: / + spawn: + description: Teleport to the spawnpoint. + usage: / \ No newline at end of file diff --git a/build.inc.xml b/build.inc.xml new file mode 100644 index 000000000..2d6c69944 --- /dev/null +++ b/build.inc.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/lib/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar b/lib/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar new file mode 100644 index 0000000000000000000000000000000000000000..5ee71d2e349cf9272cafca15cd20bf737f90f97e GIT binary patch literal 17873 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 Xg?{=)3DLKk2wUIorsm7**RA_Mpu~yV literal 0 HcmV?d00001 diff --git a/lib/Permissions.jar b/lib/Permissions.jar new file mode 100644 index 0000000000000000000000000000000000000000..e2aa6520b87e6f321effc5685232aa134d1eae05 GIT binary patch literal 32227 zcmb5Vb8v4>w>6p_bH}!A+qRwTIN7mn+qP}n_Aj<=JGsyMo%7vu-gB!?)m=UMkFHg< zx~k_`v*(zzTR|EG6a@(KpQZw0zz6i-9uy!@AX!lrL0U;UF?v}+IY}{5WfeMEvF`~W zpaHd23{AO>blI*TT}4Ue?0Vh{Vy!!NSIj&dAEZ(J@+C*K$Dt z!$&TYO*X}POMJz~X5nnnMOQ656FnPJ3juhmtIR4)z4R(yHkFiAQnU+A1ndh=&%KfW zm*NuQRrwR%r;D66OdI!j|H~)$<)G{B`C$^uPu8k3jB$#!t1!XR^-{RD$r2)ZiQv(? zwOGhN!u3^I&!KIDinq#DgxFYOyIz;OYZ74={TVYUVg-e3e-4%;&N!`Vy=L_ScPaQM zYz4QULH7x3bM2&u_93t}>>kXD~0JR89l-sOzcdy)<#1V85!^Zn?-Xg3xo_ ztJjQMcJD$$IMH}n0NjxU`^F`B!H$JNXyr3>3+sX4z~8i4;x^Jp z^OqijY$|G%A`mUC=GOi6?S4%RwCqU`ANJwLDxPW$_MkbA{kN;T>+7z^^u-(8U0+HB zS+0jL@Z4j{1$6KJEdhdm1T9y-GP^(O93NpXhNP3Jh$=v82=i`eolz;5s8x;y6EoK+ zs*DkmfKN_m5R@!*JQs>du?IMk{c$hX(iFMn5QE*x%kC77? z2xuAPf1@Dk|CfUQ$vt&#J8X5#?-&wGQqQYZx$F^_gOE+CNwp+47VAqA*#oja``FHQ zNTn7XDeU*_fSOLNBc(jJIHC4d1u0}Y(q9<{A)!gXNG&4Uc^>`I|A2#I)G+tS_+#R^ z*-pF8)L5^jFwYDD)_$@ce1BfPQk#A6t}mE@t_NLNf1v9Qh@*Ggiz=ScFh8689&Z=3o$hRjLvfmK5;uuj01)%-|ZiEmJ>BM3ae z{)X}rGcVc7Ktu^8%w7-Odrs0OAJ`6x!MV~SZSmJ0@UDt5G!ml3>8RqqYI7gFpzNrzFe^Lb z4d342hLpkL0=w4v%cs!fa8N>RvQGDqo^t6)ty3G)*Ufd|QR*jGP;&9a@z&LUX;n$0 zP6}_`rf+zu#0M~T+s#$hO#`! z^*b+=@)5^Zc{fHRxGn7(1RM?%O_~O|Na)@(H|8Z!6=yo#WjRyfYLlA%_r<9&e`lQn z4mD`a3aJM*CGH>rC8MSRUJ`rK8rQTAOr)C?yXEHX6b9c=jZD^R{JM2fjt2*8$Ct{v zv3RElcf~AsqA3lDsOVVJhXt6y;Q|pP@isiPBN>J29z6_EfmswWoaBp|PXH2GSENW>94gIvHvHQt_@VS>O4szO}Ku9*spk;;mY&IU# zR+lP;MvN|n{zaNlOxa+Gr&vJ^t@v&97Hb`2b$`CjB%3o2lwRd*#&%xzLEO_|zA-k^ z6}j5)R&cx-a|-Ax{j;c;#)dSO4!pc~CdLzIo?v)p9p6)$^7D2vjN}>qiUSMx?wA$) zdT6DkU;Lpl5z2W_YNgUGmqV77VQM{M&vbmX;3i_$eq2UfLGk)avhhQj%1Ra z8{R7&#rm6swMn(kuFdu1V$G_mcS-GLCZCQ}x% ztV4L%tvXaUZI|^O!-^8M@Cn0p%1+EBH?(y6>;o1sEAg=aOxetVLQ#AF@?V^ zfgyyQsAt(o%(NoxcrycFGGZ`aD=1dqvyf&pyUc zs@p8LJt=Ot6$e73sXcEr551XNK(|{Rnuk8vHj&+CZ`)9cHQjroGK^2I6hlxZ#C`xg zQjUH^>QFU8(DV^@-WtDJh%tfqu)>y}!MS2uH$~3LTsDV1ZFl`gYLK28B6vwJd--y~ z@t^9MY^>daC=@CKp;_s6V*P&_`=fcsk$zjKr!QR~QDUad&fg*N)d6t`)D_vL=5A^W zyl}2i=4cLakXCZuqd^vV}8J(lewjWV!-rQRG_ zw3m`%$0jk{f03@xr|PcQ>3|`QQpka>@Xy*2H8^17U%=mVhL}qBE|_g94ICV<_%hP4 zHR+{$cRKo?ag6|brOMYPT(P3^>XRMAVG7Tm23p}IU12ZF%N$BKyULt?tj&>F>cUBB^YWQ+z6w1bb zfGf53g-?TKcLr%x{9s*|91%y-G@}z2Py$q(O`cOtl3dE=z7YAPFPF5f8dos4GbQ#$ zPX}O?Uy*r&a_`xLat(m^&AzvbB5act`7lpAbAq2?>B`v73G-v)B_g=-PbNyeVCPvI zt<0mVSiOXdQi6AZHLQ+)+&zVZ7xFdNSYb@lHzFT^zvJ5M*Y)(W{gjV@T`YR6bn8uN z%RO`?+2?SmJ=b@tl5c6?W>ao;PEi+~dq}?~tCx>g3#v2PtKF~kX%@ciSvP$|uY6^% ze1*Y$rL%p+mwaMB?jSCQ@$Dgf_iL?vM+`o}#BbH3c5N3wZt8B~5AWnT+%lm*BR_wl zPj2yhz<(lV=SQVqb0_Bcq(o_t9i0sL#N{8datoEIv<(dLOw6qEBRmSVrGhvA95cLOFRH@mhp1<8r^m~M{Y^nRUe(lz`rzQe-`P+iJdGqDWT+$36 z+gI(eRHA#VWm!P7{8j)*m4e(+DLg~hH*s_{F#E6IQdQd(Srz45u4aJ+g@^RW6cIr>K}iXiwpGiYD69yKc3DU?yGWSp z%85*dYq`yI$=Zr$Lz}7A2|A%Rb9O2vnJQ@pfaRgCJUv>D)#8CBv8R#-Kx0l;JS%Qo2jH5h@Fm zRl%fX;O2YNjEhyxP+Mzn==rtjQ+G>p1blat6zF-%n z84)x54FYYmVi)i=S;A`C)^wYowOS(h@}-+CiiXmq8|eFbuNJ%(3B8@)Z@kJRj)|vO zS7VT5@TDS3zN%=aH%J+xTROFE0*20_fv2<*2qtUY_lq`q##d1ynH$U4yMx)swn})w~UhPN5LokR#Of6|J2ju8hsj`|?f? z=jH&3a#5Oe5D&%NJ#S4V-<+dHp$d8G(Eta3&q!**vBdkdMplj2VP5eExG*Dh;vFM> zlPAjt3o;Jc3G=+W$VYF4JTwA<&i$hr2%O?O6L8Vky}rh0&}!@>l0a4tV?!TSP#spJR}$s9 zX{*WD{fON=8rsel+Fkz{?VSY#59pbA^{7(w8-Bsk*fRt-`P{;0T5`A~O=kq#)4H3L z*`u5%$tqq>UjypA2uCM#k{;svYFhTtx-j|x5u%((jr=Oe0x<1SxYIzPU||^Ekg7%{$-VuAm2DX zj>jf`*k~0q!N>M>&yk6K7-^-K;?5R$Pm)Q~NmYLwR=H?JJO??lWxpIj8QWjk{ zv88%GL*?zLc4kxDw5OiMO}5h!+`5qHrmj~qO2U^mtClvn>?e=1QTi%VZ=H@iM&)>^ z)Hv}1do-o^ilaZ}LbUs_T#{*fFqv!5>i5QSGM4jVfmNc53fEgtw1=#x62yBr*ne(I z^bCQvz|5QK<{@zLIp`j4PPf3=&LnQsE!8mmf|}5G8e45cSOe?sbi9ZA>l9oE;3DENpG)h5!3V!obGZ%EaM6^j5Nxt~9nF3NQOwhv`e z+i_;I{qkyS8XqY4Zd)|Gj-4Se-AK%Rs> ztp^rlf=^#3pm9b)E8ifgPgYuhFD*332!i+`QsBTt&Gjr(98~vEHEy>eXEkJpSPS(O z$q|`kqd#U`07%lb;QmV2;vD~QKRBR04_f*-u(3~LccSwNV?g7A?qpNsT7RkYr$x^U zf|th(jALVL=F}&0(@i7=aWA^>U;KHxcBvVl=+C?2*M_r~@?0k8K&h_(NhSvA3NP9!tMxEN~{g>^{48SNde*poZ{F|EY{{Lfp z5ff7bXDg?FqriXKUZGQNPyit-QudOA4D}>XVIII39&RcB1 zkpck;48KpDaQQb93d?EHR`&em=CzMkPd7-K;jCcn9>=^%nK9jsbDDW`lBTjfaWgdi zZ~}X9`WG4QD(pcP|9#yq6^!k^4oOHEgko|-jU*E9l2{UK|ED-wx>UtwQob))G7CEF z^4@$vf6keTTOGsWUY~RQ%x+PoFT|hK+xif`qjr`34oV}%t@}2F>P|Vg`rTx!J9djq zZcXN(2j43ZqqX2;%0Tq95~-nNtLf(-Ku#0)8U#y*D7*2aIbVf`$~-U%M9>U3EG&8L zEt&sMz`P?lmNJfWHJw$0M-n^K8#O1eRetv^+gSsxd6T)^x5%$tLjR>`iJ1`&UReGNjGdgJGpWyH$M8j^y|%3P$d{F?oo-=b*ot3 zU=VR&&`MZEW$OegT()U>FBh#H5|u5>kMd98@=?f`r#$O!MlrS~M{;sH91CYv;WmJf z1>nG1EvPhru?NR*rQ!Sg{7xLQ=tNE)-D1Ap4v4Bw=t5pnbh!67@ErjoIhijZ$Tz^2 z3{hVo{mt#gFg9KB_L7(<`S!Fu_cww)q>IN|iI3J`G2Ny~#s;2Ns=G^cdWZJLZ^Dvv z0VSnS99E_4PuN$exNyRhP>NX9oToapBBzgE6_vG}>`XQjU4st|l3Zb#Sp6qpr|&$U z^a#lxCMavye-cVj7UGM-jCu7WX7UWqre;vQHzNfop*5@Q*%Hf zDPvu;SL8C}k`RcDWcp6EO1hrpkq}Sz^kXrsD0DPzF*a$@nU@|_HE9(U@5ZM`HTo-l zxA2ZHdr@LOX6jv-#yQxGzwdim8Irae_mbJ`SsU+o`Cd{%l>^Y@0q%u^>qJ%@z9{23k>wT7eWX`X|lFLX(gRNKH;& zOE*lK>aW5>(^^}IS~f4Y`0PWVn#)#d_zOw&0rnxZB9_jheomvfoW*dRv*vqIeP4P~ zr&nyooJJ5$cf4=59d9^$cQ{|N5-We&?V$Rkx=IP<|M-lZSB8rh#Ph1ju1a9)iUF$5 zBrv|dOoalq|ClbWnk^1Rxyes=>nbuQA=wRA;rY7@HYdo58nR}chAR+_&C66F-o|8+ z+F9B`qe`#CKV~M)!ni`AfQdUd7bEe+QC~X&Wb97a6C{7>k421Hhzv!*plsZach_f( zOtG}0G!;iBt(lEjTm&elPeV2CNTlseRiJGBC0nRh$&{R5D=bLYgfg+FKnoXFat77Y ztB)>W(K1+wY~S2M%3lte&%Vz`d0?GFrWhZNhykNG$iZVak%t7GASbRFlePQ>YBRql z*wYt9pxRpU(J>{`IgiRr>ZvvsX3dO*_;w}pcae+|O(R=%1y1*1P>E*Y*5KDqw6Swi zp%8&@E~0ei;}YOLV&;sp3{a1=RK#VnmNJidgqnEuln>r&p}|N;b;X*E=*@jH-EBdf zVs#y^4b`YPtZ&b@%MDZZOw6S=C>^=c0-CwOKG#Sos_N4=d3;G0B4sWgIbXZF*k`W6 z11G^_P>sx(eZ-EIYqjlUO4ahVJD|(8Y}f)D6?-gj~CZcEGM^h)x*4T-DHmOL$TlDJDGMsr_xc5q#-q@UThiI^(e7Ke3x zurC4xcP2q&Mb>qSfRN4CWE48oz#KZ*A{qYSd^rG8q^^Yo52JF@BaoV{Na5O`e4$6n}TrzGt5K5G74 z!HD$Jp8Dvf1#o9qtv`rIG&?sMwpqt-{45R3`grH3*c{DRGN4AiMB-{%lqNj=b;z0a z1nVJNrsGv;ROHEwFX_&y%mr8#=XhSq*v&=Ma`6znVy+UA_v;|0WUjOD7A}N`KgbIa zZ(|ayj}gDacu;OlHfMd8NvADwDP9*%fZvmZlZTud-_^+ti#tIhwkf0eu*W%`Hrcks zQKq7D$mJu{>V735yaxt-|7}N!0OuME+yY(xsjSq$(8Z+rJ8QXlTCve9Uyr#-{3uOwut5;7-(Qyhd&U z^8KwJ9fRLB zND#-dG3m%>xTsfq>q?71SlNZvDY(-u{#afxDa1B9uBOWNMpgrUEz{Yt7gMTqiq?YJ zULeow+zkun9@9&E)YUFwxP0eYV5Ethx`fZnVNxk<#ZGGQW!3j61;FUH&_#5lDSN-~ z>`!`tq{M}$Ha_<2Y=>Hr>iT)zZN<30k=e{8OQPSBqt*y=FsimF9m|6FB#GUO(;rT) zpRY9B0AXgLAhQk7+)SWVr@Yv(k~ylsqRx39f6SCmGbe2!-NBR*#GwLYTp_;O|% zT+N!7YVftp=|Pcx8&M;ryJyVpDVD7^LEF}qq$YyG);BX*E@-MG44SnR0A3{K!{(?g zRLn0Kru_`7F*Lbrh2*r__itSgmns<(*+5jgooQJr!oUyl##(5Tys zMOAIQ{ph5wzTq8*O*N%smXHIwQ^}$m+vYDtAC^N~idVHT6dM3wic}Y#vMqcZFtM)M z!q&8}H*75MCR)}C96IE8A1&Q2dDGV3!+8+s`bt~evanB!3$lvE6Bvv>-&1J5;VzdW z%6o<*Vm2S>6{lr{uqT)XQZ`1q$}M->#I+?{S@5?Dj&T&`L50NG&V<`~t3Ns0s*;XHy34~Sy8x2UD&GppJ1F1S!e77qfiOzo)QeJO*&&- z0Yl^-@)(VmB?tsJIctL>X!NY)7Y)U`h-pl(>?c_0ZIaWTCQFo9oV6$X(i4CmalJFt zC!CRp#-!7x($Ol_CE-YvH0z7S#x?DSeKu};gEkg##7yIuIu%BdG~})ef=O+rzyd@6 zSYO!&=_A_kWjqBZ$u}|f2y>$N7RamGp~`2$S?R7VtsYg?C^VvR`ft;GRZ;h!hr>bQ zsHVUqP7xLe$|nlj0iz^dk+adWNZ~eo`Q2YGq>+o1HWt2Q?=A-%#(R%G{`evg*=;SEZPmn~M zHdTF7(9bw$_+~@iz!vL2FyQLmqu!o4DyQgi%~)u+ZEa=!wlu^zw0k9yPloPC!w>2}x(LywMb^1jH@g%0-e7FUk z&>LL$1hGRo7Yc_-BP!80{=w|RN&~iJ=^|BO@`9mgpSh};>cSzlO}z^|dwmN9<^=KT z%Ebh%eR<`G)Fu2$Vfn~RzbZZN+>3w)GVNWR#y*8EnS*r7j{{(1GjI6D3# z+a3R<+npS2t^PAw(}D0(QC;Rg=^mdlz6bom>_9+NLXAU0I75O%6ci{(B24cS7#l+Q zwNhj08b93Nx35(Q)A$E=IEUH@)$>S_g-nM_ySyp^9!$OmKciuxRlsZWZ?UVGe3dWlfdY zMBOwM+!FgA8g~zK1KGU%db+Ws0}MP9K6MBID-U5@^BA0HQq2UMp=xMat11{40jv_I zjde7X}6k)9fnG~8)uyevA#jAyAYL}2AMWsdx z4fMZ|izZIrXbizfhjFVxXZ^1NF)2#L)QB05yof+ zNj9Dt27CLtDsrb*d+{h530`$@zcM@7x@`yP3~hV%6=~eVTl># z{>I=)9B1Xz!F&W5#FU3z_|6P=!DpoA5F@}vI7U-1Y0;sD`!z|x*TF?^&vn>pK)iBz@U=u&ibP0DXtCtlHAd#XfV zziF<6!KI~JQRHTn4Cx167I+&>Y(F^YIbb)%GD66(!8(uBUoP0G8ehc9WeF8LBs6Ot zi+RCKkbjpzQ`!5-5TT!G&+~^Ndl{+Ni`gCoKq}&}yZQVC2ILL2 zyiTZXtKlA}u`;0?OL!|76*aKSZ|10QXui5ebIne;#_)^F;Fbgyf;?B+`DXEgeVUS% zuv*gH1TNlnYy{J!koxqHJG*)4*!}x+4}j>~y#Z9|O0eim*p74?e|xNfW0q1Q?MJV; zeYW~vmR?Sztl`VW1A4AlkLc?_0l*3+@%AE;EXVF=wM4moa&--{PJ8=&LPHxOIy+W# zx&!n&`56^;cCn)U5u^Y=KIr*w@GbH!VmB?Lybe8qmf^f=;D*I@fx&_^#Z@)H7q~U@ z#sscT%$&kaK1BL`A>m(1BUuqGZARiNUQz{Q4U8laJT~*rzUe?2CRCgtlvu1s4BnWY z1(2oae&mX{9i#@9K5su4NC{U%+Y#Y9Rrz)aM0J2N@K=vvAdk`94j8aUUISBbP9Zwa zBTrK7_#Jq+1igWjHL>C7El0tXzDDJwG(9o+iW)l+HQM@syMbsM8%hVT@zk_0SL;#lJs^q#Y_T%qvOJH9wJFoyrIc_K&v{O9~cr<;AN-}uwIV$CX zw#WGomQ`tdsC5Uu{8YaF7pbN%2QWD& z7u98U<2?^?kj1fcqYt<|h2=Tz=fwfX0` z&m43(3%x6_3&fOIIL3OCvDCwT&HodW-NAa_TZ00lGVw^@3(1 zsYzotlA}fg{-<9!hsjXV3uW{38YSU}MnVyETq7c^z$EC;W7i!`Ni`-=)-xpqu)$Ku?%f#p$4sDSENw{=;0s1 zY)~b)=6DBtMs{8nmNETC#FC{nbu1KWQS5HO@}R({jZ}p3eby+(^kw+eW%47>_AyZ9 zvCOB?T*&@@(r`IMOp;PXI)RNIn5ujyk=`x^{R=^^*f3MHEXs#m^);OY%!9k>JTTlC zfYmPck@?tj2{MI^{=r7UR z@nxY_z{u4gQU{XuuO;xdj1cZ7>0oOAm`tTrf`@=-tEE!&edvaA1ID5p8Fy1mSa1fL z1@t~&(bPiGK`VY?zjvgzgj2ToLx?&DZr;~m;k2cb;bviDm*hjZ{P;mLE;rk8@FMs| zP^a1%!IdVS!b!sxR(z4W?G=afj7XrKWQ3j_yI>BZ{``@%ke8^}K90oo&F?q6r@4EL za_iCn1rmXubyLiPfspD5C~lw=QsXsmL0p*kr`3z5MY%dF%W)JVNu(@31n*U)Y#ZQ&ewY}@d*+6#NP z8L5XOa)?og$M)7PanO+J!xK@kihG>KlaS!LWmq)FRtN!1N>o6IXMmA-zKj6!t(28W zl@4wOb}3W=GOD^9ihZomq`Ly@u!4f$Uez!h?FJT6eDz=>dl@l28j^(+uD>{}F8Tht z?G?zoLnjV}?{9e$rsJSVj}*rBr8Ljwv*k&W2@^-nmu7e)3);wTqQUl8+PI8UxZ8tY z|I0&QFA>rdir|ldeRq?16CUHMq7N)5a`K~-JyJyQJk3<2or1lwy}jD1!L6JRQZn)- zS2JDIyFALzmDSN$4U+5n(ml@F+Tub#kex_d${2NAi#OvQ-tflcY`AhP58}x7T4h#} zO`;Se0gBJ~uJ0JPtRqc@Bbi7vtwvrp2Ph#=hGTXi5y z-?tV0Rob{-Qh%`m?nV25b!vq7o$ChvjNktjN}`9mgTEyOk=~!kll!u_OGB_pI>`Y+ zvkmyz^G*DeAA1Y$&%HM@)eDb{AwLiDM^5|QU!)-|Rt0EY3LB_@ic_j(?GA%n+s~Qq z7rp%P#rA^hrqlXie0B6uZt7uvh4VqyTRgRExEzrfx4OAP5nfLaoqHSKrFSnj|1!M& z=mKyq0VHHrEpO33*|e}QKhb)lg+;=Z&6QCZM@??&z7?7_!F~Ji4WB{plB{m=NrY*K zcQ1;xv?}`9)2f{US01A8K%}~|=$4H!Kh1h5_dE(n_R^KM>A-zS30FF>KJ}IFZNP8X z;!h3CGs;cq1NBcJL@Q(aV>7FJ!1=ue{I$Vo1&lnO(Y`d9_9+()*0np^BQV|gT+Y=q{bFfBS# z`2ehD&tAvvc+A#w8gCP=J+FguXJYQ?T26#-7nT^WTX|gvOh@U*;KD#Pc}s`LIx}V`A7wMKTWxrlIDKi_9Gzn%s4oG&3?)UGQb6r#oXy zM2~2}cSR1yMTLQG6#f2C;ED|r+}UAC5}PBLW`!-6vqYc)=2gUv%sFNA8qEt9Ya`3y zvPGClNX(@B>ORa(LFwc|XCyJGr>#pgg^o5oEmqN}=$p@S**zx;-Dz1u%d5hSya@_MDROp9c|b|jv0yls%OP6We=MaZLr39?)pYNBzv;Y{G8y6PXuTk0^6tN2@*A}SoybfQUJo~}5{pAA`1NUGRp0;1wX!eZx+?diWj5Qxe9_M0SeD2leM4^Q76q;V zT{Eyr(E9O5%Y{6Mn9!;>q-+q#5q*OpYj%yb4Ary@;W+>$aQ)K$#hq(_Y#4@Q7zX@f z1GXvy^C{CwO*VX*PUihYbL!4EFx<`tNRMzTk>%ID^g**-q``|6O}$mSP3uThYM5|Q za6vAP9Ia|F?J%Qlzn(yqe@!Np@CYU{os&%x?A)CBSKNf-Q zEvz<~$4pGx=9@WZB$KlwYN4H&eF;;1Mt}*~Ae)GH&=CCYKV)=|mrLx^J;lyWRW;?? z%V(L5xUDeLsmy_@_8@CMPv5LKX@-H8m$TR>^NoN$;A54pW`0@h1(XxRvnUoVWt%b_j z*%+8=%2E2VnU@RDf90*9muyO8nPfq$KRNX9O_&y8B+h~0G-2n!X36B% zo=$@}$vXnNg}LMBxjg-Wr8QWg&0gcsGnip0a`aj;*AuIQ-0ty`hshHmnE zKDq4pTL85Q>u9=}!nQ`(SUd2vA%+bA_sD=@RhoIG*%ACL*$QBH!oG0gb}b>}%evl0 zZ1NwS6U&jwd=*)rI%|`67B(>J9E$&Mo>mrJrwo-*^oC2JsFPcuS0m#zu@D7VlKE5}S;gE+Be)-rfvNXw$LW7oK-`Fw&VQD7*Fh;c6UibqxE+KMLkC zv;R#&{=oE&j31H$PyRr34W9(N4Z@D&*Q0X!%?mF=4F}mZ(~cn=A1l9B%0>foe4qQj`)q*UUJht+4_=BA1WNI^`=r~FOax;#^!4E5-5BL68x+z|0 zn}X@3#d7%Y>WFCLL(6UaG>>_s)PzmCm+J=fFJV+*aQI_F4E>UXrc+KS6S5xnLxMt}Dt!+i95&B)(Ax3deL$Dcei+eJiD7>R7~>7@$3 zeQKo+wyF@R*-$+TVWd=F9Elj-c}>gXrpFL3?x)Ah6>&07ojCm$GThI_5HAa)BN9ay zn|MD&sOou3!*Kq1vKeZkl}2D#DwEKr^gz}tEw+CfH_38tn)v7+`U?R|umjV|n@ufz zQ4;-(v8FdzS5vyY!Lc?V*}ZLPzZUHmk#X(hnjS3~$Uow)@cu+8)Td4lQ%`CO{8X?O8$N{ z)uW*Hb8vLF5AntTXl~h%|hB8Ex{HofE6C=7JY&UkWJr6-y ziG(lqmmm_3PZ}YRj20%L*&{*`6j$JdFJMN{yA~Pn#r8ju=F4z-FlT$kxb8PXU>&`u z$QdIi^aFj>s1Y{gN-Vu4)frj25BFl0Kaka#;eJK=4v;_6<%#Vboa*ipc(4y%POfai z(JMoB(7+xqwLor{2!-8;E*dXxX7+_RlL!9G^EZWSV_ zidQ5)K&54>@zlZ7fHFs^yfZ01@1V&3-G8*i~A3-T1p8I=+ma&9|DG#Cje z!YAe?%Dh}|d}C?yvO48j$xj~OZL)30qYZp$hHw8>t%6tl6^L!(&XAygyr3vnd?DE3 zms&_K3_s7=1zatYt~ivOMX8&UKqoI5D%5{CYew;XhWLHj_*!Ukce1mmK>a%wU7^*R zB_=^M=5U@!He+1vP@8!rBrN1h$lu$ExcJ5_B{V1UE719SCL?~6e{jd0{ps#@eEVDY z-Sujx{0HycxaKWb>f=Xbf5$L;yitXSPnv9k{gy_qk33_k3$rICobqaNNG;{78%FEZ z3b6+;XENM9t@dpBq@6r;zZ_;8Kx$KR?M00{(yB-Zy^81s5q%WB3ZH4^YD!+=$U$W5A*f@W_m&D|R(~`r9API> zBu$>GZs4KXJd3`;1zDF6knC)F_sYvuf6#UmU&=uJNPcqs#;g4rV3^DAPTrnr$0E@} zf%#TIDQ`*_e{HOQWz*tIFNf~_CgDm~|5>n);v2yS30mEp{&ud3bgMNQy-qga4=EYZ zE3Ob(*BC=9c~6i^KVx5Wrf4)(G{Z2$n>6#Hh`uenU{`1CCO$k$5+=N1B0&9u8R;io@& zRWrVvZ?&wePaO9YPxhmg!49Q;#@imf#e$OjQ|xe%s;B@SW}E@mPA5DWimWQ%lT}M_ z$7$7q^CVK?6{()HpIqt|ZcW44r@M)^#UsiN?iP)Xd93Gw9~cr70+p0z=`gdglFlHn`0A0up?A$(^iSd zd93Mt2hxlPw&>*jljXsyhhP%}@~HLMHtR&UD6Y|4YcoWZ|G_X`{pJ@&qjg8;j)^Qv z_Q099Pwv)Pqrg1+>_z2gO&PX)p`6_TyS<$!jF@Mp$1Qi#;EmF+-$O=k-Wk*Qb6($Z zDfi-bd$Hy5{K8p3S#(FbPSn1lz6Z7T0-qszhd+I!+oiK_;%5V@_c^|)4tu&2!LFK& z6q(yeauv$(RoAq-9HBW0HrYW&KQ3p>HW{+$+H_qg>Dx|w;)?K)qpa}7!VLOKiFcDl zDWzpclz%yrv{-^Vp;x-%5}xN#jucBqML)^*6+;v0uiG4CiEyq=TZD&QY9etVKKDt> zp4dt-u)=yK9Uq9uGbNbLu)A|uZt#eUy~{b(x$J&@Q$@C0gdb+@r$uIZIVU05942gE zp&Mv(W$d}4vOK8Hf0!(2f`_*ab=tS=z<^v9dPQ5r9TymAAw>gtSY#gnhP3JD%_toj z%%@7U!d!#q%A`lIsnlj|Iw_=)w5I;XxOtKw2G!Mtk&$b(aZU$gWs;pORJ6vs!+cSGr(y z7e1x3VG-@bdlgtchBwTUr$pBX`AHXq5iR878g9HSMp1NkAwcDgebs;L;&|oLf9gL zElOzJj!T!iMOAqcmEm8gmOv8{WfSO+7o_VWjF`D2!|B@%`9X(GK(&^$f^-YoAVDhYTb1HUu(SV(&|mZoNVNhU=efAb zW@_-_ugn%bTVHGGT!1CD0soPOM(XAkg`X*-Azdw!nwn175l-n%#fu|d>fCmE<74Ef zs)Xt;i!#Qn)CD@F2Yp2U^)7veamB=?*Ew(;R4nza1m;@4DAH)5M8(Ru1pqVe6e{gB zCqE;rsGj42XcTe6z!6;VkU+rF!Hj$hCvHjUyK zUb|)JsfhokAW*kj@aa}b($@bDY%o#_!p;o7IlXLoIsF?n({DFh;Fey%ju>GR6qKEK zVB2UTju|C@*-D=kGO9z+AB`ldCCdfI6w0a+$yrN!)&Od@wHwCHCqLi1n79e8ViB*- zdWNc4I{E&IYI0?%l_FWGdQ5ZA-15YlpTM)M{R)dFZqBBz3{KL@!OIPLSW#!=_rgI? zDKGc}|E~pps0Dto1%Ba$<`eUtXCB@1ZUJ};`VFCB7qA_d=Jb}z>87o98DI%`CF@*$ zyO}>dxhE}WgvvDVlJU8nVX68XS$pSj_ZGJ6GHC_I5{hIpiu8TgClIuqaLt#?_t+a( zNinO{4E^Kq7SHBpSeLjMm$?k9o(!uH46EV{tD_97r3|a+46CUOt8`gx-`30;k-(Lr zm{tFvxVeA#!^!_$$pSbmj8vBho9WmRqqMlEcxK(Tg<^#i>1gQ3W4NFV!1QV-SRdRP zi5_#pENfA){T4r&1z65~Jk)Nby5Zsr27F8NHsO~e^oCmSZv-scMY_UIMS@q$0G{)O zy{65!F`QD*#rU{8wM1AybBta6@D$C)on8Z`VYpgTIH@W=ndCNvb(^~v_06!VELjv? z*M_o-E?FqqMxMpBy*8{ko!O}$YPbkW@lek?mAsD=Z9f8r-;q?kMu{dAH&V4fbdOzG zACTvzB)4-x3|ez!x}ETkF2Lac3l=>&f`q(@HGoE|GxuaAuVjb0e~yjNX;Bvi&Xf|r zQQm2WROC(Jh3-fs+)j}4r?|3JwBKw#IpZUqPuLq)oo3AjPyoWYE@fHdU= zmNQdMy~_k|#4jFku&q|8S8LSkbZh@~>h-f#pjs7L)upq3X}qaczV2?VgU@R2PIIU2 znmjbl1C>6qzlgKjI~L>r{<3dda?JPTd!#RDe@A4?KB4@-(Bz6--um>aGU`IGhxJ&T zfOhm@-pY6rEj10yUsIg3qF}-PJuL<(f2Yt+$|+>Y{0|sem@b@{9G&vgXjk(=zNh6@ zJM$1V>7lce;DDfv00-L(7yv79qyWDgYgMJr;XfT%x#(5TY5arfS`G86mO02df>7H` z-k7-C3ZZienDVC|?4tEZsH*@|@L)=yD^Nc+)I3=bb7r7*nu=xl60t9o4nh7U@J$b} z|H6E=A9shU0)`oQ@QR9p+jfBMw_tGXR~ZBRKX?E8{<*ym1%w9R@s5{0dz1RVprV?x z#YNRqSKMQyrkeV?N{U2AOA%-;R;UKASQ2XX$S7oA9T?ClUjGklE*tE@`79`z#}>~` z>@ZB>HY9dwn#iiey+V)PDeHrS<^}tJBXA%?W`P{!Nc;BPP(V|o{vW8?=~z%3bW<3_ z!ltvU*xqfRp}^ydY>cSOSRT9L{J;wJB4p@-PSb^$rV2GuuQyx9G+5Rz)ZB>wF8l#8 z87keDGpPw+@(p6D%%5UaIF|1fONW0ImQEL^G5IYf5nd}p{;kgJ+clm)^Q2(LyV#C+ zz6t7V(_D_spLJMf2aw91UCP-oD|cl0`@j|`VZ4Cq@+aJJW$V}15AYYez)!Ex&ol+g zjgW57T8Qvx2hTm0eX`LCoR-yf2mNBr#y{0ghQDKMERn5O*MWbv^VZeMT=-Qy=Sq}5 z-x&)4UCSk3O4gk}{%m*8Tf}q6jOGs4ibbKY6kFO@#%lt3VSxUKhXyUg-uALdTL zP9KmS-G@u$1aFeLE zR|+q*?@*=GG@13AQ|8t$UAgsuFKh+MTk{q-6wY-ip7>BN{-4Ia0l3m&TX!a$*tRpV zZQGvMwl%TsOl&(7Ol;ej*tYSKbKbp^IrpAhXI1U0ziL;1y}Nh!-)r^4hcoW{%+IFu z8YFfdX_Ehf<~YBrkaZdZo`Ul-UydK&sVKHiCcdsam^jfVxLJhrotm42Ey48?<|35; zk}{LanEF~iV>v4u;njGtv)4e!4wse*Bn2msc%NS{^WLSf$!-$8QwxK=iJ4929;DD6 zLZKCqjQdl3hS%U2&o;`B+|#Vh>lTKt9)*)h;|TJB0I{b#49D(O-Gd65{ejiXbshtF zhfSPuTjAC+Kr)XWZaHlj*afU$iNSAtZOGA_{ILw)Z+SOx@n-cu!IM1z(2jfW#v5V= zj>WPxseCUqOc?s(MSIFA&`$^RMaxGSe$N0$-4%7tgcqxGT8#T4GT;GAitr-HjU#?F zez?3v7dL)5hcQkb&y9f?zlt6wbPMj`E~u}BGkS|Zu8d{y5P;`v{}MT(RhtW!UY>o+ zb|*2HE2+Vmg4vDqwPCFzJP2(rxNa7}NLy>QE_)3S(Tp)O~v*wnIU2w7^Vg)R|4#5|mQK)%flXpxKs3BJ1ii2)Op-H& zU|3ti&or6F^q|oh)_M>WUOOstg0tawatlVk_#4h>{7FhEk!Vn4icLS~ zL<*x!LM3O8{USp7aNpT(@7E9aalz@%$Ox^IAnW=r9)aE8)OK?_+@ zhKC(Ty?)7@IoD>f3j>A9-Mj;pNm<#0HnvUva_TorkdJNr;nwsNmf1w*0uJ|{xddW2 zPSq`dVk^m&G1PAmpGa!jd=^&WZ{n5NyD8=djx1@KNOTM<9EROTUkzf+AcpIILS42@ z*4;Dk@=k@kz`Vyw!Jh$@Exv_94VZq6m9p^uJ64M7-^WVH{CC{cUkOfmN~-b*ys#(n z{cv5|V4BVdXDU`bpTGr(V4(%|;<=y(2qDcK3kS-HxQ9qe+|NMoawyzL(x7yl?0Yzl z>VIEK-p+CM?d(>Za(`OmYCiTRK-M3swrtYtQ}5hj-c zb*`Ix5Ou)@Ofvf7CEw$|F8*^F1&FDw%k& zB)%-|q8kcS;vZ2r`@tU^{%&hqtm77~Q5; z7vR#5-8!p=Cd)#8v}ATD4|jFehFSKc=(x&W0Ce5W(}WZnl~?}GUxAXfOWq|Xl)%E3 z=p!|D+sU(Mv9qgT8~w@BIAK5ZJ?~k3Qlg~6r|+-;yEpz!ytclqU&5B9L({28t)tGFqT|16}Mel{e^U}_-k|n zVk!fL`ozYynck>P|H-1Rv(x;-b6;3f`q|BqL*Vhc0i2fPFOMz;<~}o`=ik}{gfU1C zs@7f2-D%zS>8Bh1-5e2t9#>_NwujAx=l~U6taI_{tq7H+Q;&xAyV`!O32Q==vr_IM z^6>Ru=fl|Ra)BUfjdMs9A=HnU7@msk4@0G*>9>N`>=AzSo$1V*y*Q!#)a}L$(jC{% z;U%y0UjE%n&9Eh2qZZ~U7n5^Z?fjubB*=lo^rUMZz9oBPVFE&(t%8A_KH2AL*QxE% z#tE@lD>VEC>|rZtIY_K6cpgvCpc$4N*wNoXoP0Xv6F;8(lM`y3k9@d2xG>Wcy4~Z z!s`@5Tm^RNb2t9utwA@a>XXg14W;Mc>QH?ZCXcSht2}O))jyb_5ztB2iPtH^>%YEQ zOu7V`W1N^a3p?Xr!*X@^N7_$e%S)&4y{yqSYvz zQ#dlDpJQsma?#N2Xs26uwD-$Xy690-uOqFS0qRBDQ=mH_iU@ZU>IK_VpgB;)Mi}Ho z;O~>7JCsI6Amv0TPF9&tR|&DrZaA#jX`C)Hw|#!!^PuSsZz02_m@iVc-l zs$*MmaV@SkT|&Mo%Soisd0g}C;2Son#wiMpzKO!NX|JsDjE!xPx1~b?H+*U> z=h#{EKo2KiQ|6uL<6m<>+3ldxOAqMSn*qx(H&QF{e59QO!&??iH!PpShOkZ3WsECy z5tfsXkW$EFfI3oZv72dDklHkJ1&)wdw68d=uXq`5dLT($EMu}p%-h2tE?`YC`=bF( z84mF9C-8Kz195pbpJk-{?eW4oU|szXThz3rBZ87`jWnMq2hzi5@VTt9Z`H+XOhP&76BnJO3%nhBo3F^VM=5(;E2(HgeVX74pIzs$B z!_YKm6jCJ>y+><9;tJLic1R6QRgvQ2=T^TCeeGNV1_9b{=Ug~;K8fD=2pM%B61p^H zhsKdSfveQHXOxudz+{YlK8KltEV>p!gUL&1f>RwUNftM=6%|Yv;E^f~{*9d^{A+7F zBdt$87}feY6S*fwaH3*&h52^lcJWM5%9x=mXtmmn_Qx@xSDgBUh z7++PwX%4nj1*Rv)?bCXQ@)B}=_2Ea;S9Zy#Uv-Th%+aYz>z9@YZCSYT2{tvsynwgh z3EO!pSeu^s;YhioUrsu#$Zk&a_6w?%hfg}5iLqt8(Zqf!Wq7aR7aK~B0_Or&2%X`s z6tHk~kC%py2^QiutXOTps~4+Ze@2KTLnE7VBxa8R&7$GzR#-vkJ*8p17V-quv$rQl2-PD>BXHEJ8O+9^KesWciHbdNx*vpO>$bY2P5|BWx0jh# z8d=xJ+i-Dx$pucHHQhDD;;SRqBMM+EjmE_pb&|J`T9o$n8T)aE`66Ro1mNf?YE_!z zCL6hC^Aznp24R`B35TF1liY^1Ggpy5y@cQl4S3wB$SnFw zmIIvRto2K)A2;n;A4QZM(nxnA(gxY&ApNd*TlQ4}@r#6DR?#eGWN_ED&`js^aIdAQ zomjHC$&F%c9&tA2GYatwycPt!_NPvAa1YEYrGsT=3DhqocB>5M%6Db~2xCY*p+69@ zGqC*N+#zl;oVWS*GgT^(d!0zFJs657gMTYWoNl;*yd*3b1xypSM&jJbJ$M~f$|al_ zmN$Kh@|9G$XMAe$ZbMLyua5^Nj1RU@8Z&4T68^G?vw>rLC3%ijR=+xfwmSc-QL>W7 z)0-goN$)Av`#YjK{ZO6Mn2lnA@kYiu^)SWpXgluG)k2|^rIvEU_pa}#cei|lJ=65( z8F$pg0AtuPBVh$#V9+xfG8f6A^3TVD1}QBS$_o#SPm#eHr1A-m`OCF-m%U34hNcdI zfs`}hS14Z+&kFQ9Y*8>0OmrodWC>y2Lb`Wazj)@;%^fy}4ogYQTxFy<^BWXggkd{RVQs+HnZ@iA}3k|s#q z_!A9_3)ZKE6DQ9l!#_Tz`E}V%aA;11VI14#B=eHXN7%vB=BaPTTrg11bwG-#2yDR@ z(QL^vS=>|BX)62z&CpeCeCQGTUF4r1ul==AK%;>&Gsneme}Ng zyX{(6y-aa@Fk3lIqir_FaNm}0Z1G)Fuv7!#7)mMbOgY*1C)I#hQRUeNLYcyMGB-*cH)9E>A0t5{Y#hMl7M7?dH7{j4uJyON+c~C$Ju$J}%?yfIe`!jG z!ZMpS2^jwnhW0}VRZQa7&Y)4ssTX{*VRi-5%m$5DEqTZJS0lp7ZNnD7W9EQ(7j!0a zp*TIW5W!MLle{U%MOe*lWW)-iqda1A^d3b)IPv6j@y~^I#gLbomKWx6S1I8Mo{4ry zq_Veg&l=uh&#e^B%KP<&+<;fi-=v>g;UTUY(Ob$3sX7&xofzA0>@=TEOOP`<8TA@8 zd#(8upHb0Ee)PhYsIdmjAT(6DVVd=hU-;$Mq>mBh0y0D?A>@U~1|V(K#n`Wg9m@8R zFc`>wFT88s`h1cfA-6~q@eQ5W+Kd?#Lpr-G%XCPzR$BYpEzrhq#ihOp7XS^`qoU&7 zE}Wf8E6hi`2D4Kj_}_{*EFc?D;flVjn2@7PTTybm80i9!U!4i%9B#Kd2w0mpQOl`X z-N8?Pv~&JO$)k<9wWkK?zg9beF>S<%U&fiWtx)R9aYdEy zTD=zCK9e=*m$T?cJ{}JLqQm&xjy${ptUeR!cs?x6JwlfpTL(Iw2Q*!fL{k9e@t9N2 zr)9BUb~X17h-;w2@#GQFGZG|Y?QZJMgKZs#Me8%GFdY#{HxJ+AcGXu%Ok%t35(kAH z`g3=S!l83f2NqA=A6(MNdz*lpa!{MtK6g?Fvn2-VYq2o;6kU@2aNxxQXnjRIL59yz zeo|{!DEWmWQ+A+?NK;xcg+afbk_#@QMl8L^~N+C*Qr+;(7K$Y}wTX6`Egf3Fo@HU|^xk>wu8YvcX|gbYx$m2|(Eo z;5I@evkF^31dnMWn>QnjZ5Nl<_7q)z6y-?m8UkMw3y5$Rpcv!tzDN$byFtW{gD*H| z_Caut2U?O^6NV}{uQ2HUc6aLIe@R>AzYo+uITx681x;Utr8DTtp0JM9JQJw|}$?SCeX2 z#Zg3LXRDQOs{d54$Ow_xYp|6IonYC{K_?g!JkO zVP}vL)xwwsyPHtL3i-9e38i1IAd`B8(IDi!p_Bu!#J0LlZB|ka=7{F!lVMA9mi9uy zgbHO!EraPR8iz`|QCmz-kBps=)MA8g4`f39SHVW{6iYK~-@eLj=F4MmjfNFkgGKzw zV^Ty<^j(8+uAl6q@`r;p+j=VK=JTAs8kw5==U?M8bQ*yoE)G%YyM$HhxCh~%ZI*dT z%L&z#5em$LN0laj2aM6AxF__#Vs5UnV7G5Nqh^rwW~>b$+@VU*E$yCRaR^>XpMktG zPQ?d{|p7}H*QHS_e48pb&6Wsl3Mp%te)!;Ew}letM?NQ ziM!7fa2GO{zanQ&<(2J3P0j^5Emh@;zCWf$Wnf(wS{5HPjw2?DtF?r*Ke8vm8;a36 z{Imm#@%0~)evQf*EMno7T|k0Zp;0F6#$Tn_SdSUF4#>32TSVDH{*jmyRXGZU=@+8pg_)&i)`s z{$%-NAW;7;JrmGZLCrv`Xekwbd)FGDfPUEWw5|JSn=t5EEwF<(R752%2Pc_#X?4!5F zvCpWp%oa6pArbrTZ3vJqX9+`0vX^`-h&RPS`T7z{%*+qq~W3c8)*}tkyBpo7BoEu0QZgoQrEuIusDeCh9E0!wL zj4IWe?AK+kpcwTag-zC1B|k&!O&?$tZ5zc`e1#h;)WUH0pXd2`tavDSTQ_&4Ma^XT zB~ydflfqJ9L3C!H&M3f6B)>Wj7K)sS zopT(IN#{f^TCnD4S^}Wu;GmEkhd|UZaf{!!#(=xq7DR< z@dT25Wszoge(K6cxzJV75St{7?qcRX_Z^jRdf}I@f^BhOdkH>;hzVsUPE-l=z%IJ9 z-AT}#mf+)cW`!v6DT1zM4eDmeZJcIf#vChWg8SYU0C?x)Gr>y$595blg@oS-CWULUGm)~` zm%mesHVYO-fS%rs=VR@9(EhcX78rFFMAhF0vQ(R=%O(|8BV~t?vfhi*XC8&o9gIYj zB7yiuiF6?wg{CV&gd=oA-DGU7gse4Yk#CFi*}2HAqX$A#HYgS z4nzup+HjrqaWHK&1-+GMwwR1vsnk`r*OdToX*$}t1%rBxovf8}D~!3o_>O8+hHii! zsRyi8(@*vc5Q@7yau{7>K8=|_Pm|^)So=x7qiiMXY*=9BlVBCr0`sqP`X|1gF_%!$ z$Ph4e&)`H+L0e`57FiQSJj5rVE~|6)&K^1I(NQ0#oV91rj>kwJ#T)`FW*2IvuuANp zhI5i9!JdpjdmqO9^$KSn6#jw9YF54a3dJHJ!fouh0#@k&efw8 zUEuslFGFBoXP+(l^|w1fynRN1tqGDFU`5C5bPEui41LLitgNC3WNZn@y2WvyL7(+K zZn=5cNndUJRBYigu#+M@<74Ip?PX;y2`p7?x9M6ZWK7AnbZ~M~xA-NJGY0j-+&G;u zzMCYbT1A4s(Vzn2LqyJ;Ib90>AxjwBn28G+B9fir$_%R{T%v9088jJwOvA5(LR^-L z__2ZKq>OGKkA~^*KzYKI#;`+boI{Tjq#&^>(E{=g@FRhFQrHqap@J*?i#%AAmqq&k zF-=M_l#H|#)p>+21Zu3`WVRxE9LUs&&+QT<52-?D&102P1P_VF*kc=9P^+|&bvI?1 z!sg-C4(?mxz%?>>&FcisH>`CJDRtS{&pW+Pc+~auqnU7p{^laETi9Y`9$2*bdtC{!l@EC^%%qj3 z=Lk@unI1e2G7j*}_Wd?+pN$jtY>nNCnTEr`lWgmnPRo2(uxsZ}8HUxd z_vGvJu-pX9Ra0;F_R%0{RUqb*{yD70eHbe`%w^f93MS9j;B3Uu$(kRL<gwR5ddt@jEtRXr!ojXIC z+C#qS_dGv&vg>;vC29*5;*9mVzo`6)5IsDB{YOvLazBv6lgl%vqAD6GUIrw}>6 zsa&3-Yj=^YYM)bGBZ7}s@r}rvAN;a(*UAZ4(%nl|RV7A20W7_40-@`hr|-hn7Ng(^ zcz5yA{M=RB>_6~ZY{YVCym}dg9H-bIx!ZNNGem7)V!%gHQ6sv$D1;&V>+Z2Yvu}`- zt=)Wd^adh^LrB^NVtxY&WkLJybzf)OMCYx@c*tjtM9GP!{kGV)+S38A%Xw>Tj8VOg zug=&;wsKcT9UHz~h%Jftzx$p}#uO)Z&pE%zCdT!vPSk*w6nlueuO;c|0J~q1ov#|Jv_}t72eL~?177hmCoD_*O!8g0&9Z*J zCUXkAO^QL{g89Lf+jswrtJn;iUY0v=oVCcaf}kQ5SW;IHB--Rg4qjg(L z`T7yVPT8fHe1S9;!Tn03QmyfGWwDs-HA~eYuH8SzD0wu0e`)PIx_3l*ozSY>b6@(FDLcC|)?`LU+}VpJTEk+`;RJ4H1d#mJ&_!Z)a z*qsBt)s=I!MKr4=n1kH~>U$B>Rtv9g#A3|q9+VZQd>k~tGB4^sEX*6!5ih$nF3L%w z(dO?;%&JAt)1cK5XN@Snp1hp@36LBzcR}f}3f(92x^ABYwXf^rOWHdj{<6-Hjg&(f zy+J=R<8gHksGt9`#{A0u;M8!?g_{8=yY*>9J1#l6vc|GD#Hp@OX83|GhmuHGHxAO2o4-OS?)RQ<5jJv^kO7od zf&nJ3JFtOWuygg0(&2p1g;(~W%$AJk(Y{5M<%M8UD4|y>^bCH9J-RZTFgs1j4RGXz zAhU)L_+v@%3#@|Ro>=rgei4&+Tbc!wIK-1RemT)Kx8)vT!qRm(u3nO6Bh1^%FeEX$ zfmP{7G1%`xbX=K`C1IKZ?l_nIB42{V;q~Bu0UgR%w}6D*98YmCIAFGBkDc9v!6&>3 zgKb*4PY~%u!yem{61%upEQBp5F&N#~zSVq?p0LISMO4 zxHtj#T?mAiP~ksPIv~2=b2vr?g^F{~-)sSF+Ux?K7Wf@z%Jx;~97#X+-2I&xA5nF(WwpJ_r0{cMHW@TKcIH(~N8}V3db`RW;E^A&3&|$l|Z` z+6Ej<`ffG;h70A^7h6?0s1mejP(RaQN%u+Y^@h20U|bir7&;AgMm#{oIEjL^F&vZT zM+NTJ&P)m@Ycpp=n+O^#9fVRnBML85dinv8>oP~$J?v~7D)H>UOs3f`^Nf^=lnz9t z4bZeFL!J6WIYJK*b-7X2>ScH<+L?-cjj@V{`N7iuP!uj8R>k21Z7(+DID*z9Z~v<& z$E~{_G>@c7;6}AWmAaaMFUg}i1cLcy$nq@_UPsi}*egehu#e&@G}S?6!cyl zCr!Yh*7QYDq2x7m`t`>iBgJug_eF^cTv=?3t0g6lKU!M*Ao(=Jn$%0=BtT`DNN9sv znAo&7Uc#CqMW2R>H(RLy!RqY!Ro}FW0Rql0)wGy9^R!qqwcOjK6VZ!l`EFNIw(Yo| z4*noF>);ZS*)k3KJ)$b<1Bj`nVswZW^p3`0{x+ty#f49nTy#pjG@@5&KWOlS&+_ph zuS2V?Z^eb0*0$jNpqWSf94&9eg;IKgpMM@-Xu0umP>f~fsE~in<8ncK@O>57PGxZg?)UnIs$LXKndm6L<_ikUQT`oxw^HgC|0Nf79fqEbIOxP z#ptaE#)x@F&u!G9E0Xu!ig#%pi$m ziMI*^u^{&IqY5!wQq??4pJ;E4IuYc2p^JC}r`G}qA=e=_k+SV)poW}TxXpZ9y~`$x z+61)mEU#R(IdfD_z=p8}U96iqAJDPY=!3J`Sr~`Vx-CQ+J1Aw9J81Gu2I-dvXbTYt zZwb=9F=svtIe5u3x5qb2y_NGb!o3WF@{8cW+~- z%yK<|1^38|n>A&#C(~4W3_@Rdsv{WyJZ@a#?VW1W2oALA*Fip-=imT$xM3ZC% zE?78+&+bnFf!QmV5-@9I+ZNG$-vvlIOcLZkTUJ1Cd_e0Ix)Mz1<+f`9-PBOV6$CcE zlsj=~Ztk87!t6fvom>g?_+M~lhNW7Ep;|=;6D_lsxZbZZax8j48U1qLme@EVOg9HF z-?t?5bn``9J< zMvLKrjZ2WUNThvgjn`8SZp@8tMYsclG&^VN8wQKw`*ZD}+fz44l!9OO=*~+AU_5*) z#;U>co!JyB2a0H{LXdq{uvF7mM=0-MTdcdz?~dK8o447qsfRs>kZ_+ai0haA_w(uN z8ditX=4izDG%jKe++y!M-Rwtz(s!NCQ9X8qv#qy;HSiBD!Cy=dT4)tUwfi9-qG$x4 zm{$5@3XF67r&&+o^(Z$1Jx6}8R&TCk9XU0-t*j5M+Ht&i8@&dl-61f(45!>tQ;cYF z67EgYI+()S{~}ZwmYzmAM=&7C7Q@- zO&VMkfYZJ)6!&yC&Zq>Oudgqqca!%7{(MZV=eX6YSNG}klo_ptfElL-IO&ZeD+#Ny zBZ<<>!)f&GYvQ-BA6g=5427?fJbq)<6jDe&%++JOtYRY5HxXDu2~0mka#c zQvSzW7@63c7+G4`8cfZRlMarFNm8v(&WVqTQczKePzH}(7zm9?#vsezuogUk@L4-G7b*# zeK>i85O-yC4`6$qPn-5UG~N=i#4Hd|+t=V^vpW%HT*7Oh7v`j!ES_n>rk=IODSJ5SlOs%E+#MX+BjW6S~dd50*K_vGb-x z27eT4Q6z@yqlL(RplO)gs-v%8L^02j%n!mLrpW@w)aa_pJ<&N=%Mv`&<++0$k;g{HlS%iOVtUwQS&^;|4b|f;8|u+>A3bcK*efdHWEjUTPH%Aeb6e%FvJz@{pJ4>sI>C$hf-0=r_kr96{`ZMaJ1ahc3qE_x(EixpJ7@)J;E1 zjO&(5`sZ_+v$qXr?;o4{F~4da;X6^(`{>)>YE}+#s&fiAWk9!5}XtEsDOJ!zvl4K%4ki!mMJv_w3&k`JJkngMm#CQJC9$cQs>JlX~z^cwOy z8gzhxOj*y134x{@phB$9Dwx^5Q8k$F91xf>N7JQ=l@9b5sQ@OYa_6dY&(cT-Wb^Y> zq#FUwqNfyk(W3g-FzfA6gxZ|ZTy0x+|IgeAtt(2BV>2va{yFw4;T{jGD(a;KRrzdJ zXA}6m*D2!S;i3SdM?cjU|6 z!RG0Qsu@8eP_j#@1(X>S0bl9cGvpw+IRHVOo~RknfJCo)wr`8}U^h4|d5|NpjH&P$ zoRGOu?37vZws4=FBy;Eh{(94{QJWb_hp8${^`Gop?jYR_N)YH7JF`2*CSe??}YwZ2hur_yi zBl4nhu`myh9Fpp$ffT&G2Y>y$ z0{^l1_O3T42ZRX`tDw7sWIM_OkeKE8J~WU9v7+7pmE~||{+AL$PoD9b(&|@=Mwlw^ z`gG0C5q1M5dJ6=j1^Tg?QO;vQ2A1fXxOj8hy`^bVuX9KZHLrx2V2&NJ)oz+9Qmh1CW;_m%d zq>q$s@1(1L z|HAoCxr;t_@J@;Ik*?+M4tU`Ij}HDlLC(hxy5BnZNWJmS`tnCw5&r7n|KNc6SImz! zqVfI!zCFpmsa+pt_g^vp=b!anSo&ic)mt{z2YJEy3+^qL=6^3U{qYCBr(bf<%_yA$e<2wCNZZ$*4;^{#h+ z)Pmmi?mtp%^Fa&$*z8?J`gpLtt4M!@$Ns+*rjKpjkGzlX_P+;~>-g~ilo1F12ju&^ O|L%>PZN}*x{r>^@A`B(~ literal 0 HcmV?d00001 diff --git a/lib/c3p0-0.9.1.2.jar b/lib/c3p0-0.9.1.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..0f42d60e316c0cb25c8a24b6c2b20918b132fd1d GIT binary patch literal 610790 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%0D1$QziZ0TM6VCQk~kM~pdC5St>l4wm9|JdF6j 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
-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%0D`TaXr|4|S$hm56Fe~N*?Prm+7 zGFTQi_SSR)hEC3o21fq{cK<0E`)^sSe`amAf{Yvx1A@sHi=H`1xHQJisqnQWe-7fsC7^ayTvJf+#^!m)Bi|PCJ)W*jo)o-wt2XUjp z{*u6mKpJqBkj-?sW*#%~m2;kuC@Zjt{L?deo!Nk%jP39qIq@|n#aAANKX+fyQ>*bY z7_vMTKzL*E5TOyXnc6L+ur-0ZoON9fC1oVvWyKfn#7PdYD31428H-({9t&lz)n2 zk}tnS9?44-`QhLO$9szylaM%gi|;c3rpbq7V|a=a|Bd2Pe?3W?ttydyC5_GhhawI#!6KKCEdNNsc&E zmt&mF_a79_e}t=u>zTFwCtMFd;bQ+E>i7Q@E(v23TW1Sr4`n+m6I%;U6XSnXn4ef} z@FVyfushJ(<}(-ZYvIc;4aL&~*$O067D&eIPI=mRKS$SNbm9Yx*h$ z!Jgq(d;VSTk0{jy_kU?zmNncX({jNirR3NSe>N$THSQi*zON$!I+jDL^x7A92Yl$} zYvws4OJ2|e5?O!wLnhclu|6%J7}G6M*IFohIjJXEn&GqPtYO80;V)yqGxZs9td9o@ z4GlMP*DnB<81&~`FP;9cBYFtd{TnfX8a0oGCs(-2Y8f{XJbh!|O$O-QAP~iM7y61q zkH==X*LpXI&TaqiL6$}Ele?HoCX7C>C?FZogUF;Q-na6CA$h5!>wh8#55YcyL|JX0@PomJ23+}>$)%Bv#D2H_) zM9((~^A85+9=@lu|L6ex;}3&D82VcJlLiJq%7i@sn>6^xiT&^H*~AS0I=6~8awrT4 zzEI$k)l_4V5jSoFp$F2dz$_pnq@I?B4djp^H(QK*5nfwTt=a>#jDXUg|8;mvj(W@s zNLwW~&Zf9$ry3V?dwaeC=K3XZSvJENf;$MPI}(Mx41e&0iL+j@utIi<5c-WBC0eo;RJ@IY&n8#~}vKflB`9+N=u(7fA;rfdVhey)jVOw!f{!FzImY?@a7#>h3?(PdF+_ zp$4zkFyDt!V|`MVx?3-Hp>^@|Ufk}0)MBiBim!Q&yzE-=afF)t4GyiuIc2-Wf-+9s z=YVjH;55FS)P)rz4#MT;7?k*cIrxwB-E{)`T~L|@y)4T-dmLWH^+vt*&C1aZIY9oq zZvP_#p3v|9qM-e7xyAmMb^HG-1O6HRVogYI6qSYAa~!60W@3%0+ zetHmMKoB*DG>e4!ap^1~1eX<~l@HfHPwG#LE+RT|OZM&iK6~vK^*@j2l_!<1*SXrC zt;NNM1s-HEUp`CI?aG&0&!_WlH5EEJzt#^xfHX?n{r=(A%K;Kv?eiZ8j*+5a;MCoF zpf(Kn2Lua~hOBWY^cIgi1o)F*l{~94xSuw#iOqQ0p<=hKPqdqTfw9zmxw{I%?##B% zdklCO!IPV(N3$}vk9VcHTq-Fg0@lxc602wZv@j_9_3k*|Fpgqw1R?ZOMWN$&(u7m! zCP+p|W($*33Zx9A4y4_i^}*w+q(0KJ`i_K&iD{on%iUX+Q8X`fl+bZJ>L zhcKobiSe`hc4kZ*q2uk+Ge(ZQFS@(^(07D?T^SOk(moT$i=}Ce961v87}^8IlewQM zQyf?l^_bd2#+#*UjPCuUYs?&h6L;EfMd5LVD_xQPwjkII*aW*XZ4Vr(qW_%%=Ix5c zw0+sdbti*vpA2+6aMexs;&!Lo9=+I^wW=Qspi}dxa>__O2!i63I3TO=P);2j1y7LVt6Mhl|(b z1goX(?0hDcx4@75j)0^xhNSYNY^^>CrFwY8h|IkD&_!hZu88iALxo>G+p!J&C=qYQ zB>iMiCPrAY7Jh^Qn zSA^cB10%QNnQG12Q?;Q32ABLd*44C$5qG%#O$W!JI95P6c#q)}`yg&*QWuMdsz{Kg zKlIJ8LE|z0^3pfECXprdF*OZG2cQ%#{NxKFpn|ymwknONH2ToZV#Cjy6=-0NA}WqR zeA75ukIDEi(lg=fQco>te)7#$dML5a#Z7W^8!JJNupNvGLcE479CuN;_-6GTYuNB3 z%fcS}5!K>cXab&4lZR0eMRjV(US3n!N}b~mnO!}!+hwMM`0kk<%G+U72lXi1!7W`9 zB+HLVAfTKllKvU?Jsm(g~6_^FbE1JG;vqM#|1*~Nua1)g8?BQ(04?1I^lZ78bGQrWRD zc3il$@6w4jAWLPKW50#S(LY#dkh+bAx8dv_+fFH24#{xM?U$rRt1RO&3zb>|W3-dO zVw=vQhszJ}yNO)dpJtNYk~kg+a6W}%@|F(bb&CIBN3*=g#DW(9KGW&?yA%IW5iQ24 zVUE5<>v6|=G%*4&TDt<1t817OEIyE+?!uKb0UF(elFc&0F?#}@y#QRKY0jplsr$l7 z#2pxN_H)dNzOI_-ksZOc<2#Fg(UoYGMkrD6!|5iMEXtkPF+-F?V;eZkAkenK&FN?#;r% zNMJ)6h@!3`@VQvq;R$@!=tz(Pd{tZGHo7{88S6hhk5MOvSp3?p=1Tn$t; zt8PyXo-1U)I4q9H_!4|fxctS0|0?mUViu*5(3QCGA)Me~>A6#fy$~1NN-PG?bd_OE z#b_$p`#MsTG9YX9eL9ql5(~;+0SA^S;Em5OWqW3mufHM%3HKD;#H{2f!nAK3#CcB+ zdT!W`7UG)h1=Z1o*js<@k&#VNxQbJO;io0sQ_Ub9CAA`)GB}hn|D{^GfM&5h=#|jDJ&9mP>K)BO-vm^)KCR;Q$d37Ew zh6Zv}$kz&p#wJ@5E&B!e5DuB-`5MHb|)KJMXTHzsltd_TKI=%8pPl{ssTO82BE4#r3^O;1A)k=VOyiuE(;{ zMw+;V;HDfjx^07z8&G28hW#*hkLl%^Jp?7CL+bY?r6si`1-;FnmbeX}K0@fvmySq7 zLH4)vSly7`Hn^uvd}qCpAa&+08zd~5}j16uwbr%MU*_BzIPfC$#zFTE_K8`UH@7x#mS#CB5`0+ z6?8=_5nl|sAgsX|ha*-IR~%R*(V#rO{3=@EDDkI3ndnbP(Rc&1NJZhP*x9|Ph5w(p zf}L|0C|u9TO!R7viY7N^R@@TjDqCwy)l;Yjmr70>Wfd3Pn=&qws$E#sajy%>wg|s% zX~YibWq?L;2=jTb5U~+~D-EcF{l!?U_ zmn9oTXAR82FG?9(34KR2lk89{c^XyJ)5cnV#WI5H3TUdD$)=Y|M;_@=;N^2r!W8og zt7Az(6kov#+sN`nASX(ASrvrKh1E67t@B^S^KD5KK$SfS_qKoMqJN7=xF;n+nI$kj(9MSpal)bfTFYA;x8WB`9?FZ4Gst7W9JADK=|VdmTpeA)7q}IK^4C5MX{rq;^-~rj<^TK5sTN&e#kw1SWDyk z{H(4g_R5|Nh8`J(vR^hj+KscGx(=Xbw>zY-U+fokrIol|sc3$xxzg5AU2H=krV(S^ z1ZOgHqk;kpTJWjjr-{j?KTOSEW!TeNDhB%os%B5!akd8t-c)Zt0K)+iK9?n{xZbzE z@1~v4R^YR)wifgTd-j~Xh%Y(nE&5LF+6Y;F7Bw9xneIf#VSS7u=EuMQ4b~(y4Fo`u zq6yWKViFpuqsigY#JBx_NIS0;@{r1Qf8%kU*lQ zvH{LeT_i?y7;BQUvTAl%>zZEq`8w%X3%l-J#9b*?q+& zH61-f#~;$h*|xDzkCztiDLRrr<3PFT`^r-0u!O(XH$|I;S(!j1e|n~{t{3!*Y~(C_ zL8V(;gAFTP!%;^DCYNd=kZPMNhgY`AHVHVZGjq3}{t^(s0cl64EqMG$+Y6k}Rt26rJ-(x| z>DxV3xNiD)Bs!UZ!!ILd3^V5|NZfaW$(l-*=M)#6>LOwyDQkI ziWnxGC&F^fh2KYd%4@%T1@OGRF{c%g3eVLqI2P2g7a*ihjt$jUl$!8H-wtcLsvouY zOA(Cajtlm#1kBw)=H?f9dBruj9HKk7FT&t|1@|vjFryt<4Fd8V}6epm{c_ zCmeDuna;5)7%m|YT^La2mb|)2kqzL{Adh`r>9tR3Yu6cCoOPWK_JozC+rV6=Z=)0+ z^7CLl)$eIT$=2UjD4PaDuH@UGL?oKwlAo)%=qK|rJYIPL~4)+@|jx8hUBb3v+0K>*v4mB-u@dwNyD;r(GB-?_iyONFXW8!4$(aP5OrwM=Eu+F^p zd@s60n5trR1WCIHANy~`F@QyT3LAZ-A=JfGM?-Cy@9iJ4B`GDZE z9L+45N{$h?8KPkur=-^X&90J2bfFbWM7d;e-|FWaa`qk|e2_K-mj&(W|Gn=vh!kj% z8(em!QvCSB3i$T`hLRWd{Ysg77gPmUrF%(W*lbTjVE9xT#SDWIHS=E6NhWK<9f zCr=Jol_*dr2kNQj`ac=;Y1W#Iu~{d&&J?F zINb(AU$-%&0?oj78sMRkW=a|1soT7nfnTj;G3;t=la)S2+Vbs;Sj5H4h4#D5tO!a4_wB3#wL z#NGjVoBPug&4nB)$;n(F;na_TUE(llOYeMr&>%p0M9Yswej|8am0Kr~?|s5d_$Go` zH$XfIfYr+_`m;poCldL_$cT>^qSgf!biA&5n#DBhPc7!Xf?ckHNtqs~*wm7CO zt`+i4-r`=nanEUi76G)Lu+QN+_1=m|0nknyc6jb)>Q%??Po=)ovmZgb1YOGn{fe4- zF@ywE`?B|*avMQoGSkih?VZHXlP-0TL4C0`^JeH9A!_WW z-FJ6JeG$t3GdzUdqp=6)GJ@vh@@N*IcN9%mdb^eZ>f6B7n?8To@N;btk?aG|%)|}# zWiUta@Ynpi*FsqVGCl`>4MIX8M!aNB{7R&F4@SHwCqWHT!W$!gjH4i@pfD!|@Pav6 z@n6D)af<}fJ3WOBA{+Pw*~xsR3=a}$aj{5VS5L5FN3tAW!V70ru;K=H{{UwOAIEYA zH#qDcCSh+^64`1qc%Wei^~bU322&X*)A(!#-{HT!{oaMU=(O4GlXJK`F@|AEG}P&T z=#TkHB+vzb(uH99L&%hi0Sdmyj$LO{&=IO=n-12cK+qCdfJwGDluW}62*`x}6z{b5-Cq(Ou08id1Ns6b3<;p_Nas#Ws5?ybz*PYbUAW6T z(x_N5bWXzWipmB|CjmJ&_e6ww9@{o!G>;R6}owm-(+O9iQ+h z^Ea*KiFTP)3*Iuiz;8v07SlcOUf7YZMcsG@Ebe$i!E7d$j{CpJ2Xg3v+_aXcS(d4X zDX(Qb2)}(=88(wFsGX(>tXEU$ZQ&kkj+RLuh;T9$FcbURKYEt1oOtyu2`<#8* zho<8Q)9~jzZO0$4)RGA{lH)__Y#WWrCP!mm|1sQSIVNNaUd2MQ2t$6X2cmw7iAR`B5^tgOs9__o1uWad+EPLA7Vuttn ztgQX8BjYJ@dBwyzfj_FYz%+~D6_Hcuu6BhdUMTY@amK@og~bU{sPRUY69s8xjO`007MY*Kvc3v$>3clhseZnY`nV-NVt@ z!sK81At@@Gii`5dI%PD?&49%~P{Un@kgb5p?=r%7E2tyT(Y+y<1PjDD#3HZYegJ;{ zYTgt@Gwi&tduA^L7dsZ^KS710i#{{Gbv?7Z=c~7PynyHfme^zoCWXQb$YSjyFl6+B zm(sSv3=@eAD=`nYgrO3qrH1JzE~KFvx~J(=Vh&3A9-?e6ZnF5QDTC1#Pn)&58pB1+iQX;F;l8rD&@F#$_e_IB`qP3b(r+4)Q1G#-8 zUwu1-w6*Bau0*L3@*O8wB_ULRpm<-X7m_p?nzvqDq>jg`4x^Ye(QL{~#noh{@tb+# zldDeEXfdNmrAibOX;nT9&09-8O5+P`RbH^yQNMTae;>$88cy%Eyo@`Tl z!~_AU5Nqo_%;p#%n^Uc(Yz0`-Z#gVA`SZGfP?#H*>bp&>q)4Xcq*wodWnx)a*6HZ2 zxnomd(X|vx2_R)V zp1`Eitc;+y`~An}EZdKm@f|GvmK#Em=3Ww{yD*f z`;MDV30puBbIbpU_!lM=_Al$%<<18($zc zQEHt%j-&HhJQhN!7&)X3dZP!2HX{V!Vie?Kuol_Umq5%h4@SO!8~5SX9?G)+cu~uL zf_td`Z};CnPE=u&|1hQg_t>7aC_iL1l+jsZAyy64dwl-f^o8V5`6PJw7WoT$E&`#a z;TdcEd>yi`Bx8LyvYZ@PNY$#ApQwqA4a=YWo-kB}W@Kv!k&0!?$Q3o8ceuwoc|SMT z#O)kv6TZBu9BzQJOXjo^g zo*pzlX}zPqJp++U)rarW$J9uE{gHT$2iR1;Ly>q*2P&%BX2Vw1?fsEax^EG2tY}xg zx^hvxOKIsfBy>7Y3T#;Ku$>1*c?+{^byd~uli2QyVti$7-H*_8pNU0(3BJq)Roz8k zA`C=M!jsrF$mii4yb$ zQ)45f=Yg#VD73AO8DUZcVz6B#1M<}k=?cOd2S(xv0mX(%ktslsE{hr<-jXAN=?OsQ z=cb^;4i%-P#SI8dxyI&8k6Y8rhe#2-fo6*$r@*!b=0opy{Lzod=8iq$ibxHVkw*v} zhH+t8#B`PC(p&7Z~rHW;lCM)RAzaawXH(uIUxnHWuh;1nW| zXy6J&z) zsHDTk4abvK&c#g>M>iq`31#g<)rod!rb%aJ49Yl)&dgZ>I}HU->M{)jOGwe6u{al1 zop($%y%A9!{3CCu4AW?=EQ(O=e%%Ns~P< zV@X;hN7{<|O;k}PuBvp#xU69%^T%s)jgpqd!K8ixqjhUBjX8-~)~K+UzAP=ZnjYn| zsV38?Fq`5CtzO-`eA$P?6&@7gg5jdusw_2WuEAI1YvNG|2_T)^Y0zmRe=?SK9#%pD%x-(^2frzamx)Ye!G~*l` zLL8-+l-bQzmz9|;li8XkPFY4#s&N8j_xn}D3qvXkSW{C(7&D1U^PU){ZtYgKHk#td zDK#PBp|t11AjM;~6Z`yLW+~bES{fSwziMmn+V(mTP-}_1TRy>}dU8Cog+eLMi9WWQ zOfhM^JtGur-P=@Iiim$Ax}t)@xmD(1RKgcZ^;Hl+RGBA-jm0ab;mrp13N({wxDQ zcw|XQGjF#&=8m%efILEz5|X{`z)Org|lo%X<|#89k2^CHO-BL zPH!lSx>IT;lV6mUH^u}BU6Ko$*`wW#!|R4XGH0}`cZ+l7RM}G4+o~32s_dbbCvJ|- z%i9R7)d)m+G7SP|84g+4frsyj7N^w*jBDE@k){L#K?Kv842tr5&cx!HLdo42U9hxn zxPE-FdDce>07RUVb0-T%R{ju>*{7f~P#9E$H4qF!1|rFE z4$RL&!y1@~o^hWR5jZ1Ff_D6i*y!1~`yav5cla%sKORv$2ju+n`3R+lmAsUvr}vJY z7VK7-k!i$!Q>>YB^A+ZS#&XXPc*1HgVH+xj@;jwaN0(GLDA8 z`lKXoLg(+L!}SSHN~~?SeflicUyJ&>)eEjnGD7@>LF?5dZYowc$$y;?WP1brXA%||N!$j&AFH&*!G2~6J9oFxy?_Zod>FnNIX1gBr zW!bp5*%kfj%z3-p9di|DS%UKjlj3OygE3gcH~~U%+!6@6x`vP3wV68S}#T zYZv~4IEw3hymcP;(z)kN^G=i6k#kEM$8#F*mg4={%}K+yA1{;|@d(_-VZO*@`-R%& zGgT2Ji{p4vuOybud9f6h!+EmQs6^#@ZA6B7;ptkc-wpXROZKt1mJxP;7!Ri4RKEJC zSJ=5~9mX5bIAeQN;3fYC4M1|1RE{NHA|ci>c|%ay!@u+J#MdgaeTbiw>^QbvKdI@1 z|4ygm1DoR%<03b%&bx30$vlTF!-dM3-C)Ums!dd}XIi zrCm1Yk%_sj52oJ<1#b4+q;k)3uTjO`X)l_x9n`)_Mf!!;{#iBs4wcQFkKYMYdpyx} z*30%DFusFQ+Z!TVr=&^&i~ySWovSeR}J(T zsvW#?Zzk~F8)b{b9!~Xl57bS8WP+`u7^Z{>oEl-)_R%GNpL~S1Ly{CeUWKr&eUci# zZv*1`1!-O2ha!n%QIEv++(cU%f>@4ss{ zGcBXnfE{2qa(V^R_1mrq-diG?VReAJp58Gptb10&ZIF6My{O*PFRZ%xPgYB73k||K zNN5$GFv|rd37sRg@@!K!ke)XeeVu((?n9+S(bhk=c- za8W+pRbloN7^1_5aEAy3!3Pkye<^cAl-{AU$At9{#^VWHD!D_|t6z_Nl-UpZ#q`Fy z%kEh`!Qhfme+fOpe%$v<`sWUN2+nPUVR>Y)DeY&qy6ygZs?0GW(DNknPpZt1%b)tc z5}*=4cG3SOQ6}ZbUZic(!bg@do+E9$;Jgtm%U0?K_Oc86F-eR4&q1k>$6oHQin+dSW#L<@M>{%? z;?I65-M6?jUgJdY!xU&_TI$lMHI*q_T1tZu9$ebgm8flPLMvsuG{=m`Qh&s>$sy$s zAKlF1MPuX60Td`T&vSL&5h*8+Q0@=gpZf8Gyfm|WY7K5JT&LhU?U1+>Bw*ZJvZzzf z7k0SW=Q|({tAaGNKZXWXlDNwx+Jh~PZL+vh-Ae<18Rz#(bh?)&C*3_D@n*@~UxjrE z;*yM?jN$SQL^jEZ$|lAvba``TbgIe9j z-8tF6#^oKIJiQ<7?hcwo!WFzfOIWR!7Dis_-kS6oc7GJ&_0*G%@_g~8yFE%Da0qds zBQY>xW#8Y|Ss)FGJU5U6k@axzAM8TGHRdesDC!|uL%A}yv)rEFnC~?eQyYC#xz3U9 zj;Ux~pOc{~*2)rUNLD2WGop;d@bS@1v~aar3uhY|{3Pg+vqD$j@s9{?RrPvOEZN+m+Fs5J2+(AX9IHhHC1r_0psyhQB)y@K3bKa=>BIHl@Cc=XJwdnD1;(VVlzy#$y+tH#X6*~ zU$-N!(I@Wdn-e#H*X08{)DXLW6g2$9QHu1C>+Gzif+#^0kPd(fM$E|16;H8Hs_`jG zT!ofpsdyO^U>(F1)&m+LzQW9-Db9w)>Ytw49IDC8lpRe9;uxGupTUQ$D}2_a6b=2s7gX*zrJ7Ut6G<%q41ktZ~9 zID2+noS3wV%4o+oD{=zc%Pe>5D`YTN8kwo>gw~dIW7ELX zk7jlXkp0kBdBQ%j)KW(`DP){3NZteplIbFxM5$&^AV|4B)-~hMB19?yvl668O2t@g)jHQPoa?MyPmcbPatkme* zP#Ch%qYKoX#H|BGoH5AqeVmqMISe05&?+Hx@~?uP;6F9tLg^q;yP{cL@F7isRlwaKwY7c0^ zi&n^Ag%f%QbXDFoej>-0#xGTb{3c(-6hL}K_p2|8AUP5XxQ@>tJ}1)95tGLbJriCp z&`^Fl$5<~|l)GbW1!DS#S&y!wAx4+LDSg9g^enY9fAcWLV!;Lw(W@$do8TkIKlTt4 zhk<#5Km}+AEr0v5f&XR5veUxo0azUA=KrM@u>D!D&%Z!a&U^(n5Ugpp5DwmmslI^3 zXkfBfYMe{qDrpJmWX7BjKU{uiO;i-L`o=Fmg~29G1uv>A1PE*;1~a{cre%?|3hJq- zijT0!k7g$2-&$b~=w_EdLaDHd>LEsRNR-(HrciSsi$UDbLfx9c0 zOj|5N>D4<1f6@0ep^aDejmH!8uun!5hQF_$hzswTwO9Z=if)ae_hy6C;k0Z^6lw*6 z1-~>9gFX*N=l{A&o2X)oq?C3QQxIk^4QNr|TB72a)eu4P7j4&_{*>+NQuW z$iC*OdyKa*N%1KL;QSns|r zK5(>HD#Wkm-tI*u#ZRiP$~k7w5rJAMuT}c9|K77fx+lNVSGrQ+g(XGrbT=lTOlgds zChKFQg9F&8@jkki;)x z@Lf!NQ{JF8_lmoVWpqSo#6%kT&lrv@tQxgNJ4bRNP$Mndy4zo}m~F>>tfX7GIG`ex zb?BM&_qb&2#cK@Ws?h9c6Fo7ScgYS^1Q^Y6ZLv|BWGXei8CErwmM#2kM1kLBU6${X z97B1}Si!9M`xkpqt#vm5FAsiY@hpnzGG7S5*upaBoNhZENRegOf{MMU2RRnY38^yG z#rIWMi4>gN%Ju>Z{PLkrMknxupo$mDTqozMYRt7QB1Q}pkM-cs7lv9|HKEAC zwUsWe1m*)Z^h8UGB*qaxo23cpM|am+cvcD`3+dB}>jt#g7r2vSKbbZvmw_HtM}_i) z1>>JRH{>YC?Nx1DSK7A8G%{G5LDyFK!RBuh-K@q>TzIsU_uD1~trcNnzdKB`S{fCJ_H~!r(|UvUpPB}S@8sFHR{KXnnV-|U|0Y4!!Gc0)lll~`$*52pfQrdG690Y z+^GcCWNbEUJ(KQql6Hv6O)|ms1Z@3ea=mc=n( znjs5aH$rCECmM_%Ke2B4h0fLTfws)8hg(JVD zpYGIjS}ZHND9n&oQ8-|L1TW{2HwXEA%eKJ#gQGguw+ds`S%}z_*SQ^|y!`7+UCW)^ zSSrJthR0OGDbi2^zRGh#?}SN@n>R+dl&4T>C4y23tX4)`^O?4b4I!AuuWFYjWa4M3KA7W@zmVj*Sc!{4%M;RICXTMkj%uG}pl{N#%%8C0Y}| z0yBq!nflB1MFcn`u2`%#>L2MrgXhu2p&C2G9QhrhBoP7ULXAy(muUO|sp|n1jIa=wx%Wzy z9a!wq1mutcSkF86+y8<+*otzv2UP~QX9HRh0C>0N_oTx2!QI<};~xbyMUuw_N~Z%$ zrUSRG12nD!HV*?_SLnYt=)b1`cqHlW15)o5ZR1Zh5O<=Q!7GJ3V|87`iNA1tD*U^c z6Mt339aej)xiMHaC*zH|JwU?@BVl)pzfrU1gu4>jASPsGFblAv9oQk&aN^j!YB&v> z-UVsZ8{$g0Euk0GOs4>9tO>z&+hFoEzj_YFJ`P{}4Yn;Vve%wyJD|?+LR(_D(6%S< zHmBH$VFa}eP2-2f1J|AhM7c`<_agf&e(X5rM#apDg9y85qYNSA6K6a63(eUHg?u|= zu{P-BCUFrzu4xrig0Y8V$>tdfKY~dW3S)sMdPmA_(TyM~>bAhkoKCw3-TT@}J9lS5 zLd4w5DwmM$HYAUhh7Pa9q~^d!=^SzM^W(;+S=-wj563V3;;ynMXor?%LHel<+azCIu-!357ZBNoX@n!j&hfy+y@ZmE!e_Q1*zRT+f?CkI+pylsStHTL z3`rQVa_yxkHV6OZGof_ygq2NBcZ79}Eth6=_TzrN7uAJo`qzX9%U0W^Izu_BSB`;rcH~6t4q(vu`$u7;-51XVH*sr4Ii9^~-Ym|6+cqS`29=LgVH3lDmGs=7Oj-R}|#eq$7b96pIsDBD(Nu12s zp$+?uBsb)a1LYBCPB#mW~Q@oMR;1Oka6%L=#mTAR9YJx==(V|B$JSXC@ zH&3j+l=VK;ZKDeZ3dW&!S51Cg31}vCJ3^i~udcx23$gmWapjSyW`Ehj&s>CcK!%9p z39Vj@Bqw%ouHy+loew+DOj4Eq*WWwM%)oA?@k{@fzvWPxO&6dp?C+PZ3LRsyZP~-B zEbR$*`}R!X4Ew!cpfdxQ`^Bp+x-r~DKVj>dT#}zQE=9;b$uoE*IpLZOgW2rmd{_Wy zAZR-LpQM_>)wJ3m*4N3vU4;=E_UCK~WYE@rFF`i8`(+SB%dNaSf-L*#y?`}mGdfQG z2VpwZ;$W}XS?w3p{2y;gGzWPIzp))Q7AO8jNL_)FLKPUIA)omU?Hmr&25Lvr>x){5 zosgqg4U zYI?*c?hS3pjm9M&OU2CfdzyQbGWT?O_0$3Oc84ut?&e=FIW5kimk{*le-Qcuz^}O;4`}TY+|qC+tsEf5H>S#o#;k{o*u%ak z*lv&44wUu*y}yrf<{h}5scy{Lqw;G(84!mO{L}Ld{J*bYdSQJX%KxN9fkFNkyV(Cs z6sO^lpHe-`QO96kQEi>+d%gr$P+`%9xyLS0f~L(@D8SqTzyx)e|Z zx>Zn;k_CkLr-P)OI;=ka%9IsL6Z>1-FF=nf2T*i$lg#WxA@+8?_$V^xWU!3Oi3^6__)F%#B4uA=D@)&#J5^spXSxvt@AQ>bSf=LE zRA45hWy%C~&^JpYK!Iuh#1ro-jv%o!Anc_oh4#YpS$G&+l7UZUHUw6QBSUxdpvyr#n=bKG z{gH*1gHBT{Lp?UhnOp^f^qF|VmRfNh=}N%_O5}=)isd0B#QJ`gCfAteQm#}VVMf8u zX_hd$_|_njrUUa**=#pLoJg|HVL?P@m|NDIb?-LuFv|%-)-FnbgVxQXO%g*0YTi|k zbp{B0qoChyR_R=VSVEPHcGL1M(S@DWDOqhCH_mFyYOOVlZ8=15{J{+=0oaKnDuK$H zaG-c4{gs@A3p(ySEmLhFWT$JP8s-Z3oTEImw+zuOc*ZnjHY(FO5A^M0!c~i$R1rCg zQGYKWj;bqb9-0XjcpVK?4+BMhlbWK7?jB`@W5!n>2jc$O#vE&<(fUnpOXVJEhrBfa zA(VVUty|ahV!%jyLH+aEQFw*o9f}UL`;!w$07JDl@C;?UR|8eVl zaPdKyM^U3$@YmRh;`rJ6GUMzb)zVV^TvgPhSCIj#bgj&$YRJAss?K)7No`M7364=( zgmbqmf{pd2=BMPlF5^Sva2q|&*@Lm`>CC*1IUJ_?PoTgf@`(SmjoaY(tm)Cgb4?NN z*s+%XxsNS`c71i>JF>)qUSI(mPu}=E_Jp&(sYBLRXzk*6I{08=uLTQrWtM5)8Oq!w z#GlI&6c>aTqh=)w(*aDLkY_W^$2}g*o>~WF1I!dm0Jl5d>BKWc!H77&;&maXd-VHV zbcnZ^yjTo!n&N0VZm*U%1>Lm8F%glniG6}MLwTNH9hL+~{5vM;MU8$yi z@FFvPI;OsXCI_g9gT?o-Npj@pW?|p0W&0Rw-NTQE^!RaTHJ6c6RNXWIK$&aeiTQ3F(WPeE|ACR(%iu*&<1z z9uJi)`;71Mn&mn5nBjQNPWrsu-TelkkG$oI9|CTmjx>>=h8u3APE7&nY@jrt31Dv& zY@{XDi@XkX_aaWM8@g8?V;#O19#}=}O}L{Ga^9t(f8=#+R*c}%kb7`X(AwcDN<)#o*J4si?qq&PHPw!eTLb@#D*Tt zF+AH?oDvZ7H|r@JwRdq)+gwzBuBcc^mZ%}}GWP(z!QdQ3F;HBBv5M(3S)6o~8*qaO zV);ZF@taXmJC`N1SKu+yA$5RBdvL!&tmTHsNPA?`EmsJ>3!zmn2}!Dv5WwuIPG|P>U9l zm#@$oetVybRHT^Jp-%s_6o_ncv&)(OZ?OjR5_O>{B_m8T7^+PXhetxWak@wJFA9Wh z0%ycllDQX)MVZYK&xlgt7?MWU_4(Io0?Bf|YWN!nVvII>Em1x&W9>l~47R)0=qz`! z5&WH$1fZW{v@}L#Q1rC#yweyV}~*Fka3hEX-3nDSVx zf#;Tj*{4|ebPc_2o@)FOGRYNVbHt}2auZWo51V5Fdii?d$ef*hLBNcdOE_|@_+N+wBxmJ#cTsVKVxJlGo{e@4ihb833RA*gp%Ob%r$eC#<-Kf8kIU?$ zjG+$F%07zc<7X5Q8-7&+t;IE`@{T6<297@mjQ^7BuxR+v$db?CU@A7frVrKcv$z6=9-F{XEo&pE?Y}*+6W-@gMjjB*u%n zu5|CBOO+eC=O0@cx|bg)L*z}m;}CLQrJ#4-ZEJDN*wj#S@<>SA;@T>v3F6kGbl@_w zj2*-Y&EVLktQ6_VPr29L#!&g&a9?kUJXxBFp@ps6Or3Pfh`N4OYmo9LHsC;p&gshB zv%DntKq3mO#Xf=70wguz{o3kHCPhlx)k-@cDnsrTnduvg9vbKzh|Hl6#%zNXzap63 z(r%OF75>~-{D)qEB{}O4DL-W%8L%@@) z9|F!ewdo&|0+B&uX*tvXsaIg0Bmakhk1XIn1YG~01kCv%AS>|?0q12V3;spGmDZXE z3!!9rJ9UCBcyY$s{my9J$MN>yNygee6%4gMnbE%8v_znoKuWX5}cMza^Q0OTJ`*WI-Sgqm`II$H7vO>=twQ`aMi`~ijR9?@E0eWyQxNy#`y}V} z0jXP_o;+nsl)Lvta!->?7LW*$i6Jd2CNrZ6lY^l!Gl})GJCkORZz4G#4Er)5m~TUN z0jrUik0$nlymMVj3BYMF(--r>TvHeXb6r~f`iFpE{}6Ch+&$6a9|DH{5U}ST0@_La z5U{Ex5Vb_DGG7IQJMbR@1~oI5W5>VvBmWZr3y?t6tP<}o{X;;W9|HOYRVCOt@Z95+ z67CwsA8k9!TB8SEcreN6#Sjr2p%1GslcnTF=LY8gWy5P!fgp*3V_@yd`Rk_-r`0Je1AaN@==WMQB#4#&aiVCJKV1xN)d^EKDz?LUU$nS1Q4((RI_F!#Nl@Ljvd9qj?-UR z{D$Cpydny1PvhM)sXj!Zye0101^9RE7n_XPX#c~&&!5s)q5nti_kXbOUG68<_{$cN z9;A#WdGt)T+K7Z*UTJL&c%ydGzfsU5cs|9}XrzO<7MrUH2lu=GD_4auzjcvPC6ieu ziPYwMw%I9XEPcpah>GuJ<8;fZ_o024=ibhb?;WEbJ@Wc&s9U`kev+qwI^0Bo`Z?)r zATjuuc%z<>xk@kz=^*pvO_BOi&>KIsj+i^So?stA$a|HB@sZcQ*)fBQ<45jAXzl3O zCXV6HYN5I{{!8x7T_L>?tflTPC(6&yU;5_OU{L_xr9l zJU_u!@pDCGmY}%v)*GvH8C`sXrXXISN?05<4g#~VTo~45N1Dm=^zI+$@5u~qFR}ED zJ-}EO{Zd%Lj&#A!D>!W@8npzn{2Lj{#XgdsTSK_dX`>$M7PVjZh~ZNtOQz`dOUBmx zSkzcAbQJ?pgKJjg7B*_PF1fY6snjN;_*}EzWmoJb3>}gToim ze`5-QRb`J%wuz3%d%|PF7~{agZjFAb`DiM4W^!OW<&I{MeCoMf z_s@%D2-iEzxijo|vE*4a_QmZI#h!y=I4{dO5*&^VTe)oo^}#F3@xa-yUDgUhmjo{n zE^V>j-O1EKexn>ffwbA;6t!}jZ^^Back1zOP>t8^5{WyLSVx=v*HelQy# zMP6Us=dX~zxjVOwDr#U=KfS&8+(YR&bf$;cYR6@$G~={$W}B-yariY$o-Dy-uk(^V zlJ@IEcj<}fU^rJF#fG-BVVe3_esK}lAjM)Kon4(M94LjInboS*qcn@Y|CeSbKN}k2 z=O6f2i)+N^7-uyAy}~H8#51r^;?78dh#O<^!YV9rARh>e#IW;A@bGT}ebsU0-^ufo zhLV1Tk?jk+iXwvN7Bz(;=V_JZDx$IY6tnYB^hMF+;KjW7LBNbW{8tdyD#Us4iZGFQ zOaggw4lGYFLJg@=Ux_hg$5w2pVp=YiXjXWrZ8+592JkIkEno}elYl2A&gH0 zVF^}XF6g8qAR3UTKkANpjH3d(;1K>t-A%%WYLB|-<$_r7=9}FsH!Fi|(0vDr{wzzo zf;;qmB*&$441_?m>k0Wtg8E4A8+i-98|+a?uLd|37x@+m0ho!3!Z|b`Jh|biR%C$I zwDj$`Bfp`NRQz|1a@}|D>KV+dM8{{4Akq!~Q=#%&IvW*#9i0 z{STyxn^^yR{MW;*+O`ss8uItGNm58XGHf8wGME$taR9!$GCZ@Qa&nxwBK*>VNz=fD zDH|ztsc=Q!;&%k+gSg#O6%4%5Y5Ulu6ATd#yoIzc@)1$q?jdkW zh`Ps32SoE0w3To1fvT}m>HA@(BxfbH6LK7z~oZTGdTNdVr2niMhN8f+~GAI>dkvXo0<4_?4&R2W8*t7ld{O2@Xz^G!ecJ|^{CB$*hw zr)6ys-o6gd5>}tfLsJ$FNi*VGQJdF7i>V=5m7XHI5kZ0jtDb5$wzQ)q$o?B;?-X5G z^lf`rQmKk7wry3M9XmU=ZQHh0v2EKnD|K`3`M%TIxo`iM)z(^%v(2{VSiO(& z>s4-JP|1^3)LBB%)FzMikI@)cWR`N8h2dvC#TM8InbB7=ngwI3m@iPhYA?yYA_S3w za-pV8(m%0r@#iiye=X|PvM_t4vA0j#8nf9ND^{I7z#)+cli~|$32Yu&fck!|V(Zy{ z8m5FbO0uhea_HRJzP+<{LTSi`{eC)1s*NjGVz`IWiIyug%BiuSpC`|GZtX_uEs9>E$s9R%D5h5a9hLb zaP8~2p)Hbuk!V*Mo8uP!hk;T0C}&_l_*;%tFVspiUo1FyMI~7Oj42vvak&<~`foju z(NFkPSd|w~o>OB5Kd15JT9_3!+v-lBTKV#zOqzOK@xG$kFKTx}Rmcdm@2aoWO_RB` z@Gk-9>69r94eS(TMCG_Xj7B zXuLqphikp1VMHg}y=z%S1%#Q>sZ&$1m3#vHUos=$1~Kh(51pFBljm}j7qqIWj_qYw zjFgZ|ujPiU?0iWQL-Buw|MpA59GK!qB%URL919=pkVoW~$dGem3V9#eC}xGDAU|q) z)Bbh}`|&B^W#_b%`=dWr`lGYe_@g&*xE>OhqbuU9n>(Yz6|p`C_emoOE$*RclrA*{ z#w%30LK~K|J`!?)kr@^g1Bph)g#Wqcu`V^phxnY=l5fF zARXD%ps@kUT?2Lv$nT3%4UZ3+75pOCjNp~`u9|dC9?m+?N#$x%B!Tmik5m2YT|7MW zsGMw5*NYq9{&mxx*t4(Qo^XDVcfZGcu&pp%cEe2bA`{aXX~yaHj7&q>nhd$Zje@GrV93D}*i{KxbwS0w!sOJDYH9wtE_Yd^l!xQO7Z%b_et{0(qI$*rCJzz7_Jrw_;Z091;-U(4r7Ob=8-+3l@uoQ^sNImy8#5b#70q4d5~)Tq$@VZ{ z2Z(u+7m_v*1Kg2X^thtrJCznHTe)qVmSI%zZs&CuX<50lkB9BOhvDYi9q07)#U-08 zIEOXu)s*&#de@-)2>xZxKCDz_2-zWZ07uCn+c;Jnrq7Mj6$w0XVGp7&-r>v`LXzfs zkymU}LD}Q$6aiIGmA!@C*+o`w?;CGRQp)a;@$YEh4FfZYE!#)>==Z{+2a5)<2V(b= z3?S#B(zApN3lH)9cY2I{zyIm^-?D=G*=pCtS1BF%MPL2TOX~ktQ*CW*zC0kHtXFMaMnQg4$dEv=J9G#=}tMCbqU10E_kU( z#jHwk$_4{7xy>G=_bL}H_P-F{&J=b+t*X_rLGI%h70HiLD*epKZi+Z<6<4%X8-}mr z(3?I|$I6adt&|Q;Mz}6m5P<5E$rNipmEAMka*v zg*Yw0HMxt2OPdHxlO$?yZgyU;3fHCEEZgP{?6%^`kK7}Uuae%~*7}Kiz4#G|f@l#b z?Z;xcUUM(?1}Bsf7(a? zmr9XN*H;7g(W3LOiSQ9L8L|xjF%*Li5+3uM57{1@Z217;_T2Bv5L|z3h45p6 zhGU#T>L^{qI4G%+BjPxga(&|Nd~PG-{-cZ|l*53f*blz3=QwH~`MX(TLfPGO1;3nP zrMv@$MEUtr4IBCCg8R||aj?-+m8+y%a`Rw87I^OMTv(_dE}ZDtPB?pYsr?P0NQF*= z5?=FVGFMT{q2zPuZazwrnr3D8JgZ0%dZ!i166&teK);)lIv2{gP|CH0xT{orXKv`m zEQP%>Jg&M?Ndyt)Dmfa-)IDYb3DJDE&c2Cary-8j4i+GcvWMYiSKZ5%hDV>|P(eU^ z4aXv?;f)&*8yTw}{uS?~68Fpm_G{ad{9h2y`}Z>Q@jooq>=1MSfB zW50ALMbf;YI>yk*#}JKlwBE7;FMrBdx()dS&ZC=z<2>2OcQ)`Dl@u9K+AdskdX(*5 zkVhv%{j((tE$wG6jZxsP!@~aNlD{q~seSyr_?|+$nkvLD8HsSm@srJ?Pp)Ty3K%;G zM`~4~M=9O)kQZiqC%A|@+e_8^TYO~}^!#EOgTvcHNpRW7LozF25t<}X{PvQc{rQ09 zB2G$DP#{T>!jj$ z&TN`1vcA1wC99;J2406fP8+xxhR8P;K&#o6^3uvu^)jT@D}Tq^_Ez_6LO$&lpl8$| z!p>L;3JgP=WH*nNbeuKH*XAQx0p?@kr792GfwHnL3=Y_4LsG+9Js+gwPglV@EOINP z`&5Ha09(pS(RDAibFHZLGVQTPX{`i=2@S7!aa@lSmE$`LId(ruZ~cs&MjYU4|EysU z*7mv3V#sUS2T4Z{2D-R!k16O|=-Ma*NeX%n4d|5{$3#P$@Nj$KWm2drIv-7$gOTWP z6Th(|iWC&krZ$g8uWrg6pJ-Bh`bn~dVyjrr36-+|k@<#-Wex(>5-_CWBh1^z5f7o^yrLMZf-fwi-Z$!PNh? zP=ac~R{D+)*X%mr)52d zqcyIPvSnLaFhQ1sY+NYFc*2ZYGsoSR4=u}YdU+8%a6nQosMQ_TM!}Lt+0R&EoW5dp zV`{;4i|(o0S5e3eB-J&Tp-9jw!t{(QJ*j4Yw@7ac zYEEw@+-5$N%ARFk<=#}HS8XO4J@8dFhzgi>ig0fa+wFs755*hp?5s` z!vtE6A9Sk%4&W||ErPrhu2?*>XGNugUKE2=HcI@L%%S(B)b`DzYxrSeRT>-NLtHy3 zY9U5#hrwnB9=<_a3yLdV_i z|5;;l(A#ec38mh9BXhXVj0r#?WZUqxGvm3$kHUSUA5&~=4Wmx6wteKH?kio}W=V{+ z%QU5Tzx?#392%@F|G1DlxrknAw5WQJ+$5#yVlI+F09~ncL_r z&a0{`O55cZSHBg^=myfW(hwJLQsE|D;!afyKBBi_K;MsXWa=iLHRxp)#wTd2=}xuS z*lNu;SDQHhI_~Af5n~xDNyHB$Z-8UV2mc=3o4QbmBVN;B`6qgeqCbor5=BnBhL;SC zDS6FM9CG9Lj!Rc{ysS>$Jf0`gL0r>!Y#TMt@-bEkHzZmynns<&D87k}De;|(*G z?To>Usp{kb8Zl-~>(zwo?JToWrBn=NIZr>|0Ab>)H>z&I8%tOS>4BS=chG zO-uTS;aA%Sl>mSOzaXD1$oCwJzrX7PB>`DUoB1mJHu-ILTRYsLmVAPCno&4f9^BOQ zknu$83T0}n5uNa=DY>YU#wSPGm|Q~cex#C#XG8BdZ8?{Vh(?a(U2ydS z{^5BTbxx1%7!)X&|0{mvg=jw3=I*gsHe&pj|PV!%;>DFLUS_%6O% zE1k`v-iw*BVqUdzkHAUIK9etqfn{pBmM|SOqfP8&YTTR;%Y)-n;WX7m^4;7;(-3f|`p7s1 zdkXf~AaNti5J-ePBcE%G9~g2P#X`cD|AaEGE#_2zwg0kwv4XD?sg1mvhbI1T`@6w{FlM>%M}E z+UQGL0|Y)l`T8wKdoaF1mY4;8Yh11lWS{bjCd8Z}v&7}+-RT?6Xx~Tk0ol&teN(;1 zdl2kBZ6C!%pWepV+JYmj_QLS9*FKV|8om+azT8WN{~RY|MXl1Uvm9Z9Q0x^YX5-gW zYo4Y(B3yI(luQ8Gw0ikHtYc0MOqr42!|qvuh8-5$na*X~s4gc(i(Hm|;neiBibLXP zs0uoH1o@+Ac)N9`B-%E4i30m<8>=Wcr3sPVh0+Ny-q+Y`^dI55v}65J46%s9LAG-B zVM|bFjNQ(%t#a~|<0?I`zeyx9*mc2s93e9Z4r}<3c+|bkP#2|Aq^okk?YfUF#kHSN4H7`P3lEB(@6D9MGUzuGJ9I<4XS1-u>st$e!J$u> zAxdz>ilU|5DMJ&ta~r|EK`{Ee|sM}BVH!c){TwxC(-T){}=y%XmdxUI4ecG-#}Z!TYc zOMR(HE^Yu7Gy@mvnc623M@LBc0f=uM10T?K#{xyw1>_{mcI4Zh@Ln60bLgl$oDG_Wnlhsy@x6a+&+U;-231mi|^P!uajydBx01DD~3 zrhXx=N5v3(oIkJF7~EN(o^5<$=Qrd7XN}X0VS{jZ8KT%qUN|FegJ5*7+p1vtGLlt& zAPoWf()ZcDZ&W#Ng~f1SNiA=mrEwnrHno|C8lf#)$$W1j`WUXIY; zL)~-UAoCuU?Z38_n(HcYj;V2W@*!F?I7&ttTVIA0yKh z2=nj_{j^9We>zw5O{QIeKWFR_wp1%eRQh4{qKB(dCP%vB!L3m*N1o1|uIUsOSkbNV zV>2p~YPq498UK!R2jXhqX{0~xA)Rn}ht5X$YG>P^)9){hb^8rYcP|SAM@LT|hns1w zwcP%*$?UyX1zd8yb(wb06P7^R-8? zYI}9)$i{Et_Re+3a+QZSe1T6+tZkwtZ8ta^i8L|2OL^h6&%^jOP3g(iYW0nQCfgU2 z7vBOZ*&p0Nk433v4E+EvE}F+C^SNcC2%CKx-pJ6cu+*)p$kvUn8}p;9z7}jriODNj zSLco!4k=ZJ9!v?RSteBLNGp_W)>hqjVg&kE)7)E+K?9u#@OHcqVAt|9|NmBJLN>VJ zr@v&bi7)b>#(%8N{Ex} zax6}%-E$O00)z?}K#+`xE82<(5iz{#o5J(efRyg!iosCW7-roMXqB)Z>r#IyAavx* zXM||{7J?2vqGMvN+wN9lYPP?z)*cz*xl-)xRaYegDnS}1sb{8dFMq3d#R`S6gI`ZV zpWRY>r2B|FMit!YlUNzB$C~_d&B&+&S9P|{>@wQvu!>2`2GkgMkyZ)#B|@pixsOKq zrV9s;3oXBZ-8a8aw(EH%7KuArbZ(=~uR}Xiu=?P7af?KjWI)-l?M;}2-0<@+u@%u! z@ACbif^{g9HQBx+v5MI_Zsg12VxGDzBcRaG$rRsYU7F?83hu67A_bvMTiZ?)Dm>7rpC2i_oB{ldPHgTQD?-CL(? z9sf2MfSig>CEN~OM=s5=qIPe69)nfi%J(0fvGFqE%9*s#(y(&M%?5ZHQ_c|O|L`du z?i3F?Aw1!OEiU?jC!~UfTVR-Qo2B-DZ1d^we4O6j!w{~=J(i)FEgg&c`L(^7ahBYi zQ)0b;o6e6(k;N}zg#UTxIR8V7o~cEmP2`(siY`b)uEgBSxgT_5%M)hA%dRSK?zAqF*asK zHKl+Sd`&B4NuAPMoed%MQs zs_XjynsgV>Ten3V{O@GQbhFKFK*E~1e6{cwys_u;^W0;=b{y(;VU`0w@RPIhA=$b$svr3w}g=}#HILDwrk`qkx$u20v$ z-1@4;P_+wB&@Fd%-o+YY8@m)z*xK9A5nT}RN`bgdyVEjq)&esT!t0qKuyM5;0|M3L zewKz@-`r&NRdy7ApDt^<^;MI>CpyRR{+{{MKZO5!7jyF?K85~}q4hPw=JV@rKV|a+ox^8Q zTK#5uc|>hY{FknCHhr zKmYvrSrx*38Kaf1>1>2TIn6^QhrI4ey&~j*fgQjd>9L?hUlQ5%)J>8B$q@zoDG4 zVTo6$&66;TNHc#B|Hv|}U5$JWMtw0IgB9oD`Qhy%OthxEihpt^&OJHSZIXmlYGtKR zuqdQ-KlI$(wA^fCWm5yx+wMEyDcKeB$?0K^giZ=)_LVK&Tv^EeX_9{YEj$h1U`89d zeLqaYmIzrjHA8#N5|_Psp^0Ou$!4WB8K{=b6=jKt$?MP|a8oZcG8~o`5kpe|&J{~Q6_XFyl{yyD1oiD!cD6Y! zvTaO8*peSX!|ZlHYyWBoF%H6;YhYjAz&9+y3n}n7&5^6t-`?H^MHy zjyHMa$N@h`D9~k6Q1#^mR4jl?RWwh9&)Un7UKVvw-=`D-Q!%y zf98ea_MNmD(VvK=+)yg>0IC0+Fw zYVF)a;_tP7uiYmJRuopA4@R!q35@C5sZ#_uINYyqPX|rko9NSuOfIo4>_7Yv2MS-C5h6t4*`=iS>qfyl-zJc-t z3;@RVaaici+Vv=yBn+X}#W1E)kI+y3bHS=W1Id#T!Rt2_FjF%yBKAxI|Ei4 z8cYNOoMEZ-+fsw+6Q2ePML^5djhzRBY~L9*RD@q=zARq>7eCc+U0xRgj-t1wqT+4@ z0zemOq{j8dEd|1LRKpwa)zRD7VNd5E{>3{0quPYK)UWW@kw zzj-3&M4L4`{#2!ToC&uUriINUI5Q%S_6kh1bCDYu$)|O2 zOMD7zN(tcY6RH5GBC*Klf(;XvTb%ywN|}9v`v;Rf6aq%{^-~B*^v87wiW5yvvj;TBJ>+l3+kA5An>s+pH9l`N)pV*zor;1Lry^Pb zt~kndy{kz2UhVONzzV{Wo=+uOYP|c{2PTbmy5Q+b#uP0X3#~m zkc)O)lvY;CJxtcW!GA6+NIku_XAjtGHTT*$#5|n6``{z<8YRc4KeF`l8BQKd+<%r? ztfko840q&y+Q`l~;Y}9JkF$QU{~iM6^uLJ z)JSTfWkQ=yNy#a;?mbZ1$vv5`#8SEFn(JX!{iK51E3Uh6zT_0SI3pSBZJH+vm}E8$M`jTDFJL#&uF@{^v$Fc3v7h2Q+8|E8=L?0cDsK2<2S_jej- zJ>0)}BADHH_b9sFX=ofIvw=*%DI)PHkjhF?D;c%oPNCEBL&v_0QK7&|^5H^wy?`C7hAG8y;1%ZJub@!Il2)T%ByuaTCzA-31kFK7-aF2dB}*s z`}|h7r8*km(_e;ZTFs|o*;vEN`mCBSbTFes&hH5Rjti3335sNpfr^)?GFW6Up0 zZ`xvK5XT-+Rz_j)JLDFE6()5++}PnyPHdns!hw*#63j{d2q0mG28oR$BSoTYj*I)a zR@#gM=F+%IV;Q4=8c05a5-m}o(#lCL&0cEx#g^0kwM>&bRmG(AH*JB!@H=}EO^=FG zII+YhZO1i}Q5YEMn!z7LL>9l&*sv3}} z?tbx7^V3keEMtmEd$W%A?vmQs8ubH*E|01QVtikmTSavi1$W~fXmQE5u-M=29&bQ^ zpLP@r={;J*sRSELWY7+(W4qKIVlzS{l%@Xj?b{P@)x@brf=E$^z%Pn!6WNoY)s@W{*+LvfXkCDl8)-WVBX?9%C#NO}^#2hkV ze!y|T2JY}Zr-s(xw>PV1^feaz*yWiemxB&oHXHgG`KiG=r%7?eX#i7}$>bF(4)!pD5~|l)70(54(3?<@x#Y7z#WryM@45=e2@-{s6`<;kz3@M$TVI?EHO>QT388w+pH`=li}lrr}x8+6bChQ0;F zZx-2b%~4`omb$0rQ?990IdIdv8>q;l=f8ZS-0Jr@6LUVg2F| zaMf7R?BSujvskEbElyi?R?xM1^>Ck%VC-)&ZfhND<$V^wR7G^r)8YBK)5=*dsbIJ{Cx6kK z3!s2-5&GjN6Jz>o3F|}$KM%?@N_{wVY4fal3Js_J%I@98`H_v3ubgiX|BV%aaPsLC z@>f-bt$(n)u)QMsxuV6D1~{7Pv^>6Ia8Jm7rgE13KE3XlqH$_L+%x988a~(8#0or@ z&AJz<$D*u5=jaAq$_=tAd`rv%xm)(*5>an1aYlfO$|T+;0>Qm~xtLJGCZ+LfnSdHe zu?cDifIaLKk^hpDph66yRWUnnsC9T?>nIXiGZzxMp@(4mGnDFNba1$%Bo2{ALoRO$6!_omln*7a2nNIhuq(TH;ey8uG^g&oU; z*+R|q9qdmkzia%eBw{_cbR}0e9OGjFxh)KSebQImHjNDnQc7oIt4s9}Ah7zdchgOR z%$S|joF*tbLx2OtO(Hs^qLC^?u?_!fal=p;W-8eD$pQ zmkM8jZA!VE&v-e&Nn??dATOIN<)Yj>Gh5*?!NqH$I;Z~p>(Er?m(EdsbbNZge*iyQ zbTFzpOF4lh`{(&}Zk{o$+c8u;s*QKGm+LEn)W^qt%X_LVVgQav^DPTHF_{YZ`rFt~ zkDCVi+qh4UXSFrgJl#jJ>Qi}%!u);e{yOH!s;$|%AI+KZ$-&Cuwq2mn{ z?i?S053mm%GxySON%>)4H4E-T0Ldp+F5twY?0`|0o=d8mowXP*zl_{7v^ePiFaPu; zYt|*zlpxPvm{qzRrYMzeFw=kI80aZz0~Fjsnw<3eYTtCgY>kPvuPl5(nq;8n5rLID z!pjdLpVtW~EiGJdjc%@2oN*zkQ5(Q8d|H~5N^Csytr1;5`Sc!K3aQa{eEb&(~Dp(1}R%$lP=n&BJ*8E z&chsAHxOIhw?y4=i!IfSEi1~MMOR$=)SWxTCKvWZIMt2R-6r4T#MC|3#xHmqhVG*_ zUWla?#C|wyIV0Y3li)4gqrBlA=8Z_DMmOs%+a&VOQAL{ePm$IaELy4B;xDvTPD;Es z+Zq47{tOC!xd`2gL*45uaB)OA%LARM{YNax*8l^D^u|gtn_H)hx8DXmBi->X9GNS3 zY-CFuC-9Z$Z+~$S%)K$c8_C6CjOk9B_HLSuU}5N}GW#fNj^1!KZ9RKJu_>B=CHi#2 z^|z{rEM}1s3o`uoy!dO$>xGh)$8ReiShB%JX$Zx|(DZnMwG_5;PeL5|@*~vL*oE_j zrEA_$u&jv$0p!&Hfs%JM!L%tmFcaqt+eHKJ`&55I#Q6%f$Ad(zNmc((0HZf{fqq`t z%91fB4q;|ESidyRvB;kuv47xne4IjxNO=v$5LvW{!t7bj?83#r|BdIAKr4lf`~*6u zk0*10(2YF_OMP~J_a)MfY)cU98wsTti1Gs{w}rjR*k=k%C(M61WgHgtE=# z3i{P#zsvlo&cgeMxupZVa?}pNlYdCk{-~~-$+XU+wqp~VfWP)+eqtAi+S8i?iDUgN zgEs%;hasbs!n_tt@%$(Q0{>1e3uj9nL0ALchK5o%l&5T(dLJJ znRONjDO@TP&xXo|uh9U|xylMEU%ipIH&CPOZK4ep*Fdz~>T`3V?Q3|~WQpS`} z$>-vNP&P-EPi(T~p6|fhW6Wm$>PR5oTfKo#7hT_Yx+g`P9CrqK4^qzBf|&khOM?I@ z_QWX-y-A(1DYv7Y{?e~#jZ-`9di}?DT35&LxgCClI}}ANxB{ngT6q%_L006eZ}3^B zEqAX!-6KqV?%QIpy}0uGCI1Z|*8hx|kXw&)m0I7gs^`_?doZ*(C9cKqkY@x>){Z?>;JoOopH3TKa=`I*Og|DB2$-X2NugsMrzw zVzN5@+6_AvulM^_FP#b%A=W3OwX56 zeCMVza;Y+bNmR2U_={75&1#PODzGWUoJU{c63>rhn0i9->`2!MdHBTQDu7uZ!sM#N z1LRAv%lp8oU#X!3{^UGwHD$)2)=9YtF08!g;XiCridlystjOJ4l%IRPl#RgtOwh=xd)d&K*pZZ}@KzpBcti$G()*mjl*cb*N6UG~ya)*f^2h(iZ9M z2-lyNKJUz)<66d)Kdt=dm#huZ<56D#`{ zRO%0+f=B=h5Ei?V0L`FR^Kg5`C*qQjEu&AgS|qEa?YI?;nX**q@~Q#TuvS^tk}d&) z?I|x-o>Qv+J*rvTHkw zt5MKgAyCy9R4-dI9K|`97sjo36Z>Qb#EYYhl6^Y1ns(Kw*zy4gzHcy{oM z?`Sk7K13~X>zMP!JDE}qB^8ce7`@)N8g{1_8#pl?fBn4#CIzQ-eQKxM)~R3Q>=o-K z#y!eUmgOUr@M3nbuh02$WtD+|Z={^K8~f)9fo32HvufFKw1M#!Vg!bABg9&aH0*@W!#Lmg7e zHQd#PUI;KL(l+w+WJ4SN5mhZictf_SN&I>AL+eC>;d5Ay!83&{0k!Z*{B*AQuK(e) ze51bP^t%UeNU^=Ls_=sPO+Zu7#?8R*oYBjUKbT%!SiLlFTv=FM2tz%OVbR{%U7Flb zdJO`nM7D5r%{aYUwnVwntx@Yd|8cDeigcM2>7s=1GAWU?mtASSJ6^t7Bq*6tfb_Ko zJtB`PpV>=-K@WmQZQh*>y9mi3o%cS@A<>M>Ty~n1w9UnY%bYHj&|)niW(6{eKJ6nm zKiuLb<$g)qwkx_F>QTE?zB${fE#%CK|FMD2=3#l%Kqbt!H#9!IS*=*=KM;A|&5eS75eL_+R?U zY@Q3K2F|8lK6v^+ zF1_3ec$od}6cV`wjM~Z*yOxNi@clh47#_;QE#L~hGfexZ18qk)!08#e9n#01pdRMc-qSqknq$HN)%AcEeLHH@HD;bG6f_c0ZcaBP zeICnMU9ve6VpGs?LT~ZS^Oq@WZ63InTDPb_O?$1-tG_s$lJ^pVr3)@6*`v2R6WmHQ{1w;Av z4T|P#>g_-E&;ASN@`Z5ux|$dZ|IgIHm;Gw%>|kW_U+@3hk^TQi;51=9RSv&eFm!mBKuO;PV*wO_Kg*L7vdqkB(DxEh-P>O@cIzsY3hNd&4Q+K@ z)W}BvB=qwF7wwkC=Bu@KOUnwEP3vWs^(5Zotx?9&iGi8T&k@g<_pGm>->iH7V~?A? zVR`=Vxye@!h8#bOu;TY((c~qWXb0z&@RIkml|0vjsInF9M7YJ#0lywyGeHQ$Ixmm_ z{m^}opw@QMp6F?J;f@KW)J-_rw(?E6|8>XC5DUUb!2&;09KX{p+ed+e;g4&!2Vrk6&M@>sxWQJx+V-Aax0EIz#XMKOS># z`n{0MciNDjn}hA%Cx3iKp8qAr^f>N3-`(~UzDOLs2@`*Y{&U%pNBGc8|5vbM6zAP1 zXoti#a+C{zT-Ag)GqH$Dc3jiRL+bI;8s|=PaH3eAUsZ`7;1tn8AX6`(R_ZjpPB8v4{i_zMMWEjGW zg=9kwLN^8|?CEbQcYI~aV}sd-GmE7zRfI?l-=Sb|ypwLSZGO`8ZU7e^=qr$)aIUf1 zlOW72eK@yF1_HduGhP}Fy=w-I%@XfNMQEb2OYN1x%x<@rPLcaf^7K3IYC8)`EGkYhdZ_-c@zKVrCv!E8aav^gg4H%M%Qx)q zy>do7Nqg5?v8yCxIk`W{@-Y>HypF_iet}VTchTr}h}XM-l1rOFoX!kA!itp-v|vgr z4WG_Dr>R?pV9E2#!ig;ZvR7j{6n*Y{c_HmQ-rnb4cJ-%5EWVe6+LOaV=&LxS&6q!n zqb#W(@Z6v|9!*r4DDeoTDu5WnI@-yF`H75nC_THDEFyW;K$~iJdtuXP05#rYUvrR4 zj2UVeL|dIvxFDjir#ma5AMt0)3c8s?L3Ud#$h5FQ|zL-j!HA*%?PoBt1_gqKF&Gm zScPA$Y6c^zd5%4azVH&}QUOS*TR1aFqbrnB?u30x)0Ci}=Q}1@C0rzT7Ecbz)vFpK z*==&DmDtaWW4c(r%9t|G-UrlVPL=8?4VclbiPEiJDj9ApToEW*$_}-3*N|qiKPzkYBjfB~9FeVtz&oa{6DwG%=%Nj%8(AO&F(4ENh zNVE^EpdoquPx}&HqpC^d9SJqF%ceH=kEC%nV7`#tw$2|3gya|11;p^j;1 z{j+wVjC}Etm^r0^Or(5cU-9O2TSX;7CXup^7?uiI3%TvCnoXfKQ{{q1rg^DBSQ8+z zXjVOHEc8d(MksqJ&F0-G@S*TG)9`p0=Zv6l_rd9w z&?N)GwK|BUW6jSN$c@eorq+6Szv96mtfh(?8dsSEbeX5{X*Q{!7;I%aj1o}c&a#6{qyRid-R*;VKYa!Me z3S#ifx045JpiOt9xAgkYzE1g8@!Pi9m8_W{x^pmh$c~2u2A9rvCJE-462}DB#7s=& zpw;F90ffvHS` zW>pgmS!P))e3C=WKzM5cp4F5B9RqJ2E}9hb(*ZZWuJu?;i2;=1ltw0L7M7zcWOF&w zKE+eV$(JW?w__^XsdQh>x}p-iAqUO7^H2JvPKt_OhPPLs$v26>e@fztHHH+`#fow5|jdg?Ba()=^lw$GbI_vGfcM`E^(P;*|M->^W$TV zI)e=qu+2~GmN0%lr*#PtK(87|ysyq;nreQ`ulb53DN7J*!wTenc@!;#HF)BV(g#k) z_YMCrOueivE==CpA>G8`wS(us`{5O2%8gSH2`BGNS$G#LBjHt9-mx{`C7GzXV8SE; zj3A8m7|w%$Hb2$o%uRxlR#EJ)M(ASIL$I!y#+u(IyD7Haw-_}@^6WdqC~#b?d_6S} zOn;^x?9s+ho1jjbT7`x_Ce|zJSpinFGVuqe$jngXIVmli#NDGZt0y_O4M2ofI{~uF zslwAe6;TY?VmL1>*{nM4ZrxN>RaNL8NyqNw)LA2zRJak>ZGuaRPI4S-^u`=@%X_-K zc!t&mgjSV-O`i-PtqGFQN81k{$X*%|gHYv81aZu(}sVNh6sf7m6s?7g5|^d$CK z>$t;2zi+*$NBzgN;8zRvm`vtzVG;)`sVROaCtD(06l&Mh!fqyFSP4e0sa5*3tNBV4 z6%-SiVR)w}n9g&$b6scStp@+^r>DK}#;v4QnkrYeYRPlmi1Ru3<%Y(DE?luk8$3}r zR2#WRypN6_@2x(+TB?KK>8ri6!v$kY9FW-M7m4lwHt$3i1g@V%cf42rf@q*G3K3N{ z$}kZgL5m}j+%$13Ae+*_10yIvp(yQ{mIB`JZl88GSl*Ef+fC>X# z26a!9K9&Sx)Ntd(?x}#tU(^c-0~L+t1K!>8mo}2-HP85&E+UCt(1MNLn^4pK0*S{05NCZQI zfT6<%o$f$k!1_E0KE!RR0F=ywDL} zJsblwFMd^ze3@2O^n4=DWcgF4`hPe($KXt&_RYt(or!IG;)(5KV%xTpiEZ1qt%>dA zNhUU)c=Il5YybOcx9k4Wr_QPBKHXJ)`abvdyBuL$gU0{O53d;-AR3nBuQQf2;EZ;7 z5`ZrEqQ>WrFIu*%K-0i=zL6v;ar&R z9YYS&TL$H{G}?KQ(df%sCqaRlOPN@AYNbJyJCq>*_U>7vv{Ht3O}&O4DJz=H{mlBE zR}*HWtQWH%xa&qDLp7(}wkIek*H|0y9v@Ir$trj)8Vw5 zq}l^Y3u8(R`BDt1X2h^(BtnjVjC$;dmb6D=84|Z$A3S}0+ZIgTpm^SptL@=d4mztE zznWpf)sr9LQ*n~}Hs$mH+y2PlpRXB^YO&rmB=^Od-mYq>l=p;GjPyCP(eD$QMkZil z!;f0>P%h%83!57v)iAeY*-1&w@NyZeXYuP&DUt4yt3TyUOOGIu!B_w!D88arV*urk ziI18w>}QC$OLCS=;M|+iadb|L{f;I42pQCA$;cvyH>u zt+O`8UR5lfl=K9bF-?Sh^!%)n66Hoc37p%NkqtUqOfl889W}}j40`$WD>E|4qW)-J zG|FsjO)_iS*d%~%nO(m3f@|8$G&{m%`P|)7``9H#+PVjBllKmj?)da)htP29U<_Hz zu)+S7x!23WJdnQ~#G+}HZm=EpZyYPBazaS~Z!eH%A@nl5b;C7CTmReGmC_j$oX!tY z^w$vu(rzq)x2$WA8?Ndubr}=E0CsiOxOXHyPAPLk;6175gx}TcLZ_JvpW)H5a87DYOfuolh7 zMctd^ksBrQik4lFYszL9yuyi^W(JCv`=ZY#;sw&jE%4Cva zRc>9_#4ul3;{1kedS-MA*Aw^fVRh`Z472RBQe_+DH!*xv0QVbI6ckmhQb4}c>^Rb_ z=s1oz=R$dfR)u2Dv9{`F$)=i_+tKPQ<20ME0hKizNn!}=>Kz#Gxr4^&kSR#@u7$;& z@?s%>mr(=?Do*1@KIFv2Fw|1V3{vBCsQPMC{?}ZVhZMwgn^HPg_)QcK?CTQc zJ9WW@fLyaW-{=J25U%Z_?o&Tv_!GYFTOv{T9uVT5i0Bgv`FWvXfd@SMQlY`N(=s26 zcif$l=Ubu=u zzy0VzQhU;Q2E8%Ys{0L-g!9QCFe=PjmPe~;;D1Ryu~@~+H-E#HfZwnsmH)5Q)Bnyn ziMxGMgJmt9T}e z_7CX$TiY!ZfVFt}qxGJD-(1b>?yDa2kE2y$KQII2-`3*Deni4dtf+-hIte3+5R#5I zh)y^w%!S-zI*wq^A&%F0*~7k8PJM-bsH05Fz<@Al4t|UQFC07xGK=tnxjQ^K!*Lj1 z=F+{R~a?g|90sKz1ca7XO~c^piRPP|IPC3aa$?jpm?f)R$y z6g_X8C)2wp6C+lA_G-tB@=H0ubILRM^n?>l!j`+stkNdqgvdfGeTKW-rt&>FLe0=( zs!nok230wq?3BwJ?$g*OboCWFLP4=!JOY=Atc+PzQqck~i-gQ@q}fHc60ae5X(se^ zyi<;$H6gWHQfd|pU2Su55~VYOS0+}D$v10(92Qxx&%8^$zYL-I2s#b2nY84~nlK{IWM(*ekq)*t~3Zggn} zZiC1*X&6h)!^95&gkiE2e*;R=g6$tt){6#cS+zaesTA_sKj&*P?egZ=hJ@}1ZisOw z9vE?!z?9fANA)3e-rQjogv-@m>9J+Ef5OaN-|=Qy07%+Kj&f_lXTz!q?M)MEw{E80SfH|@MZnI;tZ@j}8CJJmgQwXGxO~q-`@Fyb+ zOzu1w(|Ef@$A}$b$x{{RhOW*xx_EyN%OLnp(V8ADDd&I^z;@rTrB-Rz^3Y%>4KX*m z6uq2AxkgLR*QUY^wn{G=slxF#K`@QlNdBVGMl}wzPFAHoT|jZ|`b{`{>Y=rKo)C;k zN7i@{Ran4YffXvaKL_QcTlYhJ==;-@OsK_nX%+eh?`2U(iB((GXUdHjgzas$ihoD!c2J08lU!CYW zsX2FJ%tn`t@10yLLmO_a@XH!{Xz%M0s`$Jhx3pkhg?zN$cs<%yIOVE8y^|u7?9$V268C2oyxn9%&JDpiA=ZI0bR}o;wGBTv6-mBXZ**fl=`k~G72m1nF=@rnrSy$r5-zYfe22N$EI=emQvB3 zol+lJ+*omKRkdsGHx5gdNmENDvWqUPPqbA3$-eFN5A?qdiyT74iE>WRnX(M3zMd*N z#;2I-L$#OAneG-S;1Is#PeIiS=xVkJqYz8>EzhoA@H5Y7k7N$7;G_aQ!~u`ffqgP; zvAz#>B)B(*iJ&gxWI@D-RP3xMn@p^hTnKwd?(zF8z@8E1;RH@f;Hh0+{)*G zMHYt&1vx@ti0|}ncVz;HK?Ym~ggoA9|0Grm@$~}n5rp(y4u!~T7F?#;DrSut#t>G% zJsRzZxE!eaYV&RDuT`q^20DA`G=-uqzQk=v<-2Ar^G2W!s*gW5pTfOfIm3?Y8*+2F zS5RJPS8ngy6Z)VA^v7o25igGH4>&)uknY=9`k6>)cE^lOrXyfHnfAN>C-D%Hzib4xp!AEr>{GWOA-OU?9EJ^?JM>``CA+4%P77 zhrV2WLt>NW<(%7Z?cp&q$IR4nq2JHgORc8(Tb&@B?oUj}-KxNVFq`s!4ZRnj{RNiz1GedJ@j>X)DnKsw`UvM)noHpd-|AyDSWy} z6=_*s!JFe9*Y5F&yM^%epOw(fe?b_T{MOnb0RsVn`^K#PKjZcP`~Hlog_FJef9U$Z z>}^a;o&MAIzjbkoiYNlBt4lSGS@E1Cp`72A$;jp4dO@9$9uQg-%2lKWM{61}(Z(9F z=;VSR4ImAmSU%!(!nA=ut6!*xb-CcE<*W$0b`8U0F`~LoT#1}wY$t!OxHPna% zDWfvyD7?dH)lNQ(i3oq!UA$Fn4-85r&@ltvOIU8c_nFGWc8n$J+IdFyg zO>fIq-ZF=YKrPvvRLvrkj&O1X5bgEfg`_8L66W!<0o zl0-H>Qldy^Ky*o&r2PX;AkQCkLHx*ee8@5C`;l9Ob!ZAZrA2w=C9WYmKtxxr&ESF5 zQJr*SAZ{_v@o39#K%gZ!MRG;BF)MEQUS{CA=CT3n)(aD&$*(V|$NCN#i`N9g>(F0j z`SN6_k#1{bY&z9x)k@3)d7HI#MPtS#R0v$39kQ90JPRO2;tT~ji-n^JRB~;uji&T^ zf)I56p?5%(ceW+)I~s1$E&`96G{qM>6SNeFI4!`5?x+?3S{qShQnTP4){3}H&`9|s zEYjEVPOzCcz1ZHroS)2kzpmh(>(_0Ye+72f**!OxqW@0|@kZKgTj>dDVwE@~iKQK- z%IEZBVzibmRO5U~`+p5Tz2LCWe}k?ALfPHhgLnY`|HbHGsuPM2;v1$l{cX_A_5ZV6 z`=4)}7OaQPm}9PQJ`4&3(+vcZFlosRnv~v(r4)vgRPxVwG@6NG&C>A96)9J-WD^c0D+;%RW~oIs%fwFGg*CalcDoDR*8ACB=$ixx zaz%XxXE!%@x6k$OV>=vs*Xs#gY>DRh?u6u3lFB!<*Q%^;{WLE-S(J(8#hgk&mTCP| zKO2zmZ`x3|d5SMTS(es*XYck}ngn-hTH9?@=I^cy>pLa?wO_3KipBLwmGotFx9j#w zOrr?)$M5s?|yF40Vi@g%`frXVSel#Ib{ zFHbM8i8H{fvuW$)mSb1lhiX(iMzrX1I_Q%nxyr7vc|s>qQqIU~r#G`&8aDFV?6CPRjLPyC_A4|Ws(Fc4ki>_C88~rb!XP_dNl_VA z2-OcA85qk;`J%jjB8!vtG--=HhaPl71@@le!qi>k;oZ6u^K$MHa|^Ps2<$ySyCFX# z0>``*9$v%8e0)WRdOmlIgNDoV!OEk~t;B>1!q77j6GVb&z22b1B}c;w4oz15^smiOQx`+qI-HJRq zT(*>sMWB9I7DwUn2*JUmRx|pKG%%L2^v0AtGvZtHXSGQ0rz@7X@Sq5iyGa-o z@*p5$V<+7uU0ou%yiC$j*~L0rZr)8-pm2GX^cC}zaYWsIfpyEMydBw2l!GKNnh4K^ zw_sc_4rpw^CA$m2n=5MQFa`fp5^~MKG45oE<;r7q4=c>GJ^y2{b{sp(;&b?+9Si?> z1Rd}s4sHbu!Gm|)wrN(VLdDdXV62CG@+%^>P+586$~0!y{keNw4gHiWO7@0I=KN5h z$Un2!B}s*hG!4Ph&XQ#i*c_FP(tKQN7|g&%7{#nM3#%QPjWs0S97+nK)P~2+hPC*x zwv}FKeE;`^Ip3myr95<*M>yqBvuDxx45HBTk2lqlA~$MqR;9>5eJl4KREs7x9!4^9 zx8TFwvE*yh(wgxtaFE&ntH`^cz#5GV&dg{Ym!Wjlbr#Yi)EW&HCnZ9>x>m+Cbu^zd zH=RFM0>YBU!Hc^T3K&qnV7M=``?GjcRw>QWN0y&EYp4cbTF7Rlfz->y4!zgzuJETsETSoXLdbg_lPF(Vvh+dRfUtv|z z*DZ&KW+-fK6`de~Tz-gDiJtt|QZt!qrb}qWH^P7BwLPw1m%WDpb{uGtXL^Bbk&3c1 zUSqu7TL;$G-lqL9p+_p3+uzcRadu90gMkgc*(J7$(;jqm-MnQeZ0O#aiWiVZ6c?B+$xGFa&wHxtMGTH5<*1BGg;$2#7QAUWbfHeg5;-rzj% z;WKJM!B1ClF+$C^Q`MHH@%Q32_>&QkV&o|#pNPIg84Ei!!XN*_Pj zQDL=LfAg$H78gPRmn<$W#7ZhFcosu98~9K-uk--yjf;UO*M*(3RQ7!5jtLUzZVj6h zS7l6acRMq*HpP&r{;F_~7U*G$^jI++CoEno6i*R7L9ZHq8a+dNP?;lw*g2HC!rou{ zb_0ykbJh8O|2)6tT7ZGSGL+?R?b}GDMHhy^ztsK-#?FbGV?lwPWms*}pG%#-j&^X- zMKu2=Y@uT3ka+ORM+~9UxlfFi)T|`2xu)2Ri$s|(*kTJX&eI{a4+~RRQ&+O}e3(0N>Z=SMBWp_Q&q@YZriPm?p* z=3PYo0=s#i%%4a}J&_WHj$v-ShUfqph|?$;3t7q&xZ08mkB2)^Ez*#K?t!37#!iV< zJr{5p*gJYB&yB+w@g#Or>?B4O3K2KQNeX#*n=4xfN9j>~Lpr?4OY& zoo=$dO-sfX z6Z#ysgT`&$fv0u3%kJ$B&#o5p4LinHy4OOz>CRy-M>|i0UEjWgmU@HPejrUu-Jnd; zs@|@r$3J?hyLK^IF=M}!*(-iQkvm%-(ola9Zi}eG^lel$YGf%jrc# z7PjElNB@&J7)!^wgU|u(m8z8Qin)XQqTz}%Xo89RS7A5{?;mK#jjP0wL%>wKJW>Yi zh^nV>#1AX*g+!vmj=vuQ%p_Pj`02|=1H(av%Kxm^Dm{n8QN5Ws5kaPUfWb_^b z8voQd0~c1y{EePz-jpYVg&?+|hn3@i>y*+EO{|3#>;A>vbRn~!(;L4+pYY9zlLfXD z!5L$PdM#y!9DQ~T2`b!ET28KDeS%qg@vQ%80twvL$sEsj)z5sphePCZGsk=`Z65c5 z&@r#y@{4_ZTp7E_0bBODBPY8d-)YuHkZCd$*U#M76P+!zXP3#Uw%>A{%8fYHZ^>=W zyJ*ouq_YxQcb(q-CltXf^JSVhve$Yxo%hZD6mc|*QAmHBdI}a-x~I-fFF*Y2Pt{lOS$`;la;h6O(DoSniR6m4@zb_U)8=dTMXG;^RlGVF$ z(O@>FYM$#Oh?iB&8eH|q+;zd6P;QDSX{s^ku?=(M7xMg&ShB)$@d7t2Tz;t{ifi|4 zzs4;jf+@>xi)rL)3jJ++JjD)o<1n9Ss)yA$8ZuQfQZKylHNls(m@Clxj~@bzki3aC z_>~oDL){VHx{h6$nR~Mbf9{5-Rj2e!Zs#U8 zwZFN5w8962nYBR6YQ^IUMdLiQc#}mi)8?=QV}*nb>Sj4)t{;`vbs5wg&1AucW(JvR zu$peT>sFxJRX_PN)0=!Yu^I59A-o?`n?3AM76ph2b5~bKWfY$2-t(Hi>Uq z4m^o(JPuXl&wdUaiEo|`ZWAA1+~EK}RHa-ho>+}CfFG=GFTf8sTgIsmtoElb`-#xTO{I&zDgm$4#y}R=Z#xGK2|mVv^$GBo7twwi?lTy-ENRtHq^OsKN{M(UoyQKT=fC= zxLsF3Gn`wln;@AA{}7-tVu5723&ByPBEL$je4|BmxwN_RxJj|ayP~qjQcbVuytGoF zw31acWysfGdNns%#>KYngjVLXQ+PHLelarf%}FO7@cdhw)ho@^#SX7*H$SU1*S-+( zGy+OoNaxOHA>S99dbKZbGt=5`&JXF~@w4@x<)i6YudD!9xrXp7HH+01xGmR-0g~-W zc*xKe5<&UMjVShDf3!(1LUK-aX0mTF^{)$Qbz)=NX1TC$}g z;7I`M&+rssJjK{aEnDHADZ;CsuWTW@WHl-KBb!dlEs;>Chj&)_@p*!QH8u2^A2q5T z))t31wQPfLDB*1^6!Wy^&D<+V>!UM_D!n0^U#vzSRjMUEGicXWs+<)vhp!4|VAndR zz*W#s#DG488;wS&uX_w2^xUZ6=Hwn(?>_{5BzV?zvY?=vw!BmOo^3a}93`IdqLw>5 z)$oy;B>B1#WgEyo_0$ytplu^v-GcTJ2mRIgQbl(HYx{uF%?dk|P}+o!q&lF6Yrm$A zdN*vfR&HWLr|nebbig-AFp;BuMp#~ls9z6+X&mo;F{A%Y1L8N_4Qqe~SU0Wp%|Eul z|1==qEQ9F7--J~U=#N7P){{CAh;tH%w<3br&*HtaW%NU9K=eZH>45eU?(u!!0ew$8 z(L41O$a?TKBv3HG9lV>$`exP?OsJLgW(Y(G%t5Fh`ny}S?4Bqcm=MwpItVc+&|+oJ zKLggsLwqj|Oc&AvWlwu$FK-sY&qsW(43r4U17nX(E7+gJH7}iIpa%*F+gqV|~ObCg^*FAONaAOZsO6YeVbZ*xnKPkQ| zH#tz{rFPDLgvT~J5NOo2<7#0KM}e*W!SNAe>2FWEH0fv2DH~+3 zH&|#bDg8;jhkLlvs<9!u6o2o?8>zEz>a_<+>lCM3HlINE0CFW|(IJogyWmQO##Nr@ z#4kIM|6OKywTWpFXR;+-L{LC1ZtoHB^M!iDPZ_Y#<#Z1e5Z|SIMg2cZupQKBO~gpQ zORzOSK)xwPAjbB#Ot!`rhIZzrOm3`9#%vDEOqSnUT1@}(`TeiO*8f+Lb;q~6WK5Oc}MT>$FB3N+clxz(_>K_c)zY?BBFmp zoA#}wdiM+z+Rk4#vtQp`5T8@;p?=NZr z5d`VJt2X$9W?9ClJje4k_C#|QXVc%aCzwopa(O-%qWThVA#wc~4q?@O=ArIyxj21b z^^ev2j&l2&_UV9DoV{Unn>UC)NfSC-&$f1V-nd@|Bknf!2w&qLJ4b`hjW@pU0fzqL z@t-C`aW}K?FW7XS%TfMK1GL?GqkZ@H#H@bPvkEr#XhKI4c`Ps4lE6U;pU(+<{X71z z5x}nO=MbPzw%6#6BgsAjX0Mn192r78)Buk*8w9 zl9IP*vcLDwMQeKRpR5+fy>lwP*}Zcty);mZHk$QVg)tiLvo={AQ>e<6B`xpXge5Nz z-oz0>C@y70#E&s?#PMC19-c}lE^P$uxM_(pH4@##k<@?bMzV(ftbN2uYw6xO^ji+^ zoI;NW^h9H5<<7{eGg}xhj!adkP7r7F&mQdjEdBFuyfCz6ZIW=Ky)C@508y1QKig+f{9 z_U2vXy)D3~-=^K;>&Ky{%2m5!6(>1v|GUY|Rq|uwwX`*M<>~mCgTWT29hIc)?=^gw zZtt9S8dtS6Kn285b~`h3`LV|Jk|DOqUYJ_$`1+}<+iI>xeHE9`*_Kf5GKSEWqlU`8xyGuZPHSglUUzq)p}VxEw8&M?TSiZS#LgfD zErjehg?zMsDnIXVsF>DBSPwrt+s z+EqD364%xl6J5^8Hn)1@6pnIC(S%ek?9aWY{uW{D8htxpT%G^)+0S@Z-9A{5Ymk*E z6Aa_&_>QmVyVQShbzU50RAXfB>X4NdB3!;j61O|nliDRxs~*GF!gv7>e9P4Bp>41! zfaRzxAQF0JI=Sl8;$+NEn~Umj*aB1_!*1OD|` z-P`M}dwHtO0UggtI*%^@RfGixG3VhF_R{L!Ud^{y?lrl4xUiE0;|ADSv52GJ-WHrz zLRJi$EAjjIsWWK62(Nw(r{3f3-H50@9h$yYXO2JZUzHo>-@f@HXVZpaY?QP|s?Q1vB)lM*? zPfj?70wUyn*V5D(7)31$SWSy*Jga6s+h`bLWhY8Mt9+W=G^RWYm;Lr}{qCYcJml-j3+6)(!pv?X_Bf*6@hMiafTj!#t8k$?sicPl-+6LxRLap? zm~y?}K}t1Q1T#>Ug^6i${b)~JFugEu733FXu~=zl`pV^Pag%Kxg?Af;ojwC++J%U{ zj6#kH?Dy{3c>075#)(~gd#8(`RIf0b&8S&N?k`fDmyzoB(X}YPno_u$i7@ywVN(_! z6QlcAequ5Pi!ROxb02@iWb6(y7Z1pqpcm7`uA&*0OS77J#7yxQGKWq|>sw94zPNcu zJ)0pqn@&s^o2iY-!m3W~tMCp=iq%ctBN5{maJS=CT+A-aja&!t>Q?uxmsZ1qyJXKV zy?QM5Dt@nCEnajv%jL(_j~GW-^JQ%`f-8H|L@jmvk}5ZE4#01`QXc9sLwxKmbe7{b zSvm4pWMsiO=Pw|tX!t^)EaiEAPpw zof{$+Odg%3I<&2Wz@8#di9`lSO=rKJY76}>&P3x{t>`SdJSkU-X=TXB(9sAirP*fxCOlVOw54_+ z*DBvUGQ-a*A5&;D5YB?CydT|6ni`g-@^*nIJ28{!UYJJwLm($tt$XDN$p`jH$o@v! zliM`7qM|-lmZSCRquqw;Q_+;B>ZM%G@b8a~u5gMn7j|D$*`|b&ht3)?>DWNPV@b=R z-ALb1%TNoQ7ISw+Y)SD%%k&)K%q?1ydaiH;U;*z8QM~;`7L3-u#;74ed*hF#g)Ku* z4nf-JSf`>(VNX^rAx!O*s(T`q16ajt5CB8n1MF6!%=1saWZq9ly!C1AztzpYc$eRc zmZ1cJ^fex2LkTDGB%$U(;wM+i3q-fS6o&MU-ZAXErBrux{MF24wjfm=AXV+^sH^+P z7K3Cll7jRr#S?WL+O=+{F<_wnKL;`_G=?7!py7N#zf^~bR52XElkhXPh5=^us>2ML zzcvzGSo^ojsBb9VWd_(hAOC&KLLPv!IW7#+>c1vz}-DXkUg zY9mEd(E}w&ie~DAd|;#+e`&wvGPv=!pj45gw7bZ__t{5V+3PJlM#dk zM9YRIMN9mRW0lIoQ|#VoEB3e=H9`MSQ2U0CqCCXAD^~K_zizbdLaRDf`Ut zpee8C=%ofOFf`EIPNINC9%-EH#mZ;nv?J<(6SkmqW2C_cp4i%ezSV>?kN(p=%U;RY zl1anzsG-YeSIcPdzVE!=Aa{5WNAFTXr}J*U$R4#r^w56sz&=B#?F5&&mi=@{-xB zn3A!m^lI!8G!t>zqr&VRppPah5@YsS7ORx{FoGS+Xi73AU19pvSeGoCsrdA9XG1MO zRST6um&H&f%0z2Gu0112;w~gHBeTRiI zw<}srgfV+<0fuEWDHdxw>7o}h>B1N$o=@7LTMgSh{gK$dC_?{bn2OM#RcC3(!-_5Aq@ooCc}I`QbBC8T za0(r49=%q{r%quG_U(BhlQ@oU@6eUq#moDqb529mBa4FO&4H@RwNl3?2tw!MY@X)} z9_Mk~FHxWB2!-J?xZlyMG;5J|kZP1V=?~1e%sjyp>c#mxQ}%+Cew4dLPFP7z84oP5 zPF=RLV6vU<)mam=w;5_awGm7Z6cYMQ81EwQQ?#Eo5nmBs+9MiKKy4r6l%EOlNkv;L zugj0Fwy~^ZQK=j;fMeDTtM6Yly2N<$DwF+bfS~wfJZnv&T7pTWdKEJ*sqZ9-+$ex5 zE@Q}#7jOp*LXv+&90(;C$c=cEcV|ypSLP>+Yu%A-WaD>ChTKZU=+_)>D z72Y2&yS7hkJd$q;?~kIx@xJrPX@+EQ#G0gVa-ZO)3ze&DmH3F`QN^@LLq@4mW76EX z1H;ua^MAQn7J?BEQFSi=Im;v?;fv0WIHD*yf>Dps870A#Ea25hM_!^m;KH`usErnj zukVXUIs1q1MJY#=9jENn0*>xRArXisusbK{NoJ#)USAh^p5o9SZ<>vB=Ni#dY-lVh zI#iGUa|Z)cImdE@MY0R6+7(j3F3DT?F0+%C{pGw(W!xI^`SAt30P6B?S#ALqVYBiy z3pS~1YQH?zOC|#jZP(e#5*5}+WKhc`XZJkj%494nWij`!vF=@c@d4kM-X{Q=iQ*{# zPm9!ch5k=lKo|BU*)1NO*OMhz&x(3mRWhg6>T)wX2YU@5#(&am?0!IUvdXdd@2v`{ zzL4yzBSEZJJ8s$dhJ2<*5;FO(sl-^07@iDywi$F)Ji{j?+qS^p8&W&MAMc$iebGEC z7^CCQ{j9{^r<4Mc`NeItYZ@(vGVPqFuKybv%y- z*f^C%6V`;mZ|LJEQ>%DR#_KPtD=Jt>Gl{={8+#i%Y(*uF<=Ak~qQXkO8e7PF<~eIN zNww4P@2IW}s$$O`AyTylHYVsYac?q}SO|}p2PwF-^8oXhYvB{Jdp78E_|LBOvCCXcVTEh~L-)nIP0AjY7FM=ZmIu3eL?aZj!{I-Z z{{U6iPRv*ocIhSPP%^{yk4j!4uOyQ4>=D0~8K#4g_e4Q(;L%@3!*?hL^Y)nnZZy2G zZ@6AR`QC$fsBRhppWZP9qgVXpAK-yhUnc2w!_EKt_Jua?`))AjS$r;s6ne$yb1nEo zZ=w+Wlc0$>^72HR7b%xM;->fh3! z2wE?Ef?(qehU2m`CaPzB;|+h^%1^C{4;|UJIECfi)UCelW`9tu%;(viv?c!@%dbM! zj}*XXS>{9Dz^b~$m;O(zo4EQ}YCaeqe0t~~?m~c+eNdbxlLZDvR?F%K!&&7@{H{Q# z@iy7q>~%IzSugzYRc@pp2mTO4#BA8CefpdJ^$mK05EoY2(a2)8AQt@l2`U=71$M1H zz{&KnGJdYB8SaeLL9mn)50gA&hEj*@D2>E*TR&L!RF);u6G?gqvlyAE@d%2n@EUm2 zi7D+MIOZh2D`Yp=zG*c}>kQUa-*D+>lfGLPs69$xlJZ__=B07@{1cz4q zTZon-*dn3}e4u1syfjnk-BiUf8g=ND0je&jd^?)eKCMN7bv|q_a*YE+b@=(WEq2{Z z=^vCd5k~nDOY#bSYDsAMRq~egbdtWAIUleCS^82IOZIO;LD8qCh8u|VB8PPO)dU6SIt=z_+OihXKHgW7%^FDqY4Oi3;F;&`a=78N zaC+Z>UCR`-K_J^=t|vs}B=kOxxmiXIl;DaYdRdDP2o};H=@~ilfFsObdY6sj(DkS4 zF>G4Mb;wCuMcY~0@!ad?bzAWIwTvO;GPc!RZ=5@e00QqT6auD!PWZ-#uPp4ziqp!mRLrs?wFrZef3sP=|N51mLhG!HDpvJOn5I0C zlPo_5Z)a360G*o6t>Eou2|`{)yYsa)qcG>hNB~Ub zCyjZ~xQO}T(s&!qIDA|_3G061gZN@$bZT; zDQ4~re}`V!M`s*x8T*ZY*|iN)c+fLK;P2zt(RfhO*@)FN$ivH(r#LF2ZETWyB{g#) ziD6yFh^jylN#@Wm`BBJ@jhrkYg64urfX%U+A~SeLequA{X=UtEZ2_U%C!5;(!SG> zFB9vaQS4Q(f^cJDYVoPEI$AU+&nU`bgCO2!983C|3uO(A)O^leIu5iBJ1^5HX4o$* z92V;6q5Xy-idauaghm%AST=1b0~d9^NX)51Y3)Q(a!lE%(PB^wK3}OXE@Js8(7&q> z{sg`;;gOmkn3^~#H=0IRu$XG2><}%QgTfr3vz7A)mRw_Ok)oXY86rh;gpj#m^9Nei zvF4P%nCQ7$>>C$KdpwrS9xEA#G-Y*ggDO%*YB6B56GbCUI|Rry>@SCr9`rG-4j3Nl zaaglZ&irGGt7wBw$r3u8aQrdfz2*rN2z?o-_#fFfqLlV53m??R7AH>W1!U0Xs~NfG z0BK|W*&AOodB(7IwOIG^l*k=;$8!kx?8J1`BU$+c2Kp+j)2lze`mH_A_(94jO8&0d zB=Rc!+a<>9!7p!%0PYMWbI3`L_qlpp8jQ3gV^l{EM!y*NEjBF~;n9Ox1@6bNO+p!{ z{K=7vek==wc$z4s`H3;W}cQ0(_fGR^S?Y!GaP?U( zbI-a4^rM2BQ6w8;;WQ9e0dno=t$U0o1MmiP6Ghmwfo!+BYtg%*z8*9Pdqa z_)=U%+KTyNYIH?SnyCuBkxeuNLASx@n$iTT9%d_rZ!QF27K>iCa1$Qar9=8VTC)Fo zQ^PqHriOh6{J0`<+y)8tAk+FM#|&>D8N7uO`aeRqN;Ec;lJCd)^(Q0S0s+^~X022n1aG`{X`MD>@v< zbKfcKoaTm{;lAXfr5fm~XXVb3;a;CjOFasYQ1P%Y>WyQgcd7nN>FW_;>l0pU(8y{` zktH>9(;k%GbkCp{jJ9clsbCPqbA8s@oBIGcMo(9OnKp+w zb_Tl_-!R}eGjJ;dKi;h9_YpVf4Wq|v`1NBNjntOeJUy`E2O%?dDF|8PPb^NbB9wFj zu%s-`^coD;@W76Uejh5x^k^~zMk&bBfPM_LbXbT{c>~H)#L`t+)?GPC*0fSEww(Uy zAIu{VW>|q4Ih;6oxam{h7vV|EoB~lA)jv(ad=E4I-aG)D>DNs_O1~}vYfA6uhMh(O zYfA2?m%*3)9zeGU>a0e~{0LzN8K@<0fCn=zWf{C~R@$#oR@A>*4CV|MXi36s3sIWW zUoD3(+mA5){5`^!mN^S%+6>H@H_#C^oxw5~HZ!n;k&t<{4D67E*&GFjDe#nnxwm;B zWSX^zINd~olv~6MWAqZLtYoy8AzI=531JX%qPlggVKS=mJ2niV&Lr3ryCgtbk~nFM zxXZJk_K!`}%?S}zw?5Tx>i&f@?J=CLts|>2?7cJxbXkHj&hF{{$SQXORs{NUbYP8nL?PhJq_p(z)Tl_IEDgqMi1=B=-*1@OmCX$-};^r zK9#_Zr2Z{&gDXnrXOwjBMJQ)^fD3+I0L{kfKw5KIXH`SB5y)#6EwZSw7KL!vrsaO3 zHyH?Z3OoY4eOXsFZIR2+TbFCh-#}Ns<`^CU@wRaV(zM6C{)h%$|u8 zDzdp|cL+)583bldVtjw8*%=*RC!BpMQJeTKqm=m}a1RW}vB2Z0Ea1t*3^KW4QVv)& z>2d=R4-iiE~3g~H`@%tgEZ zNJ)o;WviYreH%ZN8h-IRws!d5D(+tMMvdqV>EK{>P_;n)s9l3O@_;==eL(mg1)fCL zH2|v>Y?G*+_tWk4Xgut*P1bJ=kg_JAQoLM+itWIwzt}c&`?i^-YHf} zart1lsDdk9F4qx*L!xh=z9JzSUwv zT+%OOR4mW8Y~wF%s23%u7vA88aEnXK>@YS1iqOby50dp)$9B}`xk}{yMGu_PL!$14 zK15$%xZ^}K&3x5Hkx+8cmSo6#3VZ@O(;>$NO>QMTXv75%iv+lSI?O@43Ygk7%Kn-K zlXjI%xVK_UW^$fA8cSY+1hf7zWg1##NGz!oZaM7`wqh&#)Z=|0OTkuYc*mM%94={@ zTNg`QHz}%o4PI1mWyGswE628GG^XUU8@>g&Zh7rc@AB=qay_AzuDlHa*~_r8T)>P6sxRGK z5Z$fOW$sFJiU(}Z(Sfr>mrrZ*3E`P_W=p}-Xe;$NvS7sSh|B~S-3@3r0uxnq)#%#| z+&j_wsZTe4U2&T%H`euV6|gu~{eZJOY{#S>GY9A^k_p-6DDdAXd&ehDgLhlAtS;MK zc9(72c9-6=ZFkwW?YC^(wryKIy=R|^GyBBEFJeCAACMXO+)u81WnOE|n!DpO}gmp7YCJif#O@&ExIZ<>uBkOVSXaKE6l&}9f($RF3;ngtS z%FE_-YtIblBN3<;1Y2E}Y6brBfamV-Qukh&oeRUl=juw;U*XtA;>zWwRH@oh*~@(- z7JQ46nFei*pz4yPLLH4b%PJnw$zElfGDrM00-578iQEOLU9?d{b^bH%2aHa>i%dCo zoWshRwZB4$tgV`c!g?-~-vk74xl|J4S&mW>z^-+Ckja=WeuOg|#9gakSSPS7@(%W3at!_EbuxbqgK^Sn>_KbOw96BK*X(8W*cXSS_wx~3C8XL|g)As7+){>aO=5QpP% zO^#owK{`?E4!Ce_N*WUWaMYAFgv}k>bAsf87{RKGzrw*ar)xM|cxrBVG@0)jX zz7}D7W%8rOSes{oxAyGmopfUj^R%F}Tq7bxg~P^*uZ4)n7S4HcLw#%MS4)}3zeee< z0u0sAP?Ioyk93PLFJseWTFRL|Mk}K?@0!Deq!JO6on1rgG+=>Qz3V(>Z*#7N#<$Hi zeCf0*{9`uFe!^65chhmK#hpyq$qNggdIYA9*RP>A_tuzol|uOZN%RO(R|-CO;l86 ztwAmrVw-CA3PVurYPy4|aMzWuaK9_l`Z*Sj4t!vv*bE*l8!pthDwnKB*qTMw#4ks| zdicPc1(j!nULb$p9KQrK%KuDrdV>))ICc5-{$r%ov_-zr(2Ue}TR&z^yL9M{%r%;=SaQHs8F^n$$J6Q?09CJe^_XTaNt*+Fy;UwpOll00axu9KEu zNig;JM1xfTct4;olDUG|w1z=4{109(5w3Db*YE^D{V<=BZ1iayG}w z06wX?_4ABHWCTXad-PXWB?$xAmR0jSBa^1|o?T+wIL6MtL>x22&ohZHQqyU}W8ZcZ ziePgqv1z}8pA~!_Y5(69CeOWzz2LdfnD}23WbVH~_8%(@z{thyzYB~{9G?Q15OT;4 zXv_i{#N7`(W1~V$`Z;Ce0%%;cf^d>QTif*kKLki(*6sh8@>c~?_UqY|rFdX`XcfMwGs-xnJ~*cBqX>h7H+%CpjP_Ot zv5Nd0Kq&^8p`Zc&{6k7`xiS~Is+)SM*@YZ7%3p>BQdH~QqakJxH%wzC(!cRGj*qVIG^YWO7^<)xfBgi@bTorM>92!; z>ePmR6=r%9eterf;Ovz3QtnG>W!ftqZyrtk(A@XL*|zKI*XolWXdjO;AXh&*#du60 zWs5o5)D_7#27uZx)vXM9%G-GVA4R-sRLwd12MEY5HV6p&e_mo!!++_S{~N8L3iwCW z_+JFqVvQf}Dn~fJf7!>R7D#7_gh8}|;Vh&W7M1ddw6*D%=4q&j3hEaQlOX1^60(x^ z7j3p%+Rlz`xNkD+qvat@^O+&C;TCLcr#&(^vgA*WZLilJ7<0`w8eRk_FUGm-idOU;A?_i2qX2zC2LDOEGHV@Wc^mI;E?@UW}SQXeMRfsdYZ6 z(!L3LWmg+=CE5P!9o3ugH`Nf9Lr@@t2P0@|+Z|wSn@WJA?GA&Zo2G+fLaxOuQ)#szC#>`=rkpJFax&L*aA zfr_(ex6Yr|)_S{&60)QvB>Fnz+Fn)0dfCeJ!m?Gdp?yhPk4~|^f~nC`MaApE5p<43 zae2PE2G~^Wq4H2Kmmf16b3`0)SFO{iUrk{%yw66wMW*J%SyQZhbf}xNr@O7ALC9ZN z+RVGWg~njF+|lT~Y0ZoZ%V#|tB^sK;T+9w&ujG`n%pgN57dDsZk2*J{lWj^JL}hX+ z7j(!o%JwfD3p-T~&=j_ladSH#L#$?*#<8nJS>C^BG?9&ANknA9m4RJ6%GEqqBYmpC z5n-TVk~(PBu!}g~s~(sDGlRB{R@vBR8+eFxia}vc1P&e#;W?FX7f2a*ELu1~%AL!m zXIPx^Muf4S^dB0c^$T*D zaK(85pFf8057#_nn`e@ygt?S64p;+tVVgSoecxkXw;juL%aoGdE50%9>3mCZ6Q>U& zwMNkM^sgdaT?b+XgD6oEQ>k8pC1oYNhfa`$WS=<*d4Xxe5PB7*9o~TSw;whkZT*sz zByHF<=at31kbQV$AZX`+;LY*BH&uT2tefFXeHEJ0%^3$6#=k%{k!qcCGE_Bz(QWVyW9 z*^llhmfW++oeuT!2i-g>idEMLZiK4QBLrD*})L%BI%NdQu_|8I5Im-@ckt@xuWR_;@`4YG)^U}GR~h? z5bVdaIa~^*gemc}8I|W!xLw2Q<<8H;GWv_m*|Q&>k~N9O{gSFj1qtGrZA{q-CMX~L zZz?=x?rzBz4t2WjK>vh*gou_~_I$_fjAuafgf>TGlN*fe=m_J13$#Wm?Q3>~+igv+ zmIyailB4$sjP6~}K2Rodgs16N-Op)wu+l{((Z}jbR4;$`g=Tx;r)t$8O@Q|C-MK7b z?R9l!ibtomV+A28T{+`yVFBzE+;`c&&!^N-?h)T56tOnD?ogFc8i2nD)(UHRd0OQT z%X$nRlj^lHqGu0W=X<1r6e94CBrcDNX#$t&!n~W?X0vKGmSy@eI=|z-8)o0>J3aJ=UvHN3rbn#QCrrk;0BSumHC* z<%p!f>T+3-LCuSh{1Lbw9Q_aEhKhQ3fw$7w)L4D^m6-C| zI1zCODL}7ZG0?%XM|S*VK8w#3Pn0bPZ3E3e=lGhGp# zO!5a_kJkJx1ZgA}zn)7*)2y1R+*jKHAkY_hqdln4n%j39<4OoReal*HNHtrR=!R@P z^j3}(>#u582<9Um)_-JY*&XJ<(a-l5A^S*gRi~@hp^JaBa*75yT@!7BAt2_Ga)u?4 zuyRIT=<%QUx-Wm=e<-#4CRFzHH9=Ee^|cB`G4vCpnZ+U+^oRIRJ$OPhI$VRuKg%0Y zj{4nDf5IEo&#;A2BdYTKa8m=$VBEJs?OG{58&oLZ46=@$gGDYq!XH3Bn}^+%n;fW+ z4d94m2@nf>qg+ycHf-|=|9116D@*T0gBa%Qo9vIkTB0R=rT#)7Z$s-&5K&YNSxZy+ zIr@y9J*8e%^z--tQ0W7GqjkjuRBSdXHU|zj|GeqL_nj%qO({sa#g_0-LV@QGG{h8Q z%;e$@BV6nw8(Gp6WMC-GRe8K~4YtQw-lwS=kZbktWZxCj?a$ck#VhiNWW5nI4mV&l ze%bwr|5F6}r!W>=yC|}fQe;|MY_$?}asZbqPg-pZi z>mBY=^!3n5OpUizPZD}e1f}=|DhPLhd)_jt!qSyOq_BWj0Z9GT)Ic=lVT%`>Zqe}r z6C>kJ2=2I`7&maEdSj{wIdAa2dS--@Uh#*73I@5x*8V}buqB;L)05)DXQb$rje_=7 z5a+-a;)iXG%8@j*uh`sIEss8#)+MGV)Tbw0Iech0j338-XL_KOJqPM?f6y3r%j@jE&@Z}9xpNU1WaTIKh`oIa?r)s_J(y-?@t-*Z zP3}3pUZAlKe-AeO;_|N;KW6Iu&>0*?CfqSB|%KUmm00}GE9YlFk<~?kgPamMxDy+R1Alj!fwx-W=xUd z0NW~_z`Jdh=YvGN=K@>GG>>z_!2MNN2?swy#+?RMo}uHoF5HH4v(52mZ$H4Hs#(1N z0gpiL#0S@{t4V9?QDRI7nN8+mPIZf;z+hoDw4y9FXIa&QV#u(?751@a&eDWf_eNZ! zX_qYf{rT!rcxJdk8G9R#6B`F6@0ai5O)>~w9jiYixMnNX1CjwsvL$EBe1|)-OhjGx zyq9T7!%vwPqjUQqmY|p<8u`L}Or~kpf(U>z8v#%5b=eGVVSF2lO|lwT7v|IRU$Fn( zrTH%ng+KATCKc{qm*!s>I`@A(;5%Bl0v!KWFoUR}v!TlWoz@_1=mhw0WmT*J>yG~K zkZ;z&m}uCK5)TrNtjI*h)aS2yq$rgK;Ru3)T(vZIO-5(!y0W!~-PlC9w7g97T<^Z) zuAwT-s=uVJQ@y-h%4coGpmSw2Q+mU};$_M{kD2qiGbyn1_v_}b?@ABD=Le7yl&-&L z90->iZ&(Yza*kiKP$xe^r^~>?F=}5Jf*8*+X5SElW*-?sKi8%fvSHGy7sBJb8ScY< z-M_`WS$LqoNjdOEL#TMCg@F{Y?u&s`?yf0;KsaYFcvuGy4ZxmLik29f4GS4zjk0vt z9YDj)S-edODP{APU(7)%o3VWDG!9dP5Q`ALCq1Uyqh4Q(sT#^uKd zWA6RZ>m537X+Ymf%52HO#Ajy6#C~;}q$sjWN#2sYc|Fu(d8gRysKIxFWD}EF>1OdM z^lJGV77Afm!YR9e?iR7o|g{a@7yc&hs^W#Zyw7 zN@AjVZgQg$apl4$fEC3qiv3Y_?4bSmiA6qA#`gr&X&Oy%f!37Ah{+M3;3wsL6xMqr#`U}AY8Y#=FLXZ^x9%oF7FjzJ1b zDJ&2Mp{tcg5iYW>4=Y-`3TX+*>y7VUF0Z#N{#*i#%`k1vgwy~0>HQc)>Y{@>p&)HO zlBZ6)z={!YddEVnJES^52B0IcIz`c{7k|9tbI3J>To!p`lIIVy-sjRS=MKem7jrS`en zt8kkUk&F9^<7>MM)>*TU1?3z58>bbb$Fu?yZOHQ=RR!WpK6$>Eu(M{jE^1}HqXDIt zaPJ0L%Zbg#E~Z$QRK2x%!~!?|;q}xdCeae%6UuJ%RtG$_P$T8fnBNsnQ`LmWR?YKj zauzHr_d*-$iTupth2wRp1!VSgcIKfA&x?&?&B0i(!CQ6!ZLj%{#T<)WXKR*Qif!dP zuRE>U2m$O@(r+@t3k)+QV7ZA5C!5X9DXU6{q-=~6h9CPa)~DLg2Gn;*53Tv9oo8+! zW(9}Gxm?gMx%%IUmn)0y?gIsrG#nkB`?kA3Veno{XFCr4&J5r%lXcZ+(b%=h-JNHz z(i^@OroK4&&=k{q?MtnkP>whoX>Du6OO5wB^D3zsH;%$OXOey5O_Yk&?2X2lzY)b! z$PKiAGxOV9TD$qKSN&Qll-@z|4l>jdsxg&56TQf4#F4{b``g(r(BT|ys^oa?JA-(_ zj9z7x%JPbv;HzDaO-q$}ew}V8cS+sdV3Ii{$`W5^1Ya%Q(;B~{5@IU_4!(^mO$_UHYbfNlF9GPkOEX`X1)^JIS#f~+?A zK#ykFEQSgzDzZKsDHA6FmD`k+W@whCz5W*`nRc5>^^Sb~7)2=_g&WV8zzS~5N^;B> z82mi=uuKwg+*&{kOYKFQExVIVxv^vNBE4lS7ZfaNKS^ukeXOx~lOM9ssYrvy~d z757bcj>$uDRy4vY3}hyLHet8jaLVO}`ef4f?kOaY!0dLy>vdVSTv5Kv4`Mth<~$vr zk~>jiuL~bR1JrEKdfbC??xKNHvGY}PXNWksYlya-0Qu@Y1RUmare-;N?Vz<}2*^0F zbWb;$cv~==a`dC93VZafTkySJ5K1!ab25`Qk_S>w%g1;?2%>h##IV>=*m!`E;uv|_ z|5KAU{y<8!13vUl;~u}tzPa2*4lpzPrrh?NB+?s&F?%a7U^5i=r;t zN)YU#r!^Kdm zm$w7bD_R*AT5GbEJcE!yse}Q%!;E?)v?ytu6e(i_Fe^S(Y{E!t7vIjO|G>VxiZYbd z0VEO5qUyHzjxNTmFwlZ4s8KTH$UG}|hUq;qjJ|tdv z17css+G{b?ydMg~NYoR`TbcPr@vept?Pef7;PhE|Hr}Ne^npy*QEMKlx{ax}_N&64 zfBVF{w*TXeOh?xr$v){9{R5}wIx_ySA%e0~D3hK^I;EO|WzHfWS2(lV=o`G?>^H=E zP2SUh198wk34U~>RwIL9*QWttx=h1qit-IfK?nA{vpZn-MW*bcz-!^huFP5XfX3n` zEv@jUN@vfwr*GOFYlY^eQ!JoOg6*a3h|uN6p~Pf>%G9P(AZ!gf?{XkZN!1QdY^phk zv%qnh@pu`&&=vau(db*HZJ?R)#2@LQF0}z%KY;X(iFHp}{iafrZ#a;pp!~)@K{?Pov)moUF1%RV6NBz6kB{dAhqpD;tE(F;K$%39rrU zs)R>j@TY~L*$Gk%)8w`q#zFzZOf}+K7SY@qBEPDEvrDtmR*N0Do)*zi8bJ<=rxx~8 z!0hOmeBFLsOjfSI-%iO2a6I+|16Q810|1wPow|0N`Y^NY*=k^bD-6cN%wLRn9Two zGl8`CJ`PK2j?-r(6*Nvx%DL^KenFcWv#U4VApeDS8i0oL)s~h6o_z4o$b+N;1YzTZ za?uPUFB=)lnjz*P_p0ZMa=@C|(xnXVy8An*(uJjRaUo%!aCiZeVlxF=Wfl&hPX&4_ zrtkWDpWqPS`l)eGGc{~oZ)3vjn_$mIVG=U@KtPb^f<6&$Ff?FZVnw5YcwiD=3V)y) zkH*_Jn0S<i<_yXM(K|Z=Lvu$}iyaH(jX^y=i1MezE?2m>{YGyRxWd2A z_zUtskGqF8=nDt`>;mS0#^itOXG@vn^A} z)nJt|q`7kVtC6W0-^s)D-S_9y7qmYVFSJ?}cWVqDB8?`C;nuJmUJG_btQf^3T1b71 z!>Ga4Xd25TG|53nSL4)@(5k$-8F8Fa8h(g$TKj6_Bk+{j8aiI~ioOwSrNv0%d z@W`Oy8&drX$ruq3A*alr_pUUpP56ujT|SE*sY&wf$h1Tr;S37*J&^V1u3X!%PZN}- zva-|we#P-<-0pvFn>&7yzm=KOv2_0?IVN;FbUQ%cC147`qL-{TAjx_0)zW zDdpXlia{8K!nbZ>pTg9mN*VJ^yTaLK)G9RVU5}9ywX>{qN!Qwh9;QJ+ieI$eoV-6P z6_WOKZ8VTgW>`aQ)I{m1$~f(1XYM-*wuS(#PZ)24;?V%S4TP5ilp8!*~-uJl~0!j@0J*l1|?Xk)L|S<0wBk>0$cyBP}k zNa9(R(I0OQnZl!(QEz=qTEW73m(6d!f=3(sL^Ix)wGm!eiBM=g`{k;mjD%fOrBmSl z-Fb8?+@O8v1pTb!{gdcC;sLJ$SLbV?L zUR;wQ0UtQraZ&a0>;4ACeTsJC z&s*n41{n_X;c;J7KzO_^jOF$^M0kgU_<%GDHW?4i{zUwr9~#0zUeNBp4=nKCU+F*c zaiwhk`Kh*s*8eBU<$wK>;-;iUgy8=ucv{(2`>DAFet2<|EEi7%DkG!AZN(nU%BSb9 z^Zeq^jO6!6Qk!%kRqH@bz?Zzw7UXBYu>#@CI^>*mNIFQfHw}_2EK0beC<>TY5jn*| z;`V&@tmq%St(bW?-9Dgs8+>7swnl3?O0(x?>WQj}yw8;ncDlnEM2?bY5Ap1*g3(e! zgw0mcrEhF&ke_4-B~BMpyrvd6)9+5NOxLF7`d$HCoW!^V1lvZ}qXqxWHJc~bU99G) z(I@!3X$Kk{VnX3Jl@Uzw3^Ip#|Bq+$^GRO95*#}Be=pj9b*9C0o50S-?;~B`p^Q3WF$tB6Vt4+o&xzudiD+J$Ex)yqKC&c4V&k z|I;#d+n+msJ$L@5`Mh^Q6GAbnOim1mxeFpn9Np$&U8qj>iQMlQCJ!(%u#aXRIGzM! z;T?U3MJTze_8IHz(&YZsuxCapyeq>>txSugJPfBix=q5*Nf}_dA9^{u1;?1#=fV&e zd~ke?$M>z;r*s$Ui-glxX2L1Gzh%}}`ju zey7oP$HDMTZ}T@4>u=KWmyFnt?`k6q`SMq!@5+5YcZH$9kgCMN5-3^;yGa@*PMD;J zafL8qDEeZDG{P98=T8!lC5_f|ACK>HA%qdjwNb%d(UMg?Kpi9-_Vt6Vu02U>P^piQ zI9F_7T{pFPQ6i1+)(!!T4JPshM-44^X(LKMZEE>2-kbiO+Z8^1XZQiMT8DeTAX)70T084UR9FYTJ5H_lrhRiR(bN zGj|L7x+whZS3ukx?#-HssJaZaWZ~JIL8v_Go3)+kNIQ6ERr;Cd`^n>U71HA))J5uo zm8w%Y;ljqiUD%HKY+*=s`9%}r9P7f-2~rswO9bwANSmQ|5m82$!GF9G6LNni@s{BhKubPV33ue2B2~o?Tm^K;x zA0@IOFWoW{e7e(|St;V1J=&z0e&d+Kvp8Bw>=0IVmWM~hVIDPXI4UmqxN&^aTv{<* z7U%8pTgy!F7vszj(2Qz$W5O-P1AtOUxoKuHudAILQ7)_ArlO_(gaD)gZz@!vNY4N^ z{hCLPart)#=#Xpc$WgZ@(jJTZFZ-QiZ4`u2$dj-^f)77(v&F_faN9j&*x z(Hdc7eaaiRRr;Oo4=cXuI5pn1^!jKU%U;60b1G}7G9O8QLiMCc@qi+;*^Abi9ttiB z)(;(Ij9XC;gdvf-4dk11W)#NtRm{lKN}Km%MXV!>C>=__A4#hL9lzoavfX~5GbMOj zehN|{>zI^qTUMPpY{vk#3c^}W`F4Ib?o_I0*uaf`>h5RwUK9}_Sk2}e{-R&5L%d*P zl0LLr^_OA&2bD^Rg~VkaACYlLrw~8T4q&2}k{mc9LY63{VgOe{`;##A)GCC?VYy1J z!EKHa=bA(jF3!=Q)3l2)4ecY$5n%|ft(?6N&l zvkadrl~Dx6G%7|$S_D6Wnn7Ve#dK@)<7pS8{5e}1)L_fJc(ZBi=_0_-x3d^}%kr8c55kL|%cRM4I2BhtiZ$hV~SZRvxZp)J$@0zHiN>k#`)#stnd3 zrEiwF@-$VG_$8ZtX?Bi#Qk9j?2`Gl?keD6hTFno40tWePKwE{b3IcfJ=6S1_3-%0h zmpqeO&3;@QtwPi#k`5E#-CrjfT;oCHc^F2um)P?zri&`45T0ix=wrE}WR#C4`b^J` zcW+zIPETk)D5!vX{ENQBM#O0zRYfihRxUt3#MU|RWX#A1*S6zX>MCPw$Z%=y+K7t2 z95-b_%Jf3mvyYPpT%4m;j%n0|lqc>#81038rvb@O=RVT4Hj~z7i5MML=VkZ8qZZI( z6np;IdWX>7jI9N!(Ma4}u?c6xW43&=JGo@W0ZryMu$<>3Q$Jkbjav=lo}uipm?k9BIuMtp9-uN9 zduP3djcy^G4fO z;WO*=5M2Td^P#XvGmdHFBIv?riv-a@VOokHId)u4^le=~suRTbp$~1imgnIedAdzr zHT{XGi1ZdIR?gd5SMf+xKQ8@ZkknYf*iq#SLi)@@HzM+V>_9)_@p$7gI^ykV7C_x^ z1_X+YCO@(-a4S4H9qql-Si8+}QEu&u)o}lgCV1W>)H#v5zm2Fk4;n46DCdVb!ql;| zlY0VjTzInGU6t%gHG)sc$Cs1xRB(LEF)0u^*AwnyAPyaS4XfO?Y~P-u_f!~`(0fvs z>snIndeD8+?*k@#wkX{sFMbrjd)mn^=U*sVGulPy6X8Qr~15 zCa}YUo;kRlInt%1)_a1VFAg6qSlnQ|L;OAo8~A{6cDz|m#U>F1Edo=gd1JnvVuy7z zLuPke3*ny?PFWcMn*59^ODIPEYz_T*G!`O+m6pl%*`SAerg@=YHlwOz*0Rjyg@;h z6O(OpDgTIV%#Nu&Biu%bPLnTJ7l`ntAP)e{xXGQkil zsw_hles9z|sHy`lh)D7As&551hLe_}HyxD?-44caXGlkip&a(qou_y&0``~}-biMq zB%N$=ht(Odtu?yT?zns_DqhFk6{&4=oMPAN@ZO~v#7onx$B^3;Wvek5=tjE(i0>bG z@oGIcu-+EWpmWsnx7*h_o*E>89=@~Ll!vA;stvrkF__gsoNOUzjnvTVsJo>1Fse*f zsp{#c=`J${Bs+aMOeR52XjMErqCb@AHZAA$R&8NxdEqz27&Hr7sa4DVl3+5^TO!W# zK@PlVbM%=Oa(^!1T^l%=Zvud)owRZU#J;iOu^K^OFbun$UGuDIZT@kx=g@OR+WO>s zmU>|pd}boJDxJ7C&b0TJCuG#q5JStH4ZJ}XK-KHOKe;4n;h92rA$@b%pr#3Rg7o+4FXiP6PTYU?R_yl4B0_qeqBgip4;Zb3_bb{>ez+ z2a61>(@zK}=qsSYE+TTp(^$+Bt%(xxFevA`yD~@z5`BPla*i(rJ-&!o4-y^|;FFTY zE{sr~Zb+mYyD3mc12oCVwnxtu%+rc;O>gUVoyp-?Rm=e%hXZ!v!wxaYqx zdA*N=(;6udXF{u{+kG(NZe?YT5-;HmZPwk|AQ$hLoBBQLv|)DqnsyeMlsfynC@&k&rX!- zPb3M5FUEktiXyp%(-TRqr+T_mRTM-)QFI5R$)h?)E57-d>2f-mHt8p^nQ42W`}_8C zw7FM~^wT#u?6|Chmo=He`A&@fJ1X@4)yRVWZuaGEpTskeA^Diug5K@UjPH;swATJE znGn~sTbF$5q^M0h!>Z`5lXXSfDVz0o+_9&HE5-xX8x+>g>0aimDb8C0Ym1~)C2Nb6 zQ%9y-hr0rbU;54MZT2SyPUpmw8`ho18=}WsMrIHF7ssY|Ec6%0QE^XN&(Kavsn^jN z&%JZ*(&&QU*n+-?XIK4 zi3CV$B_dyye5=xao>1z3`XE&!H&^feY<-hDi*0)gwf(l^5I8#idv_cAI?{ib+xlj~ zA#iY+SE%=MZpg0VjR48zp~Ln&G4t=`{tGWU)@1H( zkK}`f#Wurn&)p8-L16RKul^yI`Cf?WZ{*)!Q=#XYB{{eGAcxJ#D~SY zd7^E_)Ct3+azIunqDn(swSDD*NQ+clr7CH)be(ADN+nL&XxB<6TQ*Et^#k4t-DtOR zSi*L_I$oT-IdmBA8Q7|DTQ(_7dCWAG&G8F$3_{$Q8#r8*Ez68hdXC>EGAttQ4*@b$ zbR}L(qHzVLZE65ug)+ZIMRB=9`P%$SyQ&`3l?qy)Dw{+`n=Knspz;IY9il~Bu?q8k zXX{+FgpMJt447D9jJDa{-?^@pv5s7<*4ygz zHX~Y0gdZtbRb9r2g!sxFh_|n|v#>kS%I}6)uy^vXV~%>tFQU6RJC_Lt|CThS!$p8J zVOcn3U3_H3jD=aXyATd9%HwCjd+Pnn;fm2a=Dz&(^g>}A4ZOa#cLX#tp~?iOwPu$W zkYXYQXK)t+-A^ygd6UA#nnMFG_P@>hYl+Dq#@x$D(PNGAchz4)_I0#(@r60`K>>@;DSlD!&lGg?$mb|UQFb&jN- zm3gRsQvT$D^_*>lb*y#7a6zA9=ub*;DVbiJAY*)^=``$gR96aknM0hQ2QU;r5+;H$ z`4;5tZl7&uA?J1?Zaw7aA;IhgTp0ppi=;2XZgZR8tZNw3A>f=l5Hyh`k^QnO5$ulK zP$CXCLKFS4@ucqRt(^D>l&OqY6_XYRxsw?i8_*luBbU~fa%9F^dq03)x7!s@vTxBq z1IbHLe1xWFS3AU^71(K`6Q~bg_yOjvKZ6%22 z`N!d+e<@#|s0#A@)2e2eJoKl%c31pxjiP~72qkW6=98K|gNI&biz%FU8&wzfE|J@` zsz5M&gPX?DeUb+wrMnnqibX9adc;+MO$NPM~O#~v-J4$ez zl!d*j$y-6cxNd?Vj&mM4{1lW*NvIc|?%=D>AZ5cEQN*Q?+a$g9dXk&jIQic*2vfnF zXIOO>xroqq;|&oJLTw7y)U%L1L>htO1I#MvzBp?^r@kQtJTP(Bj{_Y;*b7(j%y}XD zo_eW7#MDt$qhA)XLmhL;ZP6~D)Svz?icV&vP)cd(y?nBtTi+_qrI$rKL8Pwj9Pnx=3y*dh*gdy5b2lWqK1~k zpd!|8_SNJ(Xk+`@F>j9PD`QrSwE4(*pQ^B7%kEIJ7>FBL3+r3K$QKHhwF0^yEM}TG zdzw_+Vyk#pu#(*Y)-G18&7|$r$)b?~gT`Il2ABqlR8&7GnR!7QwRsfWpZ5fL!(cL{ zKahoKol1fbW3$zq(Muc$5@PIm8>#CS#@7Y&;5os{j)@23xvCD9#s%{<9DP=`j*uxW ze%lEVazG?-uCi@!C+MTfl>6c>V zy;zuL?I}15aYB7D@UfYL5ijQL%+(@z2IVlH%2{j|n8CmEef8xDj4y1=calzZ%zuXG zIFyTv{8E`Pl;*m(Pt`UoTkxnB`YR&9d^+-o7L=2cEs%U{_DJU~>Ke|^8;M2l5|W>B z%9qN$plDWZ8kAFL7AMCE=bmcGbn1cgRCM7M^eufuyo7GwBy3U*@0f)K^`(n!$F?X< zXfexh3Mo>pT#4{b&Sz!MkA?k6GTfSm5abIf>w%rxx`-=Mjd9&6+9MA9qWx~cuc_UhTA39LoEK*9zQgZZ?Fn9S8FK7Y9q0qV;?$GO}I zeyL<#&$2LoTJ59{x1P<%!cIbh%C_ubiK66f+eCx6ao{4>lZ|kjKrg?{O=2{%I6sdA z=fTo$AAu50zcTP?eECP(v;&!Q)3!@lOXuqbTC7b7@Yy4%i+Jt&#rFE@F{E&tA3OME z5+H-u)yD~Dg%ACas82kL*L$Y-?e0dFBxyjYVjw}+y>t;9>FY&%Kx{}{cLw4cuIV<~ zVSUE?L%N`1xdX175#@gW*XEpApqSR>Qhr~g0mNgXgC7yuX?~~7sW(1-xs?RxT5+nY zDU~50xkZQ4aoe2kYzrT3Cb%j`5q~tCv2o@Hq*ZTI9!N3(vkkY)fGT(>14C2iN8mY| zSG!Pd56j^eN{lGosy;HM?K~O%uZ>`i<-O#|LMWH5K{z)=qF63UjSevF( z*;D>{O${5HYK}tFfjgeh@`o-U)gy^cwp`VKRGIMXMXV&jEG6$IA)-;_&W|0qX0N8% zPek=}__O;=$I~CMI-sLbTPa5C+Bh*#C;l~FOmE#BB3ylS=>*Q6{lz{Oh_8t*eDz!|4IhQ>eVXDdecIW zBbQ-$)#abrjbkP7&XKudRsFdi(5@Jaxk+{IO_)RpF%Ttc#1s7J9I+p*^+uh9Nlf@% ztboZ0w68d=g7{R#-v-08o;*izK~a_U5!bs^PQ^Y~X6l((Ji-Ak#)qv~%cf&DF6~Re zrIr7%fDl@gt`S~NW^pmqF4VH^GDRz_giu*b@#LPzv`ajgU*$5i$I`&=447eZ?;<13 zRnx#emyRm0987SXxZKhO+^)0@E9RoH$KIVg4)D^ZlQgARxY9#67I2`>y?n2^#fP+O z>m4ZPrhaRa_3D2Z;kDXb%QQg7%>cD^j`^TxH2-55};EX>EV$Z1l-8<-$RP%)&7%N zvQ`oz=dLT0#Jh#!q-}b8ND@`6)lDQ%E+axBT`PIUk0K&hs7z7PV>q4CZ(4Ph@AXGA zGyHn!@_x?u^fm(`3-`+|+f5g^xHI=PIt#O{o4ZsaX_z(1y=E89Eu?s%s-LWCvQT2@ zP(s#H857X79jx2bL9faRMVWIn7Un{G|Rl9H(I(V!(lV!A8*orFD z;CrhvVQ)kSom;oLITAIh7VXBC^czsTjXK3?aCgJ=)Kv2&IFwxHNvIuv?lW<(EP;ek zYj4+E>TQ&ygs9m=P1}J7b)&$x$Z$7Q{9lB91yCKq^X9|d-QC?K*u&jjgS)%CySv-N zJpqCS36EfbhilLPL4rHS@BVdlb#?!`+nTM~t=gTPneEx>{kr>WT>(jtc?x{_N>4W+ zBkSy=zj&vK7)LihZ==1lgD9ED)GG_X;L8UX7V{Dhn80Az|D}vikI@_F1;F+~PLGPI z7-qGeaYs96B_^34c?PY2@p9iXO5XcXEz-D5L=_$z^|@%|a2M&dT`@k$8=!OU z{nEUi+bX%pQiX0uID`%Dj zGiK+)3nckvg=!Zdh;*e1Ro?88=1F!Fz4A!IQ=p_acOP%ZoSgejS|mA_8LHo?nfO;~ zTA}ggdtOMzbL}zF<~!shRCe~{P3ZL1zu~=S@jb$H?vH`i!tC_TIv{#~ zQ14iv_noc3=6U%xAcMte^If%tp{H}{wNUpxC&ss6!}Rnmb?JFs_dR8C(D62O{^L>R z@y8s*F-GTUXJ6elV^&=~FK+~%J~2HZq&s|Hqox*H^o>If4hl1#?+*4y08RKti8#lC z9sopsq%l7-V0cADg(Y)xCg-{RiJ8jNk{$V3kD;ZqE_QXRMI}3>(-FJ~6ZQ8Qun1lt^)EQRKC31A2989# zeqy4Coyjd%^!x*h3iSxb%^N6?{n_p}mq#0X;4YLfQj%Z~np1LUaI&ryx-P?g@9M8DusUxDWZU98HmK-3vE^Ie&z#PG5;DW`XJBA;8y))l-AQgFp(?vqVfJEidzG<20gZpd>bz@w`nY|!Cp%^ zTS;yzx&Ehg=+OA{yj1iJ)GLZb?A-D8P5B?#l9Ukg@gU{R4l)Uh=2ZsBLM+Z0uqV&=Z@^%Ess=&)DgmqxDf2=Uv$oF zsp8VLWR>PQA!n5fK|B6ZEV8y3bDA=NcI#4*2TV4SvV#O4t-?p2DBaJm#{-dGvIYx4 z;f}wo_661U={0z0^m^n~I#<1h1$=h(3zm+*NUOZ(k~*%zBCh=vXnblnnYChrhw)c0 zm2me+FcPgO)Hz#HwGyKUe>k_$7ks^469&k?)1Qn@o_)Tq*7p~}Tfox~#*=;*Dp1pt zx>=UMYOe0W-2F;58tlbGR?T70_2`yC(kiXYsQO0|@!9~fA`g8Y;V(AVFH6JEu)5!R zCan01BSkSuRn$C3soh3x(dT1$`zgI!lAX(Az8aN^jBmIOkK+X1_>(`@SQXDFnCkjd z&Us3g`QO_k(%UNM(N*w!F~|-;D?T}|*w?pi*L)_--4ELw@BEs7j}G-5k|YA~ixtE6 zfx|e$s;RAXl|-{XvTr>~|FKh&q8><6!tgyx;CtZhLKNy5am?3tPlP`rGVPYG9T=!0 zgVl#1F>|V7J4;?I5k^tuB=Xv}IO)CLU=}Rb!(ltssNtfhymr`s(ww)@v2<14xW5$4 z$DQ|r3ha~6dFpq#$?e^1(EA&i0qipO)<_pJXltAV`urxtm42NvPr5hIUvR5jP8de$ z4}kr2+ryjxEau}(9^=&5N7)5-b&)KV5J&59-{|g)S*9D>)JRbE;A?e!*eb zU|j|xKt)IHv)12Xo?v6w{l`Ck!YD|?dm4yrgGA1s z)h_ZcgvpOiB=*R`n(?>42nB!s7ebEGA(Td*nNF{cQN7?eNe@h~ewyU3ceV0($YqNo zei1OfM+PX5(uAqkQJHQL;Npcw98`cn{q$VEHH^qA)N<=@VtQkVPpdIY7C;u2-z=1$ zcq9rK)!-%<>|k$r(Rv~9CJvF!M>6<-P+HX@9uUpE->6O;icK<;8=WGjHpt^Q!L*P8&PM4bsSP@2xbQkU>xdy;@%TA||goh4wVtl7)}_xOHE(GVUc5F3KDqRC`MLnOrr(6X!K9!I6~YDzry1U&PsEZ^+ITxKehBzyiU+58KX zU1d{M&pE?SIKw9|?k=pcN4Y(qC~FTP*1GsU*LtJgbNc6R|BfzJf6MAShMU$?P!28P zyI<7}{{0>=mgTGZfvfqLFDA!DY=8*hdPOPGPn<0lXC-QqavX+pI#%OK3|Yr7>FLor zAk3^h_(gc?pYIJ$NaWU@_)e0qQ0e=W%nNz$rJ38>H%9EYq^uXw=AFSSuMjh(0Hpm8 z_Je=IRS9sok>EnLv{ts){55?IKa1tnwVNyddUm(bn)$C`+iIB7xS-wwi?qgpMX1JmC$^>-JR(JZ>T zK&BsmUSVm$Ex_OhLi*09FRu7RLhWe2+o3BkI^cMj29~@!j>F zOntT4Hc55^!kNer1MP}}auGIOgD&AL+l1g7+~gF-*+<0U!|>G4$;KFv5zC;$I`1#p zYH?ZK!tSoYA^vZGV7aX7s(~_D4;U=*!;6uXf2EVrBe1YTL|*_m2l0kdG!Wr}vZV!W zZ}e$(561%2+f9gHCpqQMN85ZlCI`w7#u;NwgE=oB&6gF{oshjlJfaNm!S86&p zKZ@e9NvAHumE`eZR>7rTum%hTYd6|lD3?9AkpnCD@{%1loeLVmSRfu_$Q&+h<k^ z=IwWbD=V-8LuO8q$&-cI{zmA_tc=Nl0d!so z?~T<3O0+NT&Ef|sNjz3}8kopZc?)^h&Cc_CM;9A*8O-}ao!ha!O2WPwqK7fS&28cB zNMml)Rpan6T$$@T7g#FFmE-={{o)hrys|!~QI&c{2R1SzWqD zt!pd7I!YrNO+cSFCzC1aI@0E%xmB4sH?7yb2Zr2_@SRm_K_V{^o;Bdey}IYw3uR1% zk1_G1HSF`WjqOd)A^PYeox(jdd0`@sjXI8wg^e+jX#2zQH5bv!a&MeP4_I->ftU+4 zj6>w!kY~QTV?LjLvk@cj0Ii5A%8JwAT^I87y>oYqCA_RBV9GbS)R(aNwHJEyY|Bid zx3-`6wAqGYSLUVpRN@Mb66aX)n<@jAypku7ixc6lZC1m(etXL>jRiYibCj7q2 z4z}E9MMH_}Fsi!Rp&SZebqNsgPBg7M3sj$7z`lhpE;p_6geYCIx2UHEWMiN36v{RMP0ix_!XA@T(7YvBj>KtL3pHH>`N#&2{&Xe z)lHPqR&E)ADoXojPnGSr|8jg+glr`Xc|2x|N~h50D+3!PZ7DVjJi+DxPNf^%CR@69 zf*uvYjBfY8?7wrXZm$g~slYfW4aM>N7ACrFvZ@V!$M`?}E?o44sD6Gp^_P4^(fmJ| z75?LQ;o<7%FJ0{yEkfx-PA<_JGZZca@lHn)lvPzDE1iKr7up@-o2e&Jjg{DG`ot*vf@K97b zh*R1kE*=VnS-CC=vn(}bPB)6SfjWoe#xle_(noUKPQv3K)Q(Z5VF zKJ_SFqBF6R16M#)rMh(Lbv)hYTgd9=F3}KXKO?errgBy_^=u{4%*9r%M@}_Wn%5fc zY$KnK++D86WcxEODOmXbZ=Z?zq9%rF1GR%SrSa~KNbE75_n3{NegnkqepFiT*3WBve-pT*soYX3a zzftq0Doiug#Wd)=@EL<>HJ5dtAK?B^5pk#qJEda>0En6Z0KxyCYtDZwBL5{IW5o!5 zxH`)}W{aJ+S2uAbK}@jn(YT88Y1on|WYE-QyBVxh8CF!$7Os7931}qLADg1yP#j@f zxxTtTUZ88=3W>$*o2^gBs*{i0%G7m`SgNg$?fHh#;IsJsRDQ<6+;*xcPBSE=%0QW9&oo5*p%<{HiQc}bBY{vv5N@a-y6;l&P1Jiat}m%!y;gG>?T;J<>* zjlaJ9p{@hY$+WF(>_FeEf2I3zqIC?qT-`N_%2#mSK>w1tfP zznm;qIxTU2)`%7g@{_H2SuMn?*z%jKcv<7j(ub>17t-=?uF!TI&(t6kmN;pyRJAKu zX3o$@s?ZmjIt6rqEi$L+V^!D-#hjknkAKvN7mD!1tn7C%edbA0UCv%#W-?l?2cDl#Orb8$-IdhtnzuIYXrF&({T5HCJybziHs3U*2CPM|U z(1G8DA7zErN^7JhM}@2~fIo4C)utnAT9cokwI^*_#);j=6RA*X)p-2SgI}+;Cu3U2 zDW~lbqwv6~*`_06n$M}(+LNp>8`1ALfP9H$Wn<#hW!GDvuv%xHP4`&$m_O6&6UW8Q zVuSx}v8;V^v`-v|dDS=Nc|+5!X&W+uzSvI&u36`N3M8yIATNs0?TNz>{=yZJA-VOb zL!dJ7n2O(M#ffj>=RAL6r^%XmmXBeT$*xi6O{+|R^qOE6qjON-Ou{&!e$38s-^t>wXRVVxgd*{q}W+P$qz=5mz*lmly*=QyQf;EBt zkksj9L((-jSs8Dc&CfujI)};(pBhS&^lwvi6I{&|YkcJc4k-;b%mUcBqBABZjUo#M zTEpA@EZ*MN%noq3qHv)RcAp!)7gazlqoB_FC!KiocEuA1=K7xq_#L0Hn(3+|uwTDi zp=WO3EqXT>U@0k@p!CJHg{ZtNqcD8is`qrti+oRnGYD#e${?OfU20h2ff{rI5bA1( zZRi+k9Kg!TrfrHk))#qSw-*#Li*{lRD5S-IGci1hka7nG6!9h9=h&d(SjqkTzBZqL z?BpTT01*MX+2ZMOfLg9QZ<1V`=2XUNo$kkzR#M zBJMp{L5ZqtF8vvwm^6j$dwM219?b&ozHsLXB$7GZ%tyqpi7uiTo9Suf^KJD|`tis~ z&;Va0Pb#;x8ZlZA0#H(EYRwqhJJFMEJk}|3RV-8T@hiqS)e!Xa=31>vzSXcx|HM{P zVnwwxFg7`QG$pO@Z#$aX+gLoHGEDmC#X0WzCq3K679^E=(@A>#%eniTDR>H4hsH^);@>KYSZgFXM%WYHh_tte$jSNR)~z^vz7+~E*z_;fIQ$ETg4^6fJTESm5b`%4Yg z%y#n$w{3FhS2h7Z*pl6XhL4;J0B1wQjlPs0hDhn3k9GceZ^|`B+7&MddD5sfqXn9K1V26(+WH**trEtxE#7w1pU-g*FU)6+=9}>5}{D z#rzKUoedqn`?4E!xcYE$L}g||;AVK)l>5_Ys)FY`Nq-FyZetMAFW$W@i}E^eW0tzY zFK$kO+FBSI)|Zmepvpzc1~uGjtc!`&dWFPLriqsXG9&+=&^3`KIc6s2p_(~u>-rEFf;qX{=Q_w1$R9{S~P4mlp|=u6~he0Y)A(@#99-xDNA8Jn>fRT*%i&(O}$ z(Xbe2e=sT$bc^JUvn{*H1lJt3!;sW;6D$WH>ul!|1`%l(ofz*FXz#ImFD@}FXy?|C zqEG-8L|9|L4a|5(evg;Sf1YN0ypz@lR%!ZX6Vbs8 z;Tz5`(W*2v?C>mZ-fyP%4es(C^Ycyqxd2Zl=N^A5$xdRbvEU`nTHkjo+*4OVYJ`O-qcd(u9IugEBoY{-|GcMY=q123hg|(venWH;l)q9Cms`++wou3U!GqJ zlS=Z@%Mm)#*4Bmm#(bJr^kr*^)vz)%M72*Okza9O^wwqZy?6*Z48>`U#%FWsflKYq zr=oE=tdkQeATILuR+XJq5ba-2Q>yR1{t@l3`_;=KxubXKI9WEa zBkMyK{rlIcS`cHerqRRJ9mz)^m$j+6@Tk6laV-8OXQ6g$y6K#mn3a(@$iTtXAaxt!Q@!d&mQwAAa+^EK7#iKCxtfyGN7pW+frtVV4| z`MM15n+$8BUKAAHA*ydMwT-8uNrh27lwQR*;a~Y6tH^fg?cvOfjHLO!_D-_^=mcKh z%?*lvRk))OvK=3UmDD}%V5#lN8_`$F1+|+F<-v9#;9%QhZP>yVmKH*sHYQib8pt1(Od9T8*EnT^`TgY2G@WihK1YL&i0IjNS-eh*}Rn zSlZ0shQPml!nPD;RKfriJJOm<8+Woo9@Umd6Tec1tB~u1)@U4T5s^1x)6QBGht03G zs%+_5!&;O0zZ5HjBDNWG&t_Je#OoEo)hTl==0xt_7Fz6y{uPq=M~RP4%&Xeq3d3&e zHVM|O>e{N>@`pj$k_*`IKN%(IGR2_WF>1QjGAw0SZ9Jv2dVOS_F}U__%$Se^H3Ii< zIJ*}7xvf38PYFM*+Ah`@UccHaRe~yTCK)tPNS=tpSwusWmqJCRD_w8W))|_^FYFXv=|EwHw792ra7i*=tR{7*2i?m z*2XK(HMq0V*5vfPNA%3ghVfkkQPfH;^0C$diCa0#8 zbohR~iYg;cEu*WnZOCxS7G&Q6u}t2#hdy#v$Aj}E8`p*HelZK$PIJr>>IDMM+TY&U zT-{>Uz>}m_*CK@kE2ES18pmt~0VFY7<-XSL@_iG@W;xZqf2uSB^m4W`x8#Jjd!hLi zDG(=RNbm2)-7jQ%`h`*gJxTA;^MT3pvF$hMH*K~@3(A9_T4*&X!SracYANt%1f~-n zCL^IRvysuml*DqCo{n~PA@@f#KiN|p8~0mk-#U-^lKLXfS3_TP!FKAM@00f3`olx2$byK4WOj#52-TC({uSJ~ zyl?V$tIdOsaY(jq8Vj@7PrWMmb&mjVgHuVmhvFD{h(+}^OZ{t6GRg_7!1-j^*rF<& zw_#Up+Vy&e<=oM2vy5>mNiBhDzPgAxt|aw?Ww1-kM`q`z{6Wp}E4ftFe@&B&gDKs( zsYAX%8c0F0L+8J}`}8p!S-0T9&rs}bkNn{Q!^fph@bJ7C{<)Clji~(J{k6;NUEZHM zC&WbA4^px_8d*mR(FWGLPcFn6HPrX&Jvcm~|4#5%yFLBQsEgK;OQPU1uP;L{XLdrh zf#d!WWS382#i`a+HY=FSf+_7A_i(kb;DX%wx6GlgFGW(wE6$WQ-n1eYEFs(+9uLAP zHE1K9`7!*m*o^z-gGP(g894vXg!__grn_`~ep ziep3@K(VBX)k;+58Kj)9A2RgpcUOgROjG@Sm%tEF(T)Fu|NPzmZ|z7sWiSTO0tJS4{En6$g|js!}`7RJYaCjb!Byo4Gf31PZ0|wwKMH#&#Eu zkj=tVtHTD$IEKHM4pdkQ?!I3d#PX#w2mR;|a7cY@)sWn zmxY{3rR`?1mE}Z=aLvB6N?y9#R3obvH0O_9iM_Trtf9ggfK3I1Q2{DQwCyI_46=r32%=ari^sB}hzmHZU@dOdyok zT+3JNP7vTM2+HY6d-Dwdbg!!!C#a;`uKx4x(KtxN)*Q9{ zbLcB+5X;<^q2C~OkU-cm{bdt!=EVdI6z8btLu%p@76Y50lFt_`2PMQW%y z_L^kQgXTNdkIHGcJ1W?}OPnxw1ZG3zD2OX&?{I>;fjhD8Wt;l%q=tXtYdmaaR;07^LEpTP@X2 z#2W8Qu|r=ejKxxOaECsTm3l#4hJxzJYWvsBb|rqazWH_vqQAJ7-TA6NBXqtXJq${m z;ix~;Lf&YUyVUAIueF8)CuQaX*dRF>SRv_83HTFI-{p&=@-w2cGoq7wQ4p--7*AL% z7|ljw@>^8l_ZtTPxat5uIk1ENpiVX8G6leJg~$#gD$s0bB!1ZabeP>n2G2p52fn29Jml9*e?gdhQx){VKku(kVP z&nv3S@FUgS)9}_2+NDeyXf*y<;|QN=!<%wl*i4j^Kb$q$%x}zH zm~9<_!ClN67KD~2H^II&lq9NnHntAY=~F`54JO@_3JXDxaBz`%G-Tv?VF&1(J0^j+1&eSJVYoQ|elhSjt@wnPSO zhE>`PKml2PULpf3!;}&Xt)NPxV3qynq?t%TOddYM3R6BNtO}D>hLQ*>LxYkD9=yUY zldH0#BOhQVs|lT9PnnONK}4Akm*FYFO+u@hmK8C&D2pANYc=?FeBxS$pcy(qb}mJ$ zk+Tm@w(9GUJhDU`bOH$>3X@`eHM*uKoqS?=8*b)5NySX|8slS4Gjps17S`TJJbZt# zERk&_#?%4qbg1ZPGy)u|vWIzk86MCx-GFVO@IX$tElQ*Tg1IZ?s` z*=38Q)f-GTAuPa;ZpgYhOHMh{?txcS@?!AdTFOUK zTC*=q7$5p0Gc8d;dJsYeg~Sz(dezVZkGm zt7sYh&I!#f)CMw{V%W|LF;!T!2ohJk@+EL!VA@CO2m;_0w>)~}e%D8HRlM|mRkhgA zx<>Asr1fEBU;wYU^;&Aa)o*ZQ=I?`2-C}YvHzp=;cdbQ!UBvwkB$fbF~E9j-s zb}D3Qr`J>{l<4a8v%}HaQ-T2s9BEeJv9!VqJ_Vdm&X3%!zh2>>1vRKih zw^_sm;X_K~1<7SF!T`nhJ)BqQho?jlz5y!3t75>mg2x}WooAS!&~S{~FjMt*@~zX` zta1TOv;O?6+a=CNc-YH>261t+da6>f1g|H;OYd5{VAioed!S5mornRRhu#Pds33(M zC3rK8_!M;u#FJ)3aS-L z)x3Sos-{5v4&;>nY9K%k}OsArLcBf=H4<3 zAw-t4-5`)Y9Ns3SF(RJhh_<^vz&f3fTyty+p18R>L21~R>Y*8CdrbYGCMZr(I+Ttu z7dUpH?hdEjho8jqalJIlKsxS~bEPR7ujDnu=9A7)UpDpaJ_oq$V zmTjf@CwRnOjN#r=kDFv?<_XzEu8;KFjMMVy5&LjyeTW&kKo3INmhgQ<`7HogBdu?< zCc>$au$CVz>nH>kgP*P~dnC&I>nXjHn`iYg)krh{l1Tsd&9f5!obei^aHo`)=@c|X zTS!S?{}0a*e2?((MjbnhJ`l<{P6_((w8}sYP~<19`!=jh1kZBIx5Bu+gP7^6$ua=0 zSFlPtR2aon5|$#BA=V6ENw+{Nu1kcvO`r{GfvK>3KL#24yR%8A!rJWP<}=)HwuH? zIwu)oEI5;8qEZl+r4x9RYy6~;=!k2=9fhljZPZiDbql%oaJf|Icv6;=s&Hx9)3PF~ zplPpxnsC?x^7s)|__VjqlOMD*`Q^~bJU?Kkq0cPJjFFRmV%h0Y&*f0f<-l0NL7y4I zt|`Kv`RAke(uwm=fKr$tz^HsUO?0n%?)v`e4S{YyI@I*EKK{YFocJyiD8m2oWLS#^) z1jkv?#WvAXTV9cu<}ubw7Km;MD?@yXYs;(I_e(immW7VUIm^LIJ%y`2nf9n&Ils;@ zo$ymc6_0#x1T7S;0;K}H0!CU@7%dttk#hle$C$r^mQ8`K*7ynn<7-&DoW^+2$!Ah| zq;cR7q2y*#be0Wkh4CI@a?O;}Z*8Pb9==Rlkvw|I67UXlxX1$Ktk(n&jBy9$tWcV* zPa(APm%K`!@A=L7A_o$6fbpOSEja&;G+Qc82P!queFIeg90#xO`D}_hHnRo=U{9gE z<|vV$LtUg-jbS3ok|o(Yy--&hu>QJT_IFuGxhDrBsM8!2NsfRne2I0&@$M9h~$_GAo=aCa6oJ{OGZD|45LpRwE;%|4=nS|g{xJ(sle=%87x&Nisd zXHX_qS43NSMlyoL3$Ha{Y4yN(WR`0X)zs;54^+93nl|X)^nAtz=YuKCHp9**=mCKt zU)&(q$P1IpevAQ(;d`zJF|=#=yIiQC51@wXS|Jx+*r+4O1J&&ZR?RkLX;5s?70eY_ zE$kWYaUb^k4eb?};`c$OuJ6GtK{oU88)?&3JQ9q}eCCK%m3(IYuCi`|z$)V}*Z?iu z>H-VKAGqr^UZDdZO>okYgX}yWEfS>yv;wz$Kp5@+UbecJcyv(&qF*|SRwI1uu55*B zM8ftnH+eBRBSHQ4h~9j7nh|w~oHUGMyb0|pW9BagGtg~wr*9Zm>OpzG{=WG~j9Zh^ z_OA>NFq?mgEqb<_NlL20I}WV7$-?p{9;al=t0OyLRC+Uo)qXSGmpV^XvnoK{$EH-P z_NlQS63O&XvDKhhP-f;VR*A0htefy6M-!MXZ>!-ha40xk_@%ljlMI5hpxBl`y(fty z0>W3QLSmQNlpDlbxOHG0pvoM|EXll#VaakOexLySu)O+Ug-!8eQW8fk29d_ZQ0;uS z=>!W)sfRw8q^oi%>#X?&Owb}6Cu|HOnY_tl@|$bXYe;}@JT(wD$g~$pb^dvnwy$Q% zF*}7qR%%rt1vqSp_9fD%d`7vb=g7g&hIuD_1I7zLLrG99RC{p91QR!)VvMw;*@j8oHWJZ3tv2!QvSrP?Wp zHIBvf;xO0kmy}Xzad@q*d-)bc1t(L-rKSYjhCMdIydi`QM(Df%&S6mgk;A;f!3>25 z4u+MP0q5SMnd}^p5MUT&?eLd&X7Mq70yjKj0b9iWM~yI1LtN2xJS4IG=)Fv zN$P~NbRm$V?vw*cP7Wt97AWP2_({3dN#>S)CHsW{TX~82boi z4lr&MRf5;}2?DN_C5L1~n{YZ5z^L@mZ#2!DR zMZEz!Da@ZjB95PlYAy&U-;gEWF&6F}mA73-3I}#4!#@27e02!wGQ4_49WVo%b46Ty z{N$kzh!5Wj(Ctk&e3Pj_O-y+*M9p&LiU!}80tOCt9ry->(H>cS<_)NabESXf*d?@e zR;uRQWmz2q22^)Wp$Ggf=^|Q;@`6~PADXe2>;Ek}f^(4vye`pT&FCKjA~{HcdUj4x z2Hti^00YpM#aQ&)-cUg-W4GlkPXzYf_v75Cb|YXHBBZ`wkS*?ykiKz^2y19MLwbz_ zYh-Jqni%)RQW_WaZ@Q+9)grc$zl|R*VnmLBB|>Sns8>_bBG;6&k7>2oSK3k~aONei zMuYUBmBicFY>)Wiu1F8MVHePsCa?oaL%u{0&46v4oo9@PX83JB^BA+!<$YJpJ)?TM z?c|+rL_s7&z9?>hkecRf|^V-^#*f2!*hZ#B3w}(?jl`D z9(=-F2_DFyw#hF=kq3SZ-3vaH%zfk@L>`^S-Gw`yiAVD)KjhFiDuFuiEE7SVJgO@` z!1Vso2m4(QRC}PK*wv?Mkn(zrXsqlApPNpyJB9k%v$l2H>I%fDu zoq&ZI&yhf}ZCtB>FTK5K6Ew6|9Ag+5qi596Cu>UUqSau+zR2m+luvnv28>njU?Ga6s1P5_t$>M^&dCyr#O8nH1%U&2EPICVFg$9?m2f@p>Xh=X{B1mJ`Ah6JF3 zGKU1}0yP>au2Y!Gn^d%W!0B4BNr_mSYfgG@nvhxfG5)Y$5#L+*a%iwds z3d+vG>O-sgggK0WIs8rH8Ijr#gZe>3`qGjzgcR!qmij?K`clhW*6lP`{`^CDYUsAF zcRs-m_zvG=KbS&oH|zwG1--*<7w!b21YLw(^mG3FHk2#BRR6kv7}^;?@AL|5SDL>0 z1a~=5akuoYp?A8R_4zdiyJ?$7JybgFjdZEw^;`e>dwiMAWqwFYB5ST)kWFIjbN<%H z&PIM-dXh-U8v5x3W?Wx>NzU9^Ze)0JJN9c(x9cm;RA}TqMM8A1LVKB*2kdS3Ew4KN zJm;$Nh&4-cnlrDe&m6DNBtzZEvzyuXuQkhjvJd^uTnh~6Qgw5Re1(Mxz(oidpMMf+kB#|TLx z2^rUQks@i>`~Oox+y6jP5*hW-@1vIjp>2$d^(nBC36hrW;Q7eaaiI8!)ak+s;6cY> z1yCS^FkuAsj*&c#>r2O%~K1pK&mq#V#Io z^EDfOVm+9NYAqK#<5g2~K&|+N@}k07b74PVns*hgtRLVIM*sXl&1N@`sDchSvA4To zRkJS>wo!mVDhU|h#1ku7u9KTUFqJNUKiPxb}tc1~pm;>!_Gh6}0O@Y1aJJt3_FkEY%`~ zr#EKcozNP7ZLjjtKAoR`3NW&m~>x6=~tvkdhVz}&hiAN{4UZo&rz?dztjrL*sx z_Ij~%fZBt37sU6QP2Gj5#3lmhnQNMSi1)*j)(IuTiv-~Nx!~+OZy;@w{axG|-5FUy z&%5A8DD=5F(tT;f^X$;;(azho+dJk)DAM^LcFwcI;6=Y-!%u2x75Qx_B1 zq0~w*D#tz*Vm|TkE8fn+2xl6Fq>h~l?BAk4xUePWX2})K&VE4_w^FeGo-zH}3fKHw z%(%Wqm-J_?p&o2P>|k+$9#tYSB-16DU2%2{`Bj2+AE+e|$WOQKS*~DaH&0Q3YL`i$ zT5sR}!3_fsW5*a41I+wAXGP0Pgr+hMa3JN)2dL0Tmn%dTJo`Exz8ScM(r<{9oR^~9 z&qh9b?t~C+d>kGPzg~~Hy>s#1FWVo6pl!57J}2(HVRwf@Z44rwn?c`mL_X^cy*7M* z>cH+YJS1nc9rc#zCPzHwq;VNd>L%jZ#qSO!u^A=H!}7I|-H0Y~7qA%>b*{I*tIIAp zb-jNtHxx9IKFJ%WA_S$aPRqI z{oz+}q@-HPX`Z;|BTSQ7nqG9MJ-Uf&E%;%>17-TnS+@3*^2o$^t5f5t7pi} z8x*H_lp+PqlUOzM^O3gQdq%?FA9mfZg2`Q>Qd(!*U3DNQ?Vs59_BnL_HKoE*LV-U* zK@C#s5i}9lWC4oqgiPz^=u$rz3hA@D@lFMmc$v>x*oA-ZjxXXa(yo#BhT@>PynO*n zJpyLGWx0Q|yJin)4JXe)eD)iVaRoN7*3-z6maZZ$%Jio<+bJdRE#zMiM^kr3AFQtIs1*E^^`QO0^x%6rIewbDEX73Xaln+!*u6h2B4bC z*`-q$=Y=dLPU5QV5E3xtIlz+Cewl5DW+c0G>PZ#RtxZQ?9QWK5J-dVJ1WJ`+)&Hl<)B1=+l3ss!z=8D z`5~8}mRbGlq*lfg3mjeh%b;tC*;bwH&9CZvB2Z6FX=z1viXFwN) zdNQ$Sic!N;s=8?T;=z|a$~;rb*gYAyer5NR5!?$uw8tC7?yWNI9~zVHMOznoUm73f zNwGP0aWa$s*@y-PjJr$)J=ASWO<3>WPRtagv?yFW!1w&Tj>SCde-j`ZR&80px?zaV zO;Ztl#V^T-^$p5^O+o}uwI-V4hp2w}%& z|KaDXTw!TyY=1H95Y?kh$)B5~ss0q^b@@ha~@IqC5V_fFx>mFED_uLaz~CnZ%!$p3@0 zw+@Tz+13ULu1#=jAV~1wt^tC(L$Jo(C3pe^I%uOo65PEB?ry;$K;yv)G(iH5!;s&d zd+zzZIWy19^dEco)4Qu`)w|ZJwf3%E^`5I0VLd)e)pqm!aZC1fB?OFLEj0L$ zAB%oQ{WKBqeem0RYeu~I*!;vq9)8Jh)Z?+SMF+zG>?>m4yfanON4_S1(@E>5ow zQFi8j32&$ox!mS3X9(e!b_Ibb`~iivjGUcS^GP3r?uj3>Zgw44>F-E$SX{sKmq?N& zr5wH4-QS}vBBLoDUx_=xsk`J!mfWfy*b7tQFr>&QKCMphep;Qt z_y6kEb2nF48!K-IH`o7OmXMlcsM3(B%!J1Q?c;0wb2`1>?_Kk_tcJABf_Ip^BsVuF4xX%9mlpDR-|zDO}O zzKbUXpKG(8UFRj{w*t%55W5p6A}vWE4{_#=A@3L}+vlo~8isKQlqk`TbBaDTUZwyZ zu+0JUr0D*6L^Q}>z^%mSf5nJl(4_cUE_R`9(0-OQ-z`?$*02h#Wa9B?_?s^V zuXM<$`C)>Wa(+DctX)^nB3gQ(!dVol79DZI1b%Gp=!+D^s$S#`YjoPCo1 z0j8?Ujfod%B9z-@Le)J7T?uW4dH}9{Coe7MjhBnr4XkdF_KiD#49N*PZBMrY)5)!) z+#cNG39BwLgJR`vVqtlU@~H;~psvLCijM0Hse^?xpHliPNgqjTz7hViwY_cr-&P`E zhD)^qfJjKb8c0Yy|KH5vzm_132Vw>3&MiLtS!;R6q{{RW73HH3GA14Smlqas7Cf0B zU$V%rL|S7e(h)Hckyf#n&b2x$|KBZp?Ryf(XJ0Sd_f|&g*5UrB-EaI?V!Zl~1~5qUUp$l0&fUk6;GJej zZXZq@p~=WEEk-04Sik+InpTi(9T`B%ir~}Zsi2KdTBOO?+VQG(%qWSr)B_fvr!iVU z0y1(wcF-98OpGuaOO;ddtaN;(H{ek&Y(`>3!+L3%r~CBEn)26|<&C;?pUd7BmA^7* zAksa0qi38Kovf=>6rHSBt4&f;x~Z%8wK#fK&m)ozx!kZQ+EMREDSc`5T(m<~d6ia! zDCFxexdu=DhDx=hgn()txsGo#hKqGQ42Q{#n*(nh;NU-u2dPYpKNI6<77P8H5yM7i z{NER8uCuj|fOCG;Y!f69hM->{JO-`;5B`1vKDOw^fnF+)DT2NWdLs^XeIj< z7{gk$gsno17j>)WS`Dejl0Pg*3r9&*1pR@1n_%Fh<`B6yEaA+Cm1<|& z=$i(cddGtlePw1fgtcn?w8JTuxm7djOcs+bkfM0v5F z*((3E%5FFMqmavQP}PqEMegT#`tnAV1s&Os|usvw#o3+(xWmKpvqT9Ti=EoH%vN87vF8kU>6e-A?J)bE%o44$A06O=H`m2U45R4g|xLxZ$z{kO>wXvi)sM2 zzwh;|gXoI3B=o&z1`kwBFvju9bBC&Y$@j_YwK0LHB_4p3SXRg@Jt*D%F11VE&GWhX zw)t2h^Id?FN3bHj-Hr04bqE0m4k=ULk_qF)aS03%{EEg(icH3eY*-&g}7UBw~7;%y5XjK6s8!XVV6e%kZs^^o}y1xr!X~_MKg4bUr@coUL@fcm1hl`1| z3Gncsx!80u`UNW?AVMFld_h}L!M+OD8B?&7+}cxwUJIjP`+Puc+C6GOYf{oki(RJ* z^UVRPZ^7mPE}zP1C5=G4C^7DvCDz-ySthEmLW0=CC0Xh;6J-|#ic*p$W4EfluL{=8 zK#}G~_M8L-hgh)7O1&TrKm}0~=LLo!phrZsAZp*y-!viWGtUxV#Qh-mhN|syjE03~ z4qVWog|-eN$O_(~39)IecgMXbtL7nvvnVq{YlEqbSDwcjmg|ekMd37LZ8?P{h~;?^ zF{n}7V4}?dTsc45#8GqiYpxJS>!Yj9_!LWWgTtw3n8)Ib( z`cwY%u2s>yt}oD<@RK~soYUCzg$i6n>3LJ4SUj_I;f{R?g&UjB5uJ>6>QN6=1q9Mz zW0vMJzY@1-X8}FXl-#xa80zovg~{{VYagEkBGs?L)3~l3N)BT$xGO}hcMR5)z0yn! zOFRpEvVP&Ds7eM!?LE!Z+$CqIXvkp8i+X;6D)CD-i^>y6ePoa{sc1IkG`Mo7YrKMz zka>_DM-W;$ymG%!WrJoAp;C?L@zZkl;RgxRl3hXZgsxA5pUWBCY_qkzO_<#xMgVe~ zO=q=|QH?V3&9{7{UGzHvZdhb4-{Q_=*%0 z)~>g~p5X^w(j)J|Y`@P(;vAEH2)Et3i&TTUHOJA)TV6zR(LRK}zj04JsQ*T4cd1HS zE!Z{&=+8i8aK`D7uvoBy6}%tB|Sdi*$lD2LeX8))ul5W3wi zIpc$@Y$oT7R)yUU02pq|n5$^;ZmXO>W<&SR-AZx1{c7}8=4nldKHVHr-iJP~yU!f| zyoY@^>Tj!=eNltO&yRX|e|`OcDH17I@pjeGQ~Ng98LRB{^H3jw6ePUI9)bEeC}3g) z_$7?-a`Wq)Q@Fr2uFu2k;JB{pwe=t5948|#o^AN!%_=1L*V}-d@_OI*DTE>7_~j($ zh4hPM(WH9f@IHZNnK@rEi8G=%0h9UlAiqNjPO^H~+nzgCNvHWSwns#%*sBpk%o%BNJ=sI&-^PFWVA=BQeKUM=`% zV8=FlHy2R}P+&to4BJ&xpw{`#lp3-tQulSoiGCxF4bxlEd&yX7?aQ_@x3lSsZ;j1w zsY%pJg|@(6>%ZJT)lRyxjX0>nX4}SoZ=03q_idu5*VW)>b*sfGc|6)TZ{1|1y^w}a zq@S{Du4;NzXKGF{kq~^077_qV|Rj#=+W_=9aDQfo~x!op_d6_J9RQ#TEKOU~xQ|xMxX7I{rYPvn^Sm|MIcNL!AG25VW%yfLQf}*!#v3{mD z(H8cgUlF{V;40wVOkrQ}?U+crDiTo_SnL>8)RYw#sG+bV>@aRj-ju;R*Dtq)%084q zJQmAve6~Blq+y9#=XxeaE8ZrT>0i)L={NA}WehtTX$l9IsREMNJhrEA z((hR+ihCxak##oiOY>mFRF=$xYLMxobie}lYisRW7Km>`o=->p)}HMq@YP^zHm43J z8yL)-2>b(W7n_?((*cYBX258=j6ncIL-#`nca#E=0%GJH^zj4j3S`m@B@^0*d3 zU8Il%gE<95R|CB*c8;7>p}@Lezn_lL#a9BmPgeGyt`+-`%NrAPhh`Xurg3f3#h5!u5zC?qNnuM zwW5ovkDNV)x8?I$%hC6=#qWD;J6^`4z<GPl~YpM z3k0`CDhen6pu6d!@tS^J_eOQcizT4ENPLp}^O;O*`kC^yr;2|`{&+KcajD>!=l~>& z`C@xVoJhAmok7XiQqQCA;d@0j+6(SGJ$y@Rz7^-P%9(dBR2m@h4R#qvMyYbnv;|8; zgG)o{M^-ZsU3LqTMCt6U3X>LKj)Bp(VA`j|U#`-Kf^^N=H0HNN>Y}eQ+e}ZtuZM=M zvi#UjJBJzH^s5F7G5yk{85v)W8=*$Zm<0^49D!eZmZo1!4IA)g?o59)*wkq~W^1>W zG#^|aXI>u2Wq`R#F1kuu{WguDPG6 zHUHzDj;}rv@|$Ue9$ugQn`xKFhdWbNXn)=a+aoK^Nje!zY&+M`P|P<57`CB_5tkaa zk>C$jW!s8dhqA@-wJiRzQP5nieuq*X%?VAe$t^e}^^T4;v>xZTgt8jYj5~qV2| zHsmpNQS-O)$ZdVw{Una_+}|Vp*XR6|NY(5xRWqj+6kdO9UVlMrO8YDE*;g2ti5L9s z0j?#+_~{7_-GTfajs_ZY4`x8?xBKl9+vk|q;uBYoj9ZT(2#G$eNnUhu1tCcdq>k4% z=GMZ2Q6?ea4nGo&p8^wS=w>~}9P5K(R}3v(F_+itLsvu_=VU~@6)od?1pL^%oD&Hy zGV*)kJj3K)ZQ`*g$o8tZL-Rc%d-RV;aCj-N2VWFeuB7>P-_L}pD&)fJKX|fPB)t(< zJHSjyTa|c|QKD0NI6LQNK%B|_0jto};9 zyj8_w?M)C7>-)M))gr*8IALp;m_zqMb-wMR%riK8rqR=38mpA*^z*ei3+JD*CGeD1 zxv7NSZG!NJ`#8Wu%Gb`HYd3iM?hbC&)-4|oALW&L1yA#hlBVe;#YYtXw4XDlgTJzajI^6) zy7vWXt9@mbq|#f4pHIJlQQwh4c3Foi!+NMt$yYV=$LA&Jyhww?u4Q!SZ{WllL^nn> z>^I6JU0C&Z7n#XblJgbp02+;^sS3{u$4J-SsT8`|d1}QOKhQ0K(Cil0z=HbXqdaCFc4wmvI&iQj;O-bia&u^(< zynW2?5)wNWI)RBki?87^+c71f6cUW)tI6j~*Gn?%tllm?;5W1S;x>{wPXuUrQPr=m zqG_~_4$79gqGb&vI!NhS1wqkY#SKq|uXl zlL!<~fwcsulROg$WE-9Sx5AZ-Yp=l>QP3+X5;fOE>y|n7&SLJe=$GayMv#~06-V2L zmSWeA-;!%ke9tZtgT1ep5`*xd(*oV{3m;Gw(rn=m@f5*{jyV)gT)fLM4^O<_mDzkZ zu8I#;6dmpg$+wv0)P^tGG+(vVnjtoV{80@?3Yz6t83I}Ys}T^oQK zpk%^cOL*tU$!(+ux~`pxyK?d~(RZ^#&0jiShHoD|zLxJ|2IvN!R=gk07P)Qvo#FK( zTV$cuZsO2!lH+%~9SuoV-JS z=k=#WVHRrawLzgabeI|Xj$cS}I!TT{$FG5yq8u+_<85o~bbNw|O9HXItaZMiZn0Be zks+0Tdf={P;N;3B*COBL8UJ~Wgv6NS*V#UxPeA&iu*BHm!MP^zeE>_880nY~5NFp# z>dm*u?qAYW7_y_%<@z5emUJtpiY*ERiPG%r+zSLTmh1iP=cA|dsl%BY2*qp0hoq~B zX`O~PbdLO{8?Zf`R2b!qnJAV#De|)v6|)(QmPS5qv4Z^rV0Jk)h>MM17F=&{A6%_` zo8D1*eNT<~v$To$S5F+zhcH`W2InLNz4`|ApdoJ#Tnf?5%9zDg8K-W>t zu*ju5z=eo@$w=5-jLP8Y!Ct~d&t!vFt?6=D$CAEyp6N%FrOVT3Uy8LUPCJt}!ea-6 zt>B}#VTS=>hmn2l%P_lj7r5A1Tb#max=+Miu}_4_B6>>5Ef246a{KF5#^Zrr7zwXS zmtyex3%MH3q-81Qu|_qqxD86mzA9gwprtDE!qv#rC2D>TzO#ll9=$dUz6Nv4MqjC2 zdwftR;sslM7Q*K2Md5~r$s3!qqtR`V_|fg}sA(e_Kb2H$idtLUa$G{VU~yIg5u-mW zUa`2yPtf%qKGSLORu`QLia+#IsXhuf2t@t06f-zH7+4AtS=$(0Y~->trbYi6EisV%26>?QQ+y1oJQ%qCF1kZ`z^uUXeV%1k ziKUx%ZMZHRUl&fzhM*z2{SbYh5giO;AJ~*`?NWiHF4C|ciw!&|4?IMAr)kzc7Fp(K z*FF|lnrqh9l)|J+VM6KZBDO8{$J@1bCx@Kk`WAuC9yzSL%3%w0kZ3%)NOp>F6ISvK z(!&J-3K~@BnxE*V;>nh28EG$inFPnoP`_U7?+P2oQ3f35>Q4NvFKX6?$tPp{s46UAY~Zy4Ph_id z!p_^*5~R~wMZ-SSkg{seG51%E)cjMvQ-iSA9YH#G!x6&9@ zdEw=yFlEtwUD17SQI^*O<-c-YQ0uB-%uz>%n{C>zriPQ#v)#@}TO54L2DByw@XtuA zc~8lU+Vfoqe*uVs0iqB<>j%Kn3_FHPl-JZV*FB!9-`{}zQC#pjpTIAhiyQWJ>0?}gxYXc6JCb%zzSpCgUArKE zXc&DjV~z|LEO*CvHZSu*V3y|{5$IAg!kiFvIm?6p9E48@62pR;f}cUxH}t@4*q~V# zJ@RMjKir4Q>~T#|IJ|8JuEQ`i4cPBb$VvQ>Wlc0JQkkp+jd|DS9 z7P$wPeg#z58V7ZHr&v3WVmptqXYbXoy9)2jbspYpKe#1U;Y@N@_a!{4wa>-f=>^-o zm!OEu?hPleEiSQuN$o9P}=`2V2TBGFd*>`ib>+qDW&u0r-4-Md#k8P_FGdj0yDF<=7 zxlz4tZ!$Y6WY6n(l%>GEIpFCVwDerJ9_#!3V`AlXl>{w+Oa$N z90Gm&$mKluNR_t#exL~6X7Y$?u>XGO;>NDo=n>d-V7~PHl)(A@U=jbCHqa&G3L6~d zrUKgRf<12;2~*6TDL3ezvPf@bOKAKhsvaCY(-mQXxe|%P8X3xfi;qrm&ka)?RAfNg ziqoYccBLW?rzYINia-O|S$ot$F+k~LCU_VB%`mH+*1h^tu$POn@*@dNp;bKjNf>Yd}<+(IFJ z_4YE!5o(OD%tF_^X8jjpmvFh|sZhaj=`Ypxqr^uyF2h>&hszEOfz$TWY&}XedfN=d z{TT4;kpyvLdJ0lfCf<0;969ewZWW7=G>+P3KEf+%XOSqixXFiwrC$Wv63AMOtdvFS5UyOL~ zDdTdhdtheT)^(Da8{wwCy*2h!|IO(gP6V64c=|4ypQ!7pEA81q~P06;2E&|TKK@R9xY4qnP=9ECbF@^nTx2-6u0@6 zdsC*BZoP+yh-HO~rqFdrxZC)=H>uc%Mk(9p1ml@`Q-rgcREl3~c*f{xtkPJ`sBqGb zGC1mJ_tQcUeOGJY!v@a%c{|AV`5|9wqUcame?~2_&2|0nbIsn1GMImN!b^XeYZm!` zGr9PeuHDkY%SO${+v4x{|DJKqN}5(D<{^%J{LMM`o4XmC4LdA1u$Ci=8nr#qug>0* z_XF0)TUUpbq(xTmR(A2&X#?(Q`{t8pK`dLpnxDxaW2y4Z&dz#uKG+33+)3Qyy^t@6 z#4eVN1u^v#jiIOGobY#x_mv(Vv=i`EGR~a)Y52+^v`%|eI1K<+)q!Bvb?qEUL$9E3 zbYJ&BnYgeqx8G;xHF_nrRC~T9bTqYF>ag&eYe#ePfaJ{x-bUwT@2k381XA0)lVg54 z`NpzP@$%zbh=jL(yEi)bo8vmwMPIfvlSI3t-65gRW$COApBS~z*@zWU6DhjpHXHYU~7FC~^*LV6S~szx2IvlXyW}z~d8XShA>~XT07Mk{6V5et}#TAYTqp zdMVDfNxNl6mnhl@8|FMw&b054_JdoLvO!~+cHEwry@`?G;d(ah*I_CP0q@AQ(FG_b6Eb?XU<1YZ?0kf zZAElNb$M%bMRi5_L3zbLm&-37zh-<@wN!77x4PKM$naVd`4gCZDPiu$f$!<}%h+Dm zjbO8H;4i`57F=L_5%|`L1mIRAD5vik07C@0dEy2HcwIdMGXNj5`m_L2+wQS_5Mkin zi4}lZ_znY{417rLV+A}8Z196~+=cr#xSFbA+uo&=Rc!Lux z<CWw`)Rz$9TtFU5_7?|DLCNuXp8U7V~r;9j`UYxw7hIQRi* z_A_C`0tsA6zWSQs)%@bszze`45Z!BdgZpEjCZJCkckhYlmjGzC$(__U3iK3d@1=wE zRRGUK+6VJK^sxXUfYHLlUgYC>AN$AwRw5~$ruMP z9o1(IaC1-ZwO~U~ukwcoX7%C11f$ zyFy;c&55oe7pau%N6mExc;iSGjP2kHOU#rE3SPHYdBt3Lq5Is6(X!4OQ90ZZQ+%F72`701~+RM`-O~xtE0w^2=KkGvXj^ zo#fe)dcrv!GYbE@dz$MXQR8OBO|k{`>N!;_Z%A2$ejS7pYV{+~w8KGNdGUsN0=00T zy%iC&92A!}t7pEPC6ju_Gw?)TZH@*{zF)7h$R-AOa(SFBkV*C1D6`0MCZGc=5Iyy_ znnuayjOmBBfysQrWAaVtLB2E;au>ci9fB`1q^9+Iw0^%XVJ4U|#AjbUWHXv*x985A<+$cpr{o1qf8|wsl}Veji5t zIF!xx1M^2)RqA=3oLSD~uST!@uc+|*<$1EUgM+U@!us|s_!HArYWuP@OAp$Us5yPV z*!ydlYF&KnM;IaJAtemBqJw)bt_M@X^^BDs$|ZUc6D?*C2EXT6fmRuZuk4`a(JQ`i zb@9RFNS^qQ)l5w~l1!0X%li7aaGI`;s-d0BNM&Fp(z_=%`i5g#8UrgYhRC1fIUTjr zzYnJzgqb3$6kTgbC&U0H3_(R-w@S~-XVSp&2-G02(XX%6g(xE~4BcH=X^W|{0AvRY zRmamF!C37xXR(btckzpoU!Tbbx-*se2`6;F zYx^=75j9(~HhL}{b<<{e7AKmlIb>lmerd0I6G`{(HL231&Rg%(*Vc-^N3kP|#SAc6<*cxaZw1_7l6+cE90KKkh$(~921w9g{c1F%EniBA34Luf*}mg@HEE#)i{?du5B>z&QBs5zwOLU)!s88Ix{$= zW>Ttre(%C6IS!`Ki~fV*6UKxvUkF!D8y}9i%DAY^quhBMI6*HB+Z+!_einWo8mM-$l=3gJuSPuKQIg8KrKbj zcNeTY&g8d3PCqFo>fHKCV`t-AqXb=tRol!Wjbw3(?+wW73JbGll$W;S=8;7Oy?%XV zgp8os1*$02bw-#X>?!6{7zoG{^ec9fnrSjMAJZ+n8+Lt`rnh>fZ9r*++);LhQu2OV z15T62`kP_r5N)lFk7Uisu?vXlQ?^~5y}XTUdWONyoHHO}aH(B!64AazEPDS8UUMWw zjGS6A*6E$8?eF3Iyci8%DKAj6#qE_gq|JR!h^*WoMN3QSI^|VCRqR~blK`=}(NT}3 zQWu0r!bJjahYk{i2pXqecC`iP1@Uv$V>lklGKE@dJ}M2&g{lFR3W)^&+)XX-bmA|-O^?{Q-1|sCBmq%5^>f>dJpxKAmUrLec-YnB+IyeD@<0mcD_Ol;7D&E1>d zJhIQ&0J^r_Bl;evHQuy--!NF&rUaXNHBW2^0bSj%UV*;=Lxwg;!Rvp}|F3D^%9SLz z%iXVgqo(IXli1sj>5a#f*QZ_3&*yz~pJjyr@&G0PJq8~J4p>?cQaw!f*TA3$O_}`aL4w!1Gw@Ly_f(l z5Au->8$b)tY$IW4Ll1BbG~3ebwjc(}0OWwt{(%M8Mp$4T;GieV4tIRt;Yy(@IT!ZM zoij2R8$cwYi>-%jbH6GfCusnBHzg3&OKefjqDp4_saJJFO)Gt%XCg1s;0LxIJ!fiG zzUJhl36N5_eW2$Re{@(Hl@OL&Oc=x=gogB4$oyDdL>~}P1>E&ae|pXj-1WNRKP1D< zA&8hftCIst4q5PkC;wo)+BiXTZBM~Dl>>|l2SxRH0?c;@*@c55zyr!52zRbP;#28f zuJxB*Sdg2$kUR!<4q|rg;;kdAH#823kZinthDY6O;jsMe^AgurtFqeH@&>6yQ0YzL5qrUtU4+q#WfK%WrWgtL&1xe zhvNO*u1l6!EkJUPK#LcmB~E%01-_CJ##e^Gq@H)hAYgRQA5m)9P9>>n0&Rm|w^kl& z{m>Pk?$VexdfGdnug$QaAo&w%w2Ufa@QP^k(AN92z_8;&opbXUM4&SAO3&#v>7n24 zdN)H8Wm3ZzTw3ke*UO{d5SmTzhV2CaD=Nj|DEP`a^NF9Bc0&V)J)e(m0hHYi<>jMO zX>=5EwQjaZv}h}p7>F(y*ljckKNo8<6={0aupi$-N4H13b5wQsvEoWPKeu+Zd*Yi2?r2Dux%hZDW+4ce`pGJKEUD$Pm_O)(W@ z5H3OSsu)QS4^9D^)a~ia?Qe7(tnSMUNTBTY4L_2OVd@S7VRXA{^*po?wzb*9(G2UJ zNYO!D=z&;oInbObV52=|d11j?QCYbZfq3(kXb#k{!=AMdq*TwAQ4zM#rc%(OOw_6@ z9|BOhh&96reHY$=@d|<5h!4L9(Q5V#3ItjEYJ~ba_DMzy480ZwAh4hs`2(!o>fyoY z@H#eFS}LrA-^#o{Q{{yz`YkrhV0x1hw9wP}453B>H)pFQ60lky$P9e3igEi4hR=$Y zsk=g2v=uoVX`DA?XRc+*>@YBxl}2!B!nERI&Eg_@!?qQFI=hdr)H%Xp0#a3&J?p)y>4W@#Nf!5J(X<(NZyV!~$n_^Mn0syr*lmW7K!*y2bzs5AL2l0iE3gqcDKNotm{`vm8p0KN`Jsah9t=9hxJ812 zpW0)s#c&vuL`Qf)H9iCr!gWA7=(o5qyB^7suzS0rS+z#nk}oPC^MA~<8kbnXOV%Rkg6J z;|{QV>0u+FlCV__I6ny-Lm5t&S`sU-$yR8h1 zGl*s6^m<{9+|P^`nBoP5pK%{Kq&#VH7b@{Hr!XYXrICWC!X)kGME^`-{F%nUnZm%K z?ZUrW#zDz<|Ft_E^L55$2P_pG5K ze4+0?bm*Xoy^Xq0vW0hmj!^=oU>Mz!s0a%vl`{t}@$4lC)F#6wU(C&PjP z@IN4Pq+5Denl98T1;*tx_-~p3t)t%pVDEZ5OTwrt`X}b1<7BI}Y8aBuH1s<{lg?{X z@`bd^%?iCcBAjphNZ_u@a07lT=CCYWUp829w>nB2EsO$mi6N$gwp`jjF&mqOg3yG5 z!zGa6iJ-l(EDT>s7@KX!^)e`NvBq(b1_vPw9qs1CXhVi8Lo0f+aT}wJ+#Vj@TKjg| z!i_)+AC8dP0Pp}P)!#w(nejlS(EBY;-dlljSQTgzB~TKE(`|-{pofx$cc40x)UDl7 z_YA|4$6@R}W@rdU=)#8%Qn(MO1|tyVpJt8Y5*G{jt=!N8sbI@JYtIns(08F7RB#DU zMf%0=v4y-Xnd9KUfd`_+xJ89A_vrH+j;{mb#yDqU{|&zGPFw^Dv?i>|a{f!#A!UYX zCB-c%tf{9H1z`$34h^P-V}PU>jqCq*$=B5yVP6HCuCWu~b5z1w#8?qmy!SdyV`GfYt zO_6-*U<07E5C61ZN1Y*|&*zH<`>$99X9a1X1fs+E{!4aV$Qb9Gqb+wU4ICZ13JUCY zMPA16MS_$5Q}gBKQ_T*8|3VU81mZ#o6oIjK|I_hp$XJLeAL1=^A+&=Ajt6o>4J3kn z=~+YmM_H@k!*Jg5!T*8s7%h+%cH1L~^v`9NsA2eNrrs?%Y^X=_8A1uF5gJSh=L6-S z{nh4Uh=R3mi|t$|D#8X@^C6f7?gTQ&xJ8Ev{Udi*B4LKa)5s?QJr2J|f`e16UnukJ zv&`j|c!!5NqyJU77=Pj-$=h1IQ)_<15o^U46?x3CC=hda7Pc?#Kb>>Ce`BlhBldsB z(`SJ!u)ZFeXMe?`Q;RY!qi92d%Rpm#IG+V_z_z+MQQCliwIO5v(l^!ie}K$J^TmS! zpoiVn20gz^`m5(-S5cp$GZO3-s3}YWAASwuLNXq|^KB&zeDcMAL1>1BV1pWjcc429 z{8^?@hL2>{{?CBQ4qNVC10VpsSG0%zD-QjYrkF4=Qy)%FZxtJ_$`kNy zker2;>9e+FYzifVc0g=|GmqnL69!9diPNAusu%@a7kc|43*A==%GdoH|8K(_FA=!o z|2CZdxAj%oh6Lsk-X{O2;Qe%Mxwt>Oj3ST}CIAxau10D5Z@bgy>yl86x-Yhc>qGZK zC1~MjpnnCSzs)(nL~#5^_x&p-d+pJGjNMNd?6K53@mu{1G6WA45*~~UPX<+FtkdN8 zSI_-N$9?KUDdBS7e{|c*CuuB{olErLFhkx!$`NArB!PJurP|XJLZ_l1FjQs85!PRc zHET3bdk(jRs&xN_K_<$yhT>lXAA%TK5-NcL z&-g2Gh*H$iOspxsFAB^RDghD-Jwg#f^2LEYfuO)vOZ6WE_upbhQTLy1;SHb~lt2j> zRreYuf(a@V-huYl^jegin{44(pkw4fAy{Dd8V*7ddKn&!^!Hi~OD&av)xYICP>p}G z%D=Kq=vW3m<(0^{yfB0APHcn#v?e?l1^(q9IrXBBo{+_d--4u&Zs}fHXekR(7x~WW z1PGxlww65=Hn0?O82C-9G3ct#>!b3*sVN)uuW0cE!hI&;t;;wp17sKKf+9u*2SUMN z5d>~D?QmO@VdDZD;OVp{3lv6@d2$N>A&y@rb*h5jo?eDWfMeUanj zbnL$+JKd7F2m&Z1>`9omH&Lrk?newO>5)W17(pjPgK6M6Aam5e1<79`OvYgg-JJjg z9@H%?7ze%#T7P!S`B#-gY_)q11A?3H<*74b1HMt>rC7%n5f>zC$I%y2y|U&jf09_w z^1U+Oza=`*+t93MzVH9KJw(THa^XJ(*r%$^4MdSb-tr*~p+ljj=)NK_5|BZdDIUW5 zZ^1OIEm^pW-}X9$@;f{Q-yt-<5t6nl=(`Mv$M;%>xg@X32RT-rr!S32;OsuJiUAH> zD+{cxB*yT5EbkZN7J$(y!iiRlxTENr;sd}d?K^pAZq9gk_k;R==sU_0kFmB9ZgLxY zbWztVcgVycbl6>(N*wYVX}Kqk#jVUNwNEkjUxVWR7^^7sFo;{=k^C8h-TWpBP_dtNBr&}!F1{{+_i zIVNSdw2L01+}ur=1aq?|&!rdc)hC@}gpbZERgEbHOvEnG2|SpNqkezmD6xTQx8VVQSt32fyND&Ej9Zv7Fz}Bkc56b%EThC4 zg2}0o8HD>JL~9nxZ!(g!igi=UCUsb6nZ;5aicf6!uTFG`qn6XqA^0k2Y*Z`@b|COs z(2p&2GN$+&CD!v)n(GVhU(O2#0k~YM?|C!LUVHGC<*>%gs0k9Ye2Gl=)XdG}U*Uh+ zAX9pvIPuJARxwK30#!K;!qL|k&rw7W&rz2`_^>&Y?f#6ACgLMbqB{>Er*yAX;)yV$ zN#w`TM0Yg8>Y)6ON6Js@m|#TNksnJKHYgPRmJ6!m>q5(hinT+b5k$ zoJ-_O6>>e{kzj4l11u^f}2s_eq;LnxrA7Q)S}D zBaSzMFEbh~?wm`UX8{4z^~q)eN4-~zPa6wL=sGT`=oJTR``i9R9;al3JTu1pJoGvu z@9boPM~`z-w?$lM=S($qXiE1%Og+iBT$6ch@Dmo7Q7~D7!$2LC8ki?D+f~!<7g?ndo1H}DZ7NqUKB+wVKXLj z4%K=53tE{}EaT%PhMAF^%5`Upsk@xYf0$EtX_UQai~K*#h!>{G<%?@6T<2%Y$Dn7v z7?d2CX`hpGc-Y8Dm5*hPxdL81uS#KM() zn@I)@MyRK0oG48zHP;)F$hPn(@f@K=|1!)?M<5Ra@eEB$4B_}4 zgrNkvYkeNEu@I4kog#;|`C6I4CFPZ^PJFs7SCs580S{r4=;itDoIf0w(i|>}bUKyjgM#eubUT zO8v%>sZEdFw2vlJDa{f7JTu@yu4O~6wZpGknY&^6vV&f~z&<%=KMbnm*ETwPePHJ+ zN@ka&7nGdTZ)8p6#BB*Y&o@-4iN4T%AqeVkF4H~NOog56s_)g2XzWQ2EKb)r3W%{a zZkqYgL~RBgaB}8ad(ag{$CNfTr}Or|KPS2Xuz^cSN zJS*hY)nO^5IXjz7C|69#@m#|bjks;gDbr_2-+M@KyN-Ib7G<@TXtfsS8ZQ41F8vN3 zod4Tie+*P*O97NY2PgIrSi2Kb0Apm}E~{)<&_wx$CDaU|iND63RO!ktn@MWW#O16Mm6tlMsn}Ll=%~Jw;1l zO&`u-4U$D)9DcDE#hYG|-XrDkxku4DAqMv>L0XcRle`?f(AvIAtZ9&E)?qn;34Z59rqne|)9s{|I1O^rBK2_@$cnDOSvio#bgY z7{y=j?#jqmy`7>kr&Djz>{LO7-7*?58cLEBp&P$%B2T@g^QGEO5-+BIw+tfRrViE#0ywSm9lhGC=g4>{i8~sgZ8k!tJN)RWWHt6 znMk$76kn#XNVlb!lxQg0%aEICRsj;sZc%d^(`kJ9F4na#>e4bzTc(6j*jDuLSM>fg zbS;raLY>#yo!1edcm2UkU0G)}X%E=^{+GAmIJgJoJk*d8%$s>dMztZGy0Nbq+Z*zK zTi5TS3^oZtzRF0S|FbR#=s`cXHMEEJhW@YeRD~gk?KfjDY{ zI$Dgl&m3^G62zc#*EMEv;l$hfc|N)?95Xgkq<~?>yJtme_ic1vIcCfZD}IuhK*Nx? zZrDTjfjLG3WeLWhc!$s)AM;EP_OsUG$0sW?*QIAV_uKT-PkZAK+kumpv=Z2lX^-f) zXN=SO1=teQrSDfEZ8{-}dk3L$%sYpuJ4~eT(V&CG^A{*EulVCpsWt zO#5($NG<+J50r3y;c0X99*j9++JBi9HxKa(BR7X{@fCb+g6dJYauvTEi+k}s@Dc2t zI;L;4l}Sl7#zmR=YUA8&Y3}BSz!&B^IYi*b2GVw~CrWJ&Wy}q7c+3xq1MV6J1t$3x zG_>RK=U;kyT0Z$+`0d4ECf(qMRZ)#(RQqex2{r~4axI&Ls_8+6qT>oFr zU_~c02O}pl)BlSzcDX4jf<3;2PYM zBJ>|N6hKqnWbnj3C7A9OaH4&plp_y;xEU8_`aIssCmrxS` zsT%rR>&Kv7EpMEaVBaw9Wjv~|XVGIT@05qsP1N@kUf9S)l1f+zA898$n0CuNPU|K1?Sf{XzkXs-S3_}}2TU2l)Aq+(- zIjM~9^7ZoWS=Vt0KCzstARx6oH9R7MhlHkR2GX6d2vK9<^GX&7z)6xE^5ORvAXG@= zalg#Dde8N~%#%sug87D7gS z9wMve~*r+tislqi0vI z>JA-gvoAMxPD(t~WjVN@e){#uSyZ(X*e1;9yzJhF~wQ+A|>>y>XQ016x7<2FBknWm=m(zR@$M zzAbLrYsnWpn{tI0TLLp8_Qp7Qr6!_$Ppp}$J*s?v1mlKLjJG(#0)4J1;uvCFzI}Zc zeWCi+W*tRGY2R35j?ZV>o>nh)a*u&pYcK6(3ODQR2 z1T-}@D~Y*!-2BtOa(5oOaceAyqiwG_1nmWZg~zMV9B7zae{glhRPbd)UQNiFH+NA| zYCBqG@2W4ZL&$%Mmp0EGJ6LPPIqIt+pm?PGVh zatBOWmam`Ul2Va!tkoRk(n!+WEpS7St8;J0Rmwfw;cwxr`(SD-)9|@v|543e9?u7l zO|ma+R+>%d`%9Svm3xNQOA|h$Zg;l|@i0DZ?Q9oT+&F$%ZO8K)^+eMgGv)N^V6Zf* zjJ-p5o>#toW;eHC>e3Qsrwq#Vn_c{}K)=OeV;2m%J3L znjSKpP6vkY+@Wx>d4cE%8$pMDslrWI*^<^A@p#68u3xbB_zB!B@W@*DmBODh#@&<1 zH+|=0qa-&03wR_@e17s{VlYSPNFcbC{=v&O;SgX7!w0wokWfLhQVf7{OXoRh(tJ-J)g z>e(83ic{CTwbARZXxVx-1J1lKg`Fy7wCna1HH(6WQ7h-?LO>*HYWE#o%NjMsS+!46 zme;K#t!OQGNDg^M3hoqhFMVnBT@%vZ{JUO*P^IiQQ)zl~W9P|f_<2U3BsuuyR+2X) z=OOnCl(O7hzRuR5E_XzZCbwZ$Op3&IruC*s`S9wtHP5)A{N=TF$qwzNh)4I_U9Ghf z1B#b$h9{=NIXi0y!|E0u9NgCDWT)2FA&uF;R2Yl%2X_XAzOeQs%{KZRzpYKvgU#!` zyv%lBuF$o^Z2ydVOK2sx&+X@0?Hj`K^jr(o?w6EZ1$=ut**==!mAe!aNgexh{Rp@x z6}IYN4GTgx<=D2*fn%3Hge^$Pi*(BS&|u9@0>UZZ$EBPFl4? z{!VHOR!#fhV?4N%t%V)ue9Qd<$1WB6OISM9_R)Nb&gEXVG7o?9f&FvEQabp&Bl=@t znBvrfVLxY8c+O6QO)lr;Ja^A9cSYSq!A5!NI!Fw_2wrTqxb@Re^l?Q{a`+3dBZZN5 z&~NMu7S_{d+zsEK)0RDKFU56;r1x#ze)GRaMMp!zzefLpF<7v6-Dk-m(CFE?&^fv0 zQfk+hSl0{0O?a|WNM63oI5`+upxomG&lE)W1(ZrJ1En{NTsG4Ef+3Kd1Ri1kXMhFqO=sd&G8&_hfcID_*E7bafW*;aTGwLxd zGNoN7cBz*}S>C7o?A5AX8A}!SFnm=&ll!02e^zY_?;sw%lh~V9r;eyo^UCOH_(W!^ z?(uBZ0JwbhK-d8=yARQ*B?HLu()MF5AvKK)uTP~S_U^wBb3`t=l?ov`wr z*|!J?`VupZN#iSJ(D*D~YJb{CgI{um^?>yH#+OaFf@gkLEG_V3jPbr&y6>io^zG99 z>*pzOgBQ%(bX1Oh@_ej@DBI4C((?lb$BpzP(ib|e$` zQgSRRu-JXwQSvh4$p(=v&VBIWAbr&@z@eu;}sA#lfci%|<9)FM}&CCmLQILfcV{bFV! z;C9&06g*z3s5vjCp z{y!CubdI8U6?ZW}t-C5~X=@5qxeRU63W<^?gyd7vBTWc;iIB`GlUfp3ZpFVOoutE< zQ61bL6r+TeBSwo+xA@%fMb4+ZEOXB;pjwi9gV7N{Pm7U1oD3lmpCW2yJ;s4fq<05Y%GGFcoE zu8b&SocfNeZ;z(_lD7?c|ln^<35Z;A}xjLjpzrhmR}mD&{^SYO z4lXo;@&nlO046nXABt2UT@G{h1b{)V@JGP|FFaxAZjPS|^yatWffvyfXu08YCe%O@ z&ZfA^AObe=F>c-2$l~Y%B|evX!LgB(MVNkylb>kZ4Dmt|DOaG691t6XTStBzpcQW> z5SoNUlHZX`Pa()l2K8gC^`qLd=k}d+pQX#T64HKy^3=INGI7~t?KfL@MT;=m5BkIT5P4+L38OJ%CpN%AGnsESbT25Zio<@utM8n zGrmMyh(ZD(5rjgs3dU&n`NTnc3|u${oryjM#&7j=eh_@Uq1(^{?l3+A1;<7npQulM zp!4=SuYBUYt;9a@#P_6-Hbz(GX8@1>Jp}yr;}o(^CCrVy@+i);P@P-9pV%`4wjOzs zWyTv`@xyw5Ip_FB1N6$F&%ud7yFM5Lys;6#1UA?p3{Vaj0nMO3U;)k`InX;`Ac!Ci z$N|vU2;IA1gK!af;rdBIc(MD7L3~gG#=w4}^_zj@f$T_u)PY>14F%>$wCVh1c4$YN zAJCG^6{FX*C@RPj;~Tb_Kys#*$r17$;cZx}5M2ReI1D%F@JAjHkUyJZW%vw}G%TnT z{R~hJf$pR)bD4vQqnN;uDcp3TK{^H^Ir7IMVUA|_u!oZ6Q#Lw^!A{HWi`+RG>VNC7 zgWg+&nYKpGS_Z#@3OR~R_(KtLL=Q8)j+8}f3^y%@EOIC1MFZjk@)M&w4HC3mdOC&N z`j-=KQw{MX{YRU+sg_9EdV<&C(i%^n61DPK@H=EB80Hfv!G68fVPBQFT`Lr`MwYo5>@V6u zyQJ<%(A(=Kd5wYG!%LoaN7Yjqd8&@fhgH9%hU3(Jdb^J$LN?d=lkgr0o- z0n>xoa%KE{Idr=jfA~rqArLg1Z}?2mfBVimdbp0#F6Cf)vv)Qjn$fD~Ham*}IlGYPegbe#**i+6n(SP$X@ z-md}CE3|_P*NbX$;LRLjPuYX^TqiJAVQ(*69N>mRo-qnmpVFB*QPByU!A`IsIA|0i;5l#<%;WyGAET64 zEqve^svkR=Zb6n0?GruV{_P28U>TyfbVmoF*LlF5|A_%&dt|4JRlIju_(^|k+6t}L zhxGZ&h10sz1?#gMd=j-RHGn&#&T%SoIAiCSPy_T=B-a;)xuqFHUL1UF2!2*cVxC z%C;r^9L<@)5|(O{H=t=sjA|D;(1XcoGm>?f7p^ESg4sp@ z4*A~Xg$!q#i1c|hs2=T0ilYJ5`)wy1qWAl?9H;^MlRW6Q%eC6ruSWpPHs}i-jzMIi zPxAl=rVqn)E@-dkPIKT40zdTAS^qJ_Hp%tk*T82b9|KXngy2|%gxG$Y!Juxi2$@Er zbQ7VXHs<_zNKayngAq;ibYmg?I7m;k7}(pp2-sVh7aE#tr2W8p=xcb8Ud(^01;UK@kST2(U5lTSROF#&K z?!`vzOh@dPi(aQ;kv{!NfcZ%Kz>T%9Nc7PeXovT)547j`$CO0*uoyh@6^x13<$w%)x80xKY7PQse}AB!whKRZ0!3 zO4KsB+}DS4>?ZqD$g&bMq4Lf+yEq;TZY*X*|BZj{Lwq^PKQ^_T&52=}D;}GeT$T>t za9p!C_m(R~ODd^Lp>i!ItAut<2Uf-}M6;Cgr;wW|*Da(&Nxk0-Xi5U5nt~+5&d5ZD zlHQPrJSiHU!cNIFeMqP8Pna2c`X^+**L2q)r3e?mL5MSx%aAXK;0R*_6%FCadx4S@ z$>J)Jtm5gES_Y23!Ri}K_-2|Qq1$|tpRihv?sK~lia(9;%&-Y-RZsNx^zKbqOT}@aTrmocz^gD6VL@7v6fM9fAgMSCa6k@YkY|A`K7{+uvYzhx zVSN8sl`&Inb;L2F)*zMy9SG8#tot1&*+C7~3Tncu*_ET6B1k7+2E9HCrg~HBbmrfd zLMvVHi4K*9KcplSm4}=cq%a9i#aLAO31DoZMb8zCL?^Z+T0=>iPMT z^*Q$=0!+<{Y+)?m1x+y=^Z~n|7i2*r-~~$Y6LP^l;Dtc(6MP{aKd6%i;%vq;kbSE` zkO!3J&dQwr*{iAwoPwv%IN>aqxC20E=7#P4gwo_7?Q8jy~i|`>@w(2Y=WNf2hm${`Xo3f8332gh%(`z21mum)Ecau(-3@BfFry|@AF<4vpRTuJxn*=Qu;Qd?hhl<6B}lALR0hwr z*`;U;wKz|t}^@{G&k-)Uc4**rmXt1H6I*uLVLR+>bAYuYVcyh@}Q zAAB<}vPfknoid4pMynE=z-SVk&cBR17^2JSqRZ@tHsQQHNP0ZTdR@kvczQ+XscfJ5 zVx?vr36CJpwr5tWuv6{@K<|j&M?lFTI8EzY_yirHO2?r}mhp3p6`cW|hSDmVc3K8N zGwlgMaU1;1fA&V=PU-&0nBLmPc}u2fvh-%wfWvgO%GxZ@uR)D}d`In>Cc>ga8Pu8EB7!hRW^ z)c|utC+U_g3&`IWSD!7RHq9LKKKBjf3w9)96xy@0u5X6Y43=7QfW)QN%VWV5P9|N68yAyaUB%K*kwz%K1WUVR>kMa@*}-xh%?adNMIu zUC89fl(`d<4CleOTQDs%PS>oN_GF2E3xni94RfW`<;e4;{s?r#m^~uJvZ_?n5)4ia zW!2`=kvOj;#egDC3tRO^jM7It^o*FSkbsWDB;psO3zVNMnCF^3kXGq;|d3&jZ_X|OnFN(QfpOT<`CjJ9NU-ikr-SFMi zc!0l3b1+)uXV8JtI~WFk#T(Xv$uSY30t_55K<1Y4w&Va4&5pvr?<&^C$}cO#w_|z{ zO&@;Z%2eqCUflPJXiutkDLh+3Zg#mvZ?sgQ$PJqU}&%%lV@Y(+LiCzsmOSF&)(8rdAwsyUV5 z;A`HB`kz^r^@u6wzX?%(RWtJG!mRCdMqoBW=`J{xbSG}hPjV3oU!H2gjThm-pme?A;19v8+XtmS9;D}53=+nnsNtS*|T9#ZC$u)4VCFX_SUW57M# z`V|40b;cP|E@gkA-s76`{~;Xdei4ok{~;VXsdsCB5snC(WLMSyML6<~asIRHdnhzfC-Mgl|9L5i{p#(hZ~jGI7zUf7lTv^Zuh7UQuM{^ zQnt@eIvPpIN~ca9#~8Lw1Js2yDX(K6m5eXSt8S6Bh&wl z?86@Mv%4{G;UwDHBZq!ITo-qYAlzn-a*y5PE9S(LYusy)*Y?zhWxh4<)f!Dj| zkT$f8*SmX7h;YpLmOj*u*SqhKH}uJ=yK~JK9*yU>;}AI%kH_Hr6!`@_5^(-Gv5SeY zj6}9a#3_mAf_INc!imL+#U<(#v4=E0Ff4Rrcx1Rc8zQ2DFwMz&JR2k;gTRcZ?HF-5 zn@`u=YmQV-Ytu3`jB@{1D{i}c9bN<8MHM6DEf zQ3+2eO0p^qd`t?|&Ay>N$3N^NcSo#IBhGLZ1X9kJ0|$<9CA`aBrmUeJyitdr@k5#j zkIrAHBTxi(gnh0Q=ZyY=-$o>an`8*djsubi2#8J@#wj!;r4yEw(oQ&~mEwRbC8uvu z4ytOaH!DuF!EL8)c#kbnIlFG|a$>HTJ)MFHg@arGlzRIg6&qTaDq8%j>TKhAKlm7- zX`P@Dm6wY2sw>&kd#YX-%9{uI3x7rOPgdjqrV&~VTu(h#xJcQr$k9&xG0acez~==_ zU8jX`RYb5TbK-rdew7>JhvM2;{7Yk2KkAgeseUoM%l3%p2l+SYD|`i8#w|9vKj<+W zPiYG&sXQloqo%m-4^>&8@X&}LN~9KdrWdTV7*f)_+X=mp97A*!Pz2+t{Uv5g-M^?q zZo5Hu<7c<%sNJ*6o*by}fqhs^#OzE*9S}77vr7@#{Ldf#s>! zG@xx%LdjC_*@h-HiGSD`oOw+j@fx>f_TjR#X99sQ`rV^vz39JhDt@x|IV-AP?1A6& z*x0E$_~v@z8WG3U3dvk{NXpHKZROSf8Sa`5lK;MWhycyryiNmI%CVI`l&PZ3)>^hU zkA~a+_hH3QP34}aX+kM3s`gLExBPDssncpY?ZZ<+IO*%BIL6h(9oAauqkkUeQ1R7% zhR|BkBnD>~j)m8-9`{nL>$W+m>Te=wKN0RYblCow_MN zF`=X^|77Y-H9?DXXC$dT&@Y`*V&Bv6?Z>ezXTAQr)t(lQqw}EFc82Q%YgRhmEVgP|Uah@aBD-2b z_e3!Z050>cUBW-3Yb(D%Fx;tA60*gG4; z`Z^T5L1w6RZOyb2me(u6Npo>&rE|Ejv#;_V)*CjlL?2wM7*;#lW_h%_?MiCA-vNj9 zkU|p+Fcm~Q^gD%XGrH@fxg{hv;f2M8vuWQv$>=7{09wz7?Q6$uD?M>MEG1hwp=y$E zQ6siT!?y{a?oyDSEK6inrAe17A(%a>Kq+5&?0WJGVZ)>z&oR7;eu3+?Jm*?A)I+Ja zt~-^`N;gV?T$}uZTFTohDl{ zhrbCN20X6*F6(Lbx^4AFtKRFOm0T4O`M$1sN(2k1PpVHon)k6!G=cTKR2fiF9fpM~ z^#RcAd|XGCO6P2?s_@adf^Ah`fw)WIGkex(Zxb+`fHCgb*hi%OY+>C#-YknBuI`Hk z?%SQ?2DY2NefFgAjl4M0+Ml)U8QQuW=(V&txKopF*{9X#KYE(0 z6NjL`S#3X=tNlI0YZ(xq_VKPU7%jIGy-=khE$=*^$N!CEo}$6I>2`Gx8ylJg~2@cgIv{Zf9Lr^?&x#_X5F>trd83jxw+j-mT`s~cXV-@83Vd5g>INEj5e_9}OH8VcG##5a^BIK8Lx?l)i1 zW-FMy<|ZC#+W=R+j)|J<-XHBpm|Cneb`I{1Ee;Cv!%dBMIJP{C#n@?{U^!15d;IjJ zr_PvB1+AgcxrgSSfb1mYXiyGDd*7|6y5sd(!|J-WR0WKbY&UB{ENWbZ25Fb-9ak<>CC@Id#&Q9;;q7ym+nJaWv zHEmU1O+9OY9k!BixOoNcxy;hzlPco!>cKPjM7bABY8-G*$f6+j-~&q*2)e*p{SUeihr z$uzNYO>(Z<3}umZQYT+cN?9KWA=^eKqol+w#nH-QFq&8?>izTbVaeEIlwv-iTziky z?k!pNeop}kf{)E6~F`$zDK8UPIY%SxQSw%GVY(DTN7t8c3kiqjyIc0HwKnAX|fPntS7>Xblk|zQI4IZb8 z<)BKUEb5qGW`u!(AZIow`;}CbF_??c!!@;9FdXqvOy|VOoGdA$$r7gugXy@V&=4w{ zBvDWCSWJ!3zru-GA}P1yuVk^_lc`-dEf;im2dV@yM8Bor{0Foi&ih2M!js9u2odIR zzorw!Y^?rWc?5DiX)d?}ridX!=8z%1CM=3DXDs6A#63HN$6v-RKhuYNo3LmvkFPy|w(R700#MB{QMqK3Mof2it_$eOBECbA393fXAjoUUqR(^wG~LBm#IrJG)|=X4 zQo(55BSvU8yKMo+oevO8;T{I}HBIG0Whk)vcw~`MahL zSN8Vbc1#D@rRAo8$om!x($syjtqe$n&kyhfgRYDhCBO>NHc{ANYTMe)U*quVPPdRr z^}{yLcwXWiq7?dawU}WWh-M3!*1H$GmyM^`kBD)GW4MprL4UCQZIOX#J4E+h%{>D6wn`P|+QB-tX-vL-J0Zcl&TPB=X;R0gZq%g%>1=ChDfIk+l*Hi_3Op9;_uY=)@Ydbv|O()A7FCZeWsEE z3nJI`7eC?s16H5hy(Y*a^1YH4+6K^u>q-3>Ylp0ba_tuAp31Xs+PdVa`?1Ml9#BKAB%Mob9vtdKs# z$K!7!BExPy`d=d|k@i?@;&;E_;CJK1`H}IqO{_>MkJnyhIhH#cFzjquCa5PKqt zuKV}Enr>9Fk8}|O=Ww0nBK)7{mWPtd1s$#vGQmB;r-Y9{k?8^~UY;NePEp1K(zp7t zqs3l_+&^ zP=XNk;2SF{eRz?NNlVt)VfEq@eqP$K=I=Ovc+|js%g^}xRM_Z$RSs?_%KcuqN^|DX zR~XcWzU6|1)``sFnX|%K>Po!B$qB$FKES)vVLV{em)tf?a0_Br43nNvuP5KKZhWEh zBqRMj@TWub15SIY7$QsI0su+}JLiOq(uSqh6XG?iOfw9rYaxA|$?`7i8=S$U_n3vS zm&kZn6jm0ZmqNyD)qt2fUNO}Z{H~Z8Gf^YaI%*_J8=nbUk?PU&ebPWUdT}9aNfBB* zdcF^VetAD>Q!p1m$}la*c`*H*1{`{0G&*T^FnI5)GcBG;@)9B+bT~7Fi_F%VPIp3X zYh{nCZ$Gw{TS1${2Io_W6*kWdVPW_*JuCa31-dMJ58~*;=$^5Sb^qx&C@Dn}r5qXw49#Q_MV&yOuHdm#YDXAY zckLU9gRN5#iEza%mAsFdaJp01$!T9>0VDgCKqfpFwGwmR2%;7k*5*4OpeJm3?TFMCGuu@HCdT%gDtRSn@ksh z07ltY!!^Wt&ss_&ireZ|EtnET&;6%shDp!;lMPS+&vOY4-%LnYCFG$uAOYYWb)lk8#oQBy1Ba zRNeY%#cg^jg{VR>YW5o5cSIE$bkrie+O2n~3qk3!C1vOao*sq6!n;1ZCiJV|+bvT~$x>YyURq#q#T)Iv^BVQLNnhI!Rx zJ5Fr0KUp%w2U)+D%`wFW0_bG-4Vwm35t8|8f?fmtR8z}&r)5)_xQw!(l5xv$GR*r` zVdv@2E!bt92PfvuT(4+uTfH=h=|KR*3`Jsw^rK=e5SVkyx}uZ)+Hp>rfzg&`Fqm@+ zXGFPd!8MSk_(Xp|S3!P>3$lYYVJFZB*g%@#JpKXUB3%@ne~DQWrbon?7)3=r-J0= zY}Jm7lIdJ#MeA=_$4-ir5^M3wPK=bg=t4L>y2G=*iY^A?kf1IK$wj{MZ1qPaJ!r|V z8D8q4$4&mHCZ%jLh$OtGQ+HziP$jTVhVv2cBN1G!>@q9UYj6R#OgJOT@CWKEd&wNtPiDhdv4L2TfmKC^L&H@ihh#;EI2}gL4{9W~1cEG~ zGSEG!5~u|1fCVrX*o4)9DNs`eqC4S$lSLsfD=009U&exIAWdiqW&w22rjSImpjwc> z&X9s)ka*n%q zXV%DQeT5`ofbrUN=Ih8=WO>L;+wTtA8;w@Z(eDFso>y5y@B)nfK|kv$jyrFD*@ zSkxExtRkMcnm?`S-Z6nfFbf92BbjV3^`cg++}uzx2}n!>s!GliUm#SX1L-80yJnAt zvk(E8l3l`U@W3D>=e3f+mdef?3~OrokQNvqa>CzW7m$(+=M!jQZY*G70zz;L959ji zh*fb-mQ^Et-cMWl3sQ#xq>&sGvI=g&Q|2j2CUOB0bpC&e@V*b_J~JdJkKbr7ol;*+lQKCE3KAV5jPm?LwXSz}y7mu+nY# z)4bWL_Q00bh&$=eNHb&)I(QPfH8FB8Ngmf_?~1Y`r<}Z6$CsWwGsc9>R!6U++s?2p zdC;x*Yl48s&mBHV+lO!}vH06*7fzccZV+_OG9o4_;su%NgP!UWTZ0_bM50)ZjJ!ZTDA_|&R6#X}w#T{A z7TA&-HTMlDgdfg~LuLmb=E~3`e2@oji^W4?kmvi>9C4gd;8q-om>9XmWl^EF`YorV zZ9*pzy#)EX(s;7sID%z)K@zRfxV-8utK}xK`mHT|NhOUqrQ{V*SsV70PBK5lg}ua? zC>QpWSMpe-69gEVz!2o(7*VWJz$#Z#J^2NWEuAFNLpUWQ(gQt}medgH!~wD;)P=g> zm;52#MB3Xpt%d@^xpLvxmAd>W(IN5$2i7Lo1-tN+@DOi8p4v%13U*=weTjePf|aT# zRx*^EX-gvtd%*zxgC1WDp^36Ds&5MUFA!$IBguJkO zZ^^!Zd$)C^$Lclq2?pqsr>7F18dL<6p)Rp{%iMSbIcr0j$VCw*(52 zHBca$qzbVdVxt#$>2pyt_bC;9DObXg@ERu2N3u(B4IOBgfFZbs3fxM-5Y|R3YLNjy zy*R6SB%m)PPe2H{=a+;Q;YI@*C8P;)qX3l>;=)|uzHI3=TY>-$$8Zg=H6BVlEV}Z@ zE=!k+$^M15(MX3%b%0t{TCHLU$D0ntitLrzQ zG$V^5&vpsZw!JdvEHuH1%!Ob;7xfsEqRW`nEaWV#oxFnKOV8T8MKC|~eYsFR>Nq!4Bl42hP%@MpAl{G}I%x%Qq zG#?h7S_yQDrB1PzExjCdp<&mqT*yGzPC|Dukz!EiU~2|sn40iU=_MR|NIGf!>>?hA zlyp)c>)<#Km2^T*+CY>dK-yd13zNDmcS6Fg_f3KZ=S7q916eVWbiz)G$;@;_OX9_m zA_yjn7fTu=9&ek4YQ!b$=<6iBpk2O}c#TOWa#O6iA+9J_3~EeT!_7^x%L!xcqMp|T ze}FqPswoxTuhIFOzRg3n)q}yI{HqIknAj8)(5T z<72uA1rW-<8gYZn3uPdL8q%m)WR;Yjf@gfC#UB}Q{rAkW5=Pum^Ntzv{VphFDonWu z1FVXZzk7BYu$%q_Q`wD4IF z>c8sYKP6RAW38ICRNFw|KXT(Cg)#gwr5v7Q8}v*`66-e)fnp|dV}dU#vOGx}MXaSN zEG7R@7Auo#zIlig6OpgOAJfY5Nw&fKlM|6RN<(I*cT7BI$_*5}#oLHx9>~|Bj!onq z#M{Vbppr<#?$C=bCH(lMj)AZjxC4$Gw(H__u)>dCPSWBKyZf~A}wE!d!?1o zSVMdXX1_53NsR{Ywz3j4wstL_uMq<~B*<#fJ6utG&>odT2;T=)e(7{C5m-_yYGDsb zXVQy~DvhWs)3a0%SW5jQx7R}6mmbs**D~VoUK)AFJRH{?$^iV-VTe_Lt$_N>kcytB za9%XSATo-mhHELauNI`mdLK2~U6PvHAwD{^DQt<*UMAC+it~99i{TUnK%t=%mU=Ha z3j0|vG!;c^6gKkSUw!{eXa#3Z&HSaGbbOdCwo(y*5NcKrIMi$Lt(=%vNGYX{vEMDN zyPH>%D+LQ=%iap82(g7#`pG^XYWpDv%(94d^3J{#GR`WED}$LODm1!=K2?@ z1rPED2qMqI0rqVheAKk_tZc0W5obAo3H=_BpcMAp&|_{T(;g34P~*ohV#@wG2MYc>Rz`S{%x0$Li503q#z5AP)BUa9d&}Uf?L8p`ROp7EVdCkGoZC ze#2;7$q8s@mi0-KMXAv&3uTrVc+kg<26_U_=NW2Mj?S86I!+HY;e%+{S;B1zl*RxC zpJo++|B;t?0Q(~>c3S(kc~<{NUV@y}0XFwGk$`g9&k>naX9tnBLBD_c)nas_f!^3j zz8;e+MVk5Hf%@44A!Z}lNf2haHMP&j7r`FHAT0LWuw!hcQou7Lh>JZp{Fn$h5w7k3 zVQ^~u`blujN&{JYJqSQd?8f28gqA>PePzK>E@`!p5qzCIyFq4cUxR|Qk-0EtkQKJI zo%l5fUx9Z}BZ~nQ1P#Ol*uiPK>G}HUt&7cEF;)LfhQ%_;u9{m(h0#I%Xcc6bPgOkz zv6^|77-{mII5EO+li31UNY&GF!n0^f;lBr|A%AvLNXiM3n=qq~pcLp&%HgE8w$K~N zWH~5niwdgF{BIdc0+MGJFw26}q*0ovV=a`OfBVK2%gxk6Kt5l%Wfj6h1j7dh!-ogM zhgS7O-vUG55>A1=X5^_mk&-2z4%vX5wEwjV!h(jp5<(wknDFxgWCJVou(_wHVC><@ ztt@I6>Q{QW7d@HvO+lOS$nn~Z0^GPY@mRj8y0|v6fGKc0;aL94=XK$+45MGK$0(@* zyJ87R^(kS8(5&H~9q9UD36Dh*eQRg9YG)dZ@2aGjj(I1UoONxIrve1pB*of~1pd~E z^|g6J4Xz)JU0d6RyG`T|>Q@LIV!6VOG$9-Ya18>R)r4l5=9Zh%{4z~S#6gZ8zm9pb z%vMwqGrgv;K)Fo=cY-4Jf=WzE?Z>{eqz2|IirLC9N5-?8M}f21civS(U;JW4IXjhq zD_>3>f*y{ljss1*@=Ap|o}P!Pi~0`nak`N0i?ittDhZGC7QuI>z^-q{!R&!(vuNyZ@UyDyZ^*N3TI8B~ zRO?tLuu*9SDClm~`g=BZEMwSohV=4I3gvF@3K@nP5o=ro-b0vT;Z0t<(bSeTY5`+qiJ}tg*{MMK2TYr zkz4Lk_DsW2mLb|m1QEiWg?|z zV)!GAf!Qc-Y^j#9W%o3*Wp~7deDN6re7?+Rp7>~<^l095PV@se($gwuiNh-aeFE9KN} zL;C(-pZwq~A4x~A0#mm)d6@c3PGET_%BWGTM`PTygV!>EgI`itC3?Uc~knBb~C+Z!lD}M*S_wJT?Jdd^-*Tl76)nR>CsNf}gbjl7^L2R>d9()N8EQb%|HH zP8y-id3?3f2z{cka}L7a{{#OyQ3LeEG0G>VA_7*m;jR*+Gg0HKdROP#(A*M1+2Gm| zLE3QN5<%NQ+UkVgaPE1jmg#?H^z0v$8IOn+gM6Sv#$)?IZ#v|1jTjND`zZiLx)rK_ z@D!i*FL9sCb)jB$A@b^3;Rlebv^(U6_T~=v=8pH~4i*2BLiLhLHCQ(9Z-{UpwgCa} z~3}Sh%LvNxCiGe(NC9}SE5jt?pIyVmrPe(u$N+6Z+uOh$bE)Ic4h(cjUm@? zM?q33f1$T0@$rLya3d|~v)}38rCM{Sh0t(TgY#E027!RdG#E$9A@r z9!XzdAMBrl1vRtN^v;P^5iJ>93u)ZDPqW!S&i3K*vt+v57xSh&C^UH#CZr30%u=QA zdyO`)i5oMomuHl~;pqE?Ke|t!LNdBlKfaBZ2wyl)YZxHg2FuBc`_UDbBz<`X5I`Oq zC!t1qKo@&U`l&{V;RSZ4K2FxA93~QG_&I;V{Yy2ZT*ZGEMRKRmL&nw2Pv3V#p2?Dz zAAa@9VIJ#jin~9_fb@L;R`B9HBls}u!Q?@l*Kd84OqmbiY(<`SOv}zL6Xe0-&wJzf z*8EuXs~@m|G@1%nm#_T*{w?D!X`>{#2}&EDynkoOdTHbIec$60+uaQpcNnOinhn$y zz7gEd2uAy^-W_t+mJuMtex)!b8T8xckI;~quaN#%5baGWiC+d`^8|hMUQV7Ok9srKH7&?FUFR2=F>}bfQ2v&Q%R&_bOT0|bQZ9rc{Z;F z&(~xoUHJMg2i9WOn2cj}2UUb+%*$1l!~T-}&+a+8)n{Niw8)b5SkA%d{?geqBW?}gK^ROtSb2mCx5 zg!=(OYWxR+gz*7ETGGG$LePUA2>yQ{NcRX6j*dyM(zfvAxx7#Q|7?tOv#DOO)N`Wq z|3Z!Gd(E@Iep)uoHloerhOGD=^`*r<{t^VbTC1~;(5XOM!E3mRtnf^XMK2(w7_j?V zijnt2J}|SGQ*hbcM`1dky;~L&U+2Aodpcb6j;y?_nXUTv-CA8-LP2|KJ=(l#>Mg6V zS!q`2G`67i)4SF&%Jdxz)hQ1n_wcN*E8>EH5XS08DQ5+0b-F`(C7dX0+!2)rNmnGw543tF%eq@KO;RGU2uYs+PnG!i4ZMtu9iexuV*1N-WEgUSVi z>ib5W?!&cACE5{-F!t`v-(-gyFRX_mlfD!F8@ETJ{T@13A$Ly#?sQ~63ER0~h>+-1Js7Iv%G3fx-9VCo*%T090%=Y zYVhw{Y(^UKl2I;YsWxOVI!&ey53@Lms>Dx1icKo%I7|)$sq`vdnE^dP#ds_ZlYuZP z?#gI+M#Fu*`C@7wf?Db_2Kf_up7{!pzIKiFzP@&sM9%CvZwF%kscOCVa%>=x@gUQi zSNF72%iAsXj&WWy?=hL~Z0TMYPJM zJZign=X6DZ0k#8bE#SewW2_@@+z=ZiYibC4uP+$XHG6)?riPzJG(zP2o9Re9Pe+oX zdgGXvP-u0LaD(>60MC%~R0OsC)Te!sVY63ey?f(Wlm0bGs4vioi$~%B-82tpy*pgN_YV`hEy`_Gk+idA==0q zM=hc{O2z<4_N}HFqoc9MPLmNzuQ7;|R|*J)Z4L?ylLWhtP1S6w3D zwd`8pj0D!#6JL}pjr}6@azN1?+QJzY$S$G%A2yx@eg{OO-Dl%G;-~P?B8QL|7 z-zZ{zRp>jedpPz<<;mT%@P>^4iy7-7Kanm%Y)W$LH)-tOFh`X)9&K+S5wMAi@W_Z& ztC&|vWCTWC3s*u5xyQV)tvp00V4drsZ!@1{s8g0dG2nXRbe276pw}#B^ibTZBa^ za!oKApV_Cah3fb=0N&Z(tNEpbY= zNa1S!y^V9N#Kb%|)*yxm`Q1cOkDYL9_!p`v#VmBOzx^mG#@Rc6%SNH=`gt zsQs66vy&CIw4hMn8>eNNrg>g{1!N^7b(hym`cGJIP_W_$k>=0xH}Px>Z@HT+4GoP# zwO5ht=?4fbSp!~ogPlGrK=Vjr^wX^vK{KmEGJFr3O$N< z{|p2ggbJ+zK8ojS+y2fana=UN35SCS+rJKp1Y$DHzjGZYdEFK5y@vnf5bM}+IaFwk zQ@dg$7-wgdSSh|c5b**UqgW_auw2_vthbbiCi<3n9nyZe@0}aH&PCkr-3B~$K;W&o zByV*?XRNpo1X=a(&%C%hV7Z2)=#I8j7N6VsuCh8WMz!b+cygZmsk=ZqHEq+XyEJ-K zh4+I-r>r#H>0M%xpFXKHRk&qmRWerDwB)gcOCaJ_-)$?agr|=jNc`WHT zuP>+Z8LmiQ(dx9@`a|M#W}t0OP8=J$tv9D_K)tQ^@!=*vsXpP)HUOoQDIiDEUellD z6ZXX;5b^PRpQ*?kQ+Q?qUuf&eqOP3PC~!rG2{fCT$yB;~*Sn=(&~g=p$0u~%!Wr?< zHm`OPF+NROh6U)KUPtKbp+9Lwt3AnKx*y1#2y}4SnEj1+!FH*xe{0IZb@Hgb5i$nv zmItYBLKx$3OQG4@8eHBxd}kW&=n%J0=dPI_%~qIHGnsco)07rOQ~V8EDg^G|4gV(i zYuy5nCghSAac?c%Ax&tk!LP5YTVqpYFPy#+6|kHNF!BO#@u@e)BrQS|B0!Eorgo*Cs{lvzEve^p?{5Cn-9-+Pw4JbKJZPaimpKKe%$i zXhg&NYw#1ob8Qt{?10-1$@W?X>*VZN8M z=l&y=Dk+#*8%#H;bvq)N)Bp@eLBkxqe>LcR!WET0xQwKECvURqI`YTJFs;M8_Fpm& zN#VpH+}Atu6P|ezmOg;C`T}JH`kM@*=_r%e9uS>=M`20LWO;fq8}BB&hJi~m6PMhc zjnZsiPNI(we@XH{9~lo9LE-LeZVz$S_(jFQReklT*c;C)8)dPFwuqmmG5fr~EgAwp zAycjwJ~d1AsRl%H!!ijG!P!U`xl2cdqPgUc-3@Y+VYQ+lyH$&lrr(LfoO7`fG1PTU zH_Hv@cTa#Lnd6NWU4m!Zv@5fu3INd=NaWdskmcS<;ca?~4#K7zi07}3l|B|TgX#KN zmORURSZK*?X|uE}BCqzTqTN2}8VzqqH`Nmssl_7bfz=hGe&)#$5r~Z`DLs7vtR%i; zMHDlK6*E(QXA!4H!-(_=R)Lq_{uDP=SIGfw+4ebeV;vv%pCf7LcNr`Vu(gU9Jsq$& zccN#)OfAvsv#JIAA$t-XN7${61VhN(R0>8|VLcy&bdE3`w51AqOh;}EnQKW`feI1! zTniLF0hgKy<3r=G*z;_J6Rl9e_#&0kWoz^~edwQ_Q3XN55Oc@VKtdcYH9YkvnzPQh z^9-yx-q5!1MKz%1Mf5pOXwQCh@wZ|!`VH0401^n(E^XK=@;tUh%9my~P9V8;hDVYU>kR{usPaR7?8*dZ$)H*Da9 z2VNeWPZEahB-`1uK1D~ek?EV&}AO_4)=oU)8lNpqiG9Y+$r z>9z=VB}~t)Aqu?$0e~Y=PD2+vGJ=_9s;WXbGQ#QB5SqiCoU)rpKgHS;{>`0J9pLT2 z|Mcn8Thdn*S~~j?c_smU*|$@K6KuB~O1cXQ7dH%6R3`91#Er>qW15;<6vQ8BjAA&9 zy}P2~Sa@D4>D)vQPexmT_}}x#QZBG=bNa=WOgD3_^xB7jgf{XpYN{{`4gBvn@N%rZ zCEuj+6u~)qGK-dBZUQ4MY3$7$Z8a7i#>&pdlK6`pZBAw$>jOt^;nSY00BPNKyIamz zX804X4H}C8cQz4l<~>Yc4JJ%)rIdJn<-iY_f>gPFc#d$qD1rmcu1cGT0Nwjeg|hae zFk_Ftb^MwOibvD$?IO^DWQ=nrS`}|)8gOdWs9(zc;FT+c_M+ytv?Z?Z&H=v!J?v)etPyDkAf|S)JU9&rT9RE=MT2@4!(S^U_acW#_9pAw3<9!i`?Gqo*$K<+w zm%4pdy4@^&BAa?ev;8Z}{f?FO&M^KScMvQ}eOrrv_B;d*)T*j+J`rnr?{0b%DmKKH z(dW)XbRBNiYYoOqwwE75RvZNwZ$6ivG8N^CYnlUTn5ha3Whmyq$094@aq+e zVvNxqclOO^7bWK*<7^ZC;t|+)^ql%(4~pb-wf!ADdVWAJJO$ZETV8)?V%sOwHc(Q9 zKD*IuQuQ(Y{0@hv;^*-6Fop35Mi!iT1Hp8=Oq-bqGIe!d_aHMK%S}uZO^N znsPzWTaR>Q>jbk|ZN@f0t)U6Ga6+19?t^*UJ>dr;`kWeSZuFOb$CfRHXp0}FW)&U6 z9IBuMkPN&YyzysI;aZS3q9Hx}xPid6HDanM@P})F{m?mx>`3nLs2&Al9%WeG5yU5h z{DMt!s4TJ#Iw4B&gOSY;Fe@CulKC$Q&FK3plyi34aS3+Z_B?t;^V`&p2nIh(TRA+2qdTjUMH4S&wJ31+}U-2ADOpHB$IIVfvCn=sH$h9EY@L2N>e_ zwSbhm%oJm;ANn3%Ttr4q6@5+<`W{(ags5m!((8*Zx0)vh)IFzor-E8HP1z>KTsHJQ zu6U=i+9mp2JM_ItTu{PlbUR$T6Bi9z^t`9x3lR8sLh_hw;9fOurmF|~T=8JGHtN)V z&u-H!;?Ft8s{!KEyFu^fN(OYJNyTe(9{o?LHBsjC2cq`85PlIXhUdDv%_U7qrsAyb z3#R4^D_)eN>Ya?o`on^v1wVlwm@k#2;TD11GxyAzKUvrriv39bK;y8YwFwJ!n~4$L z9D|4cRt(LKBFN3qMQ9*JMrzT(z0-Z|i0;Hq`Ryov@BWzDgzN`;fSq$yslad{Is(au9KLEXO$uC)Z ztKl_pQfp=l87h_z?VmpOg=5R(XlPGXd2qoyMqms8p79$oT~v_lKw9&njC z_E-~CK&&Lxu0Erz>)23|A@7bjG52}{MmJ|I;N}neq!$X3p1Eir?|R%lbhB{GZ?I3W zFm^_Xc-}aaE1Aw8Oss+y&bXbhtqKGmNL5(xAXk^5oH^q+T6gn1m4trHgS}GaMyxBP z;V|MxGC8n=A4KIvzk_;FpFWE9t>L=8-*Ua3q4OgoWY4kBI}9doJa-9gmTm?t4{9cJ5OXjJqGy0O%1AJ_?|Ioa=Dmo zC4KJR5ye}CPHTIUI-HAv@vi=a)j59+Z&YazmG}hJc33-y z_V&vtRcPKhbl$#z=7}nhN31dDR)2A41N`&3{uC7&2W;Mzl)a{zud?(QB3)m(Ln@vr z7&@t+9y9kxOo)nKIXgbj_|*S8>l5PIgT9=aaVZ@;osz{H`rJvpvvGPx+YWh@WaPRl z&%ubPrU!Pv)TcI1A!xjJQS{J1wf2j{`y_{Z=M{8xV#}Z4k&lffQrHUk43Uy_k8PLK z>Z_nU9TW@=8Px`KB&Gmggv!S#G$yL|7#pS?e&S8(h*v{c1OEKN*=lI)+==__`4j4KNZ@dl1a1`_BvMutB#`ObFFLmyM0RrZ)j^EDAAvx{ zuU`8gvZF;Wfh>I+gMc(`n}dK9@4$KViiIq%Cq+~^-1+5-M3|-0TG(gd+hG8GZ@Ib; zDVxt#Asn0Ul`$D;Hx+L)<;ju^w2hboA2H_u8H9 zB!>D)q_?FHoIZAMB2qU#MRnb?qSy30ism`}Vv1@t{*Q&KDtGz^M{9$km_&xM!WoIE zwOBKBT5bTIR$_X1#fG~>N%iP_+Jf1J9?bdV4Y$+Y7gEBimC6p{daKmFq%}?UbOz$V ztYFovSqPQWdL8#laWDMhuKK;pGF`yhfGra#7%xYedSpnpZhQ66BG=$wf&tPw^&UX( zOtCAoa{3*wCx_;ZU(dhH%gwg?htUm7NBD;n)Q<<8*M--nEHdWZ6!KbN)B5u=-O zANS_U92UrC-L(L|dEPyt*EuDtDpA>1RQ-*ha$1Ke(fj~YkASf#YG4mTZyLa zw||pKR2vi-tz^&R&)5&!8c2;<7UvfgP4&xF8r3* z!98Np$KS_FzlGV#L)IUKZ?90>3%Sj9U&+#TUPy`w?}VH5mk^J+u3;5J*3xtqa^x(A z-Ex8B>OS&RxTH5DAJ_cRa_gk%PA_k`y6%7kLjQ^e&_c8@ffe~O2ss_UOA$i0NF8`M8<(Wv0RE)HHg}& zcnp!ISqAIe$^`WsL((c)rYLT;VY{g~0ds>PMQMyj-ko}tl9BNX4OKd-yQ_1mgp)28=moN=3Pi? z?#t@42up|jwUR-!Ta1ZWW##gA4H0h@dcDDd)=XN0i_=Yxuu$6l6vThZ7_zb|6o6;M z5?nvCNdk~vth*Uhv}a*$q2Xn;x8e#qMUO_5S zlm~-z(`a{4Jt`e2Pvs!nBY`41IWBUK3|VZ}GGLLZa74};R$hN$y!s&3)o5<;aWX+z zRB};gn>)O*9~Ve+bJjo%&718w)nY`U)G<_3Oqy`$;ZE?gb)XZS119@tYhdI&iIDJ< z5|y)D*j}M}w2h`|Ukg3%>)BRbab*AZk@y_83<2vs#KK#l zb?S^NuGIp){N<0gBU0H+YhrGV?7(Yb>YGTa=B{$i?!_}zsUWZ7^}Gf$s{$1J24US&*w(L_dWvC%jvvFCktQ`aF5$M=;p@;#ks_!ozV1KUr_|fM z&1=Uy!sdJ>SQLEVKD~g~E%)@D6o3xuCB5<7l2Ymm{=^~J2ax*5@OzyTpAp?dnv$&J zk&;+=lO6;hulFJKPvQ68Y{}P~yGxO73B`BE{+yQ)Z>mJRS~`jRMv+<#LAYDxezu<~ zot?EQ&1RDiFp$W10)-JgLezNlRIlfL^N*#vK-*!=7O>c5#W@(%E|D!rOWSZTCpFet zN#tk+vhDj2aGc`XckP(L9?WnbXxz>t9gGYFAkff1?KIRHJG@k@UHkwHkxulkr)__< zJWfdjK5|XXbKNS@U;3$K zlEh5Crs{|QYVV;Osz(?yCy9ys0`hA2F%02KP*)wxUHTrCiBYwy#ZjH;QL%}>rlys| zyprrtj8XU)LKp^4Jt?0k*Pj!cO$CW{sPxMAwgW$ZTVd+_w{IZP#y+9QVpcu1S!Z$dfFpIkS2%Osz`yXGf0U2pw+H59tks>lm800i z&Rn9tEXPY&)b)400}1~>%Z&?(0+9%w(6seB%KPu1thU|U^M3!bXK04p6)=&msN~4v zV2_?EWhVs9=y2KGL1^0*bP|^D2{ZELcQ0zTR=0%QUqM)|4RgAs*aB&|XOXS`61C*3 zCJ5)P56lN_{1FJqt1PdAHSHM(S%0^MqP><5h=x_N{Ogvt8EWVVg}V&9rm8z>Y~+>U zLj9<^{2tR{I&JWR&WL8_aW1b#Dw!r>kCS0F@_jd@46s9Hgp0}=*idCjTK=(AOIceM zgCBCxv$JYaG_>OzF#R|T)}XtJEWQ~I*4+6M51c2FxFZNXP{7GtxjlDfGbGj}Y58po zoaxO;78vfgF75c#8CN@<7pZirtv=?a)46J6iBR`u`*K#ADg<8h5ZTA~iYFdv&EZUY zz3z{({<#s<&bDl0SW!M8Ak|UdW|JpSG6$SA)j`fvRA!F3ZJ?j{Mc<**B%sb*M~}G9 zfNOv)>K!AE8*Zhql~D0q@1s1vOP^XwkE{reF8wAw5n~YAk5Pkv#XsspRDhOnt-SgB zNLYnveRA{#!u(p?Zx7m=v`=0*PWBo;Z|{+qbj)XhZF%9(j_vay>&h)P*YLX4JtMn_ zrDYspyWc*F?M2=&y|HgIcX;hgzfSDDnU&Or3mR)d0^Y$*cTVr+&nHc`ozr6Buzuc% z&I3}ago(~!7Kh4IsQ~p^h;&r5%&>szqfg9aJ%~eoPLqEaX(sykwF;1b2K0LppDy=y zW`)>_8D{o9?KO4`#>QSqrm(qsoh$B8&hXHWvN;{fv9b0LIp=~rj8 zwht54cCCt7_IyhQMIo46K9kjM1_CLuDD(Q)iHXr?Z|v#|*;p{ubG^)gj=xjGq52=; ztXse=ETjvqG?XgF0T+E=;~7id?gj&7aNb5x2(Eu}>KjNx_8snjN*RAPYKl2%2nb#b z2nd0HCuROygZ?9BzI=!nWlImhKi~gT%v9^xYp&{`i$D^=6+uJtf7;0s#meJADP{>t z!iDM`R0~D0C0C|AvoDfLC)Ni|vE?4`!TsbKx3IB(hI%d%Tu&nbkm7Oh=1pJQd0yu2 zuD3J2zigVmL*RcSks+I@J{lD4-$mzre32kl8=T(Yo_-6rT)MV=%uVehb*!fz(v zMAnDxO)?+mI%7XVuEjTrGz(KxoBCl%9H?6rt+DJf)5pMIquM#+_0wm0I-cJbG;EGk z>X5zCOrhgw?`$ew+yJ^8ilSql#l{}sw6z>-aypra3tbNB$8papaTRyHavW(;MzJnqJDQ`G{@Nq2Paq^NC!Nq z2y>Yb$DW24DmGVT8kkt9%4wj_MX&0(>>_U?vL1%Jmud9ghltBF_TBmusPAQKz*||; zS+Y?zSQ;ixXz@tG9>RqU(k$+Vh%|Cmd! z;P0-f3e_p}ij@juJE2|^X0%Hm(tFxQ>PwV_hGBY;ID#o(p3a;ez6QaSJ zW;AFVP_jd$RMGOAeUN<|?Scz@wFCF4Ge~TBi;RSfMu3~FRX-r4p{G+HN`@V`$dQE; zN3uHDI(8gEb@mwg;_0S1py>9jK1wuz_{F+2{V{EpDX?nmpvU&7&>v2swSo*kw$9lQ z+O{&`Ei~<@y6l>u0A!f_q_h&8PtO-*V&4KwSy)@ zsn$SA@w9t<2Ev~7S46i zG`h$f6-^X6ag`OhD0?_9x;yQ5pO@iK{LShkHJPJITBC4Vz>^y3OSYlH;9Nto0YkRI z%5Zra;Y0R(<)!Ewi*h~F9mRNQ*rf66Q$1DZ0@0bHz-MY|bGG)g*tA?yf3SI??-|GC zz+lDO&;ql*_~LV3RXWv5`UIitVlmYPUOt9wa7KXPSzFU!P<7)V<_vC8u#@O+jjZ6s z#)80wPGWq!tkc@h_kVGH(iK)5IX`?mf{%3hZyAyQohtvuu1nKUcAou=9(c;{iPcVq z;HcTP5(c7il_35MuZDpqMP1xf28|O9^?jH5T<0%*GuHL5q|e#{E_*$R5@10c0}0k) zgG=xk*x%XeVe#@(45A6JpWLs58oQLPqi=vi;$2r%6k}|AZrf7%W2nwfs2=~8PnfXP zHSsq_zrq8UbajCqw?;ZSFe2Q#5AWJN;)~-!RS>wK3m(=e9U-4Ap+gjHb0si?a?ojO z>7t$l@wil+M-)eD=0q^W+IOP-Jm1Cswa1MVbv6Ae0^uU$e3dSMU0a&)kH*PSioNmB z;qVCJ<{?G@N=HD%VAStg+K+wHNeB_Uuo%(fbHy3KPs`i=deA||KU9L)@WW9r;g=^5 zh+A0@?0b4Vp?r^K7zy=17t0g>s`5rxs5C5_sE?ULMoF=VEonB>DFOD=qy@1pIvBa6J`+ z)6zp|Vwh9rLnO#@GY`$Ic8OBi_89bjymNBiZT^U11e|?I>xh@WRx;e*hbSBfnm_)>6WlHBCp(9 zXO5PpcBE_xmi7fGXvoPk-qai`Ndy-d&*&g%zePK?8k>cPHz*OuM=8k+WH=BFKnaIN z{2sW2HuO=@TvgSJM=%-nqskQPS2p*e$zF&_fewKj(4jJdzBMt#w)C4q=%ZGgpn zrO{=zk0hk+w8XDsqs(HbG%$@8(!LYR`(#wUB2a$JJY*D$KWe&#)WAC}NBPf%KiSyOQPKI9w(9 z?q$~b5%mBnaop*cX`*P7I7klrQr}g(jKc7FEk$DWy6L|F^2hYyARfNz^(STX32J2A1l<9aK^I{Ted4X(B+Z);EvvAOIJb6y z46Z2#IsI8$n_PJ>$TGZ?3j6WX{2%WquR|h4Qy(U?w6^b-=YV)WcieD6!p~luHlelk z(TV~KvBZ@CmzeWfdJh$K#;tY84}3*;BB!-+q&sXIN2C)l&|+#0DiF49vYVn&ac+lU z6cRSbtGrIaux_VN35(|BWzXj`d^E{KZ)$@zxo`PcDkh6Ay>8>$x!C`VBj>b+juHY0 zh$RIG2#J3eN4jnR7Z*!6NoOY~OLGrfXQzJ*?f*9```p0SM@za{taN6IFE=6#by*UV zJZy?td@V^i1p+gyF6`?T=PWhf)OU}_3)Ij_OX7z>0zTpg*G+YV__!BT*00PB(ezP} zCvju^MMYii7u9!entWGX51p6UVx*hD1w1P!%Ad98%iUG9{myGAyWt`F2W`u*IR7S( zNGq{gxgn$|W*QCcxzXyfw|*bdR;uyBXqEYfW~>&w=r-=DRAcQ1l|sa`bP~$&NcXoT zdgNmm4dBLBWN?aLetm8&PAXrg`2qb^<7 z)&QO{JFc$%Bj#;}F*~g3HfHklV+E3F|6*oG@18QPv%s|@T~`V$Ps>8|Y0e{Szt3d! zC0En~_v_dBMJ}K&_gcZW%m*37B_$%8XRXiCkmpsd-;vO1(IqlMh-a;2`#0gm!W9_T=LK)Vpvkej zZ%7MUVn$bp%19et+lh~=cz=XLmCu_9r!f!?!bT(=j54uFffEvkbo*i~SuU0rUg;x`iTEcepLT6Hh$fe7~_ z&{q}3i%WHJ3+sS@@C>k__^lHxLU?ALSKfOF_P4Lg_f3a2WuIKwQalhKBsR+%;~Jjb zLJ!_+mkOcxh!!mzW{B}M*0C=PYdIP#&ey#2j?pN^-@>+pXQ)O2gav6%+^}40gBJrs zTn6vd>a@|M)3w>|U~rE-9jmK*)hxK9S&yj&4HKaQZ?io=T1RRDuGwP6i_nA;ezBxc zN`|nx0 zqPhX;qzT}i-tw7&IVEz&6H1C;vrmBGT(X(KSjKEhzp|OL;KIqxHC)Q4yNGbV{z5ZD zi}Y@3x`?S#3Viq@6pUbYwRKz&#_QqHj}t3Xexp-+iuev6p~UPtot3glXG1kI_~Ybe zwa?B~3DFDE0VuIn;Q=Uu;|<;^wG^1hEL_~B&_n^uAydB?@a?ATaiK#ga$n%#vNMk2 zi?QKf;#A~*Ms_DJOp)pHGPTIj|nN58|} zoEaU$tw58N;6B0(OlRwevQ~MKa=Z>=#8cBI)Sg#+0DT7ZErykFC%PC3J0Sj+JrOtM z-jAx^oy*F&L=X*-q4tlrcrH=ENj}4+fN1svZ-BPmAV3^ zl6{b6J?oMaSFwXX*E-r~)<%ATOF!%OZBC?>-)xw{&_60|O>Eq8;BWKv3GXiX+4@Cg zcyT4mM#kZ@>uT9exM#HCF;H;3+1)gAPSTPNEnP!2DnQRlZ~lP3mVi6EioV9?+EoD1 zp1y%gatz@gnKqyK*TvF$Qf}%%K5ZgC;l?+P#Xe-&&NHu5Xn}e;&?M}I%Jr1d2r zxMg%<8&}QxPc^B8j^q7sUR_~B7)|@1IhyVM7;M`6nUQ?Fh<1kyQU|Bv+sLgikxO=iNp_7GXq(9` zhZl#s=vH?;@hkubvp37X|8lGdWZrc=EfkoYYnEyU*Htu^G7zDC6X{Qn*|9*7wqZsk zQ;|r(%r79OpS}U(e)E>pOebLiqK8H;hFmu?FtJ?Zmd5&G+Ub3qeW@EB2 zf#|z$=i47Rg+6<>;}_HtJ9IXYWwkbWQDw<%K@d{yuF}J*s-2&V4?pff@o_@NNwPf4 z49P3#Ga^UqaqNDTSsNBg3r0FjccAokKfFs_mF^)!D_|8A^w;GLkOKS*`U@z&35bs$ zdFsa&?DYG}S5dVlI(C%ASrzHTv6u8h7Q)>pCk-Lg2jEsAv`i`(CgTSEkeX;zm|#7# zDoN+G{#iU*)gR=tZWqBeCmjyeUs{RxtE2CvRG z96Z$%LOI<^4rbD&y{_nRXrjzjg2!6uLP){e4p`;N(Yg%|4{0`2l58}>%^(=0eHMUE zCF{kp#D6%8SlmY8>p*aB-FEc(jbfi!Wq!ljaTxKi4aHY=I0IX=I-F02+1tuL$pRZo z;j}bRo!tsR%4pV*N8XP})H5eaIal&xUmmf*OG(T;v${b@5m6EipIocUXkYog=T7_5 zx{Y-4q(}?*cuUSlT&S88^Ha&Hr9MH?(G z@L-5*uwKPA$B>v!Mx!REMKY3IF3>i9*=7yU;>y749)q>^C3Op1YMWBfE+rR2fbjlF zoImDc3yv+ru?zF~m_i>WeRP_hDT_>6%OF0-LVRpJ+^)QLjH{DtA^!*qBgT3mqUO3! zdKn11Pmo$*pY;`R+mLWSO|ibZld-pNax3T zQT}p{t?wh3{fpPrqxC4YFuH+Ln3exivM^*;;m038H`?|9$e@&4{}*fD7#vyHZX4Ui z#GbgLiEZ1q?Mx=NZQGjIwrzWojycKAhacxVRp*|nTeqrr_pZIGc6Gm4{k-da)_U|L zkprC0-D1DqQbGke={H6M8@pN_{Aa7=$Di*C zQ)af>v7|OToRQgW4V!Q$63Dm#)`kv^DLc}A`c04%yQ(^3$4+D(owu+zmr`Yr>bx_@ z5JQ=kXwEl{Qt||tHt3JTlu<+8<+lk@#p0fsX!vZ#!VJH)h2Eg=)}0rYB45t}&?#Qv z_OYCqx9E=zx%$&Sr{GEZ9kd^c++)*+Z&>w*ZkKSAd<-vOM8lco{*SanjC||QyF)ddKFcQMX#sOQ3XOlq)f%!sGeqG%Fv_L*n)~z)c@MxDb z75TbHcR!wuNJydYJ8FkcO1}Ey9Edf{%dFAT^%Szclrg&C$}bP1cD90^ve-;;<0r0j zTq12hn)lC=j1{6JT8CHN^IBIGihlDRTpAuaqkgt2Q>@H3^`ek*%pablqTy;=7Frw` znXh3t;KXiL;(c%n8S04F+!#I_-`r4#U8FBbT0O?%>*B*#OE`8KXR7BmFsxLCz}>!^ zykul@*3Qvi51NWMjRh5pcsdsfn&Dx~`z957yS-ysIqzIvHbxgNp3S;a*zlQA^8L<4 z7U=pJ9nBngz6vg`?}4ia3R>H5tpJ78eF%zD>P_g_r_LK#o9vT)=yJmHL-!4#ThG@% z?hn4{-_Qj6gg==_PgpNqs=mL-ADSh*b#Dn0u9JLH4~e9^wQuFgcgQ$(Q4qV;AA96) zXDD_UkGkW2bSJ(0Rq<0FA>lr}05N?KVRmp_e-&Qa?{%y`J;hC=BPU;29{C3SQkv*F ztqk~qc76O431}&NPgSrLJuV1jQEZ_B`3%vIGX2E#Ri=ioyj2Kx(m(7ea8r}>+$`V` zE~jG>{T@qZ**Cu(kQ~=QTJi^Abs=fqJSW^tL*c!Ph7Z3bH=7T!Uk8?62{A8=IA{pz z1a+2W32ssiF|P|-l!+N84?9>6H9rL>LX}O4Pkcd+f~brs(5~(OoGhS|RsuG^1y>a8 z0>&=z+zCM8cvJv!)IzkWN0X43xrQ(SN;zoxH^on*;S*mn;YfryiLzcq&?$qR73-l+ z!5#9}->cb0PqeeCQ~R5gw+x#? zIw79vSc97sZf4j}#Ie%G;U@_=!Gtj-X^-aK*mFl{dRDlP?yBx~6L>Z7-`(Q?TC*d9 znCN4e@Sm|sIncWxz51);pj!k{={Q1Ym^&i!>Dfu)6Kwd7l_U)a>%c`PsZb!L4y0PH z&IrbFF)E^Ix7w4Q;-#_aggrKN#0csQp)}#(iA_sHSjv|i4ir7<)I5&P;51*KuA}(Kw_(hHQEm-2YJ9 z{~LL>FuQ=8Br&EGF{B#t4z)jmIyg-o*h`E{cMIrkJ%m#dnnXV4Xsi@5*`fekwSX_X z%c6jrG_g3X|9w5!i!AIR4qF@_7BTq}A_2PqU%Wt!Di}=zh+rw&sG}9Js2Z^)#Goy> zNi2jDPmBr(O|uBZ?fZ9Ps$FVP5o&f)Ax9?>YDH0qN%EkszF^I`@HK@XPIgp(#v}sN zJr*+3C^fN$Zne!9sZHa>`mS16&`21)`YEuh_uKefO0nBJPyFhoG9D0Xa3h zDFNEJF)8B2MQxT@xS|w4nMP120Xx~~d5wwcVJ>A@lZM+AWxKW`gorJt@oGDBc9JY` z-W!$Cfwn`pN;dZGZ%OARKY{G7A;mZN)1EycjhXf%SZ(n|oW;Gi64C@WZQDf~< zdXNuV=I{<>zZXP9K{d>g9nyZ+_M(Dk1wX*~1%Rk&a3ijPWXV1bg2?~=W7Yb*vYDX+ z?R|k@O_g^HNcUCz!xLm4x<~TUvR|AYy7Yj=K_eH(QL}&0*@)m|*V3b%`Q{r>pi~gj z%-~Ksv?Lu_hg+Q8UjuROD4a>g)ISca&Y_1}|@`j6TH?EP9$<@J#!9U60jxos6C0sBEy_-QG*YTf$q!?pD0;BToI$PI^g8W z2zZic)d#3S#U}jL^BI?F{O6okdNt5+PB`lc39p zFF`o70b|hPuTC^4#jlu6n2fWQy2v8~P!V#_22FiE0nAPZr_{6i`XZ%&jZXbj1+ets zegXkFeyIZronSFTw1#wgkmx|Gw1^b}UOjm8UDv#WhuHuQ0sL*4lfB$sv`*NXzRW$d zPROf4?LE*=#GKxvIyC!GY#@UN_;tt=&`~4ysUOM*qBL+?`+2`*BIoS?Fi-Ra_OZj(R&q@rZbg&a+ z@Z@gFk#z|Ms^DWTyi5oGy}5I41hflBlGn3QiBc(RQXt(eNQt0Wk)WQOxcU2P|ARn6gjF@c;fE@d@DY1Mp@gjMGlCS!?Y`Mrl~NYy!J?Kuv+ z^sUX9Gx6!z+zR%7|d_I?>YUPE;hT}H%2`k z^*xs*Dx?I&p6OLYIN0>5vU=BeX@HduxRRP869>daC(m^$6l6ig{VzYa6Tj(I1W&B} z?F&WVJQk09b32sNjVSe(miC)|$lfzt)S!Ako_?S*(6wxUV^_up{rwq>Zn$Mn#|N5W z`1e$f}hGIfzGrq_LK5cGTkwM*j+(4@-y-CO!%KIE) zx!$JnbmBgz)2T${XTqS3a=#%X^GMRE8KYwbjbOJ&P4pm-a=)b)OY)#)Ns!sj$XSU< z1#b+C3~cIOYV!;<%SW^x7K-^lj_=z^qjlE<=2G_!*T&s6d-d0aeMzGYxweHg@wSZl znP{AkXtE_DHC=;X%A_-TM)@@H_KbTR6mXXm(*O#%KNMK$Xg@D0GGxO^y~DAT1B@Jd z#Yior?pt*|MKE)K@uN}C2;mr@+9r%2aCvKoyp+7;bf#M#R zpRgT3{X@`S0XsnR%b3sM?q~RvgIbr`zlc=I`xWqmW+XsBe837EG#_dE-a-L)4Z7SW zHS4=n(f(6E#k^?7D3+aL(kY2pL{34B)p0n&9Hm#dbFld4cfgQtL5l``!{7vYoA65nri#Y6%+jV4CCt`Ehc^q1G<}qyOT>D_)X|MSnCUCeAoE?D^~z$kzbxqYY|8v@L)@9e+EV3B z{(?~~0F2(su|JHB@OgSOoQlu2)L9dn;U}HcS@uZ;dNYuU&w+|p#}7Ird5ho4QI(CcJdNY`ct@Cm64_-A9{YxQH6BlQw!PZeu87t1V7&R=13tc%E zg${v=xqA7iL{NY@!Bp zM?2-LIICk^v5&v#&G0I=u25rp@IHy|F^aX#UbOMUA>$nJ>CFTxdW=$Id-5WS@1cUr z>(`#lQS+E3y?OG+itoV|Zth%o0^sCvZ;SP278ErM4G4E1c+i8*qn*-M?sPEJ@BrXl ziWVo|h8w@bDHd|>)%eigm+t$l7Xn7}JoI4(^0I1_)Y7f6Lj_3#(R$^x6Nf$ynqo6o^=KRD65?>=qM_=i*A zQWjjwec8;P6+L|AHe2ne3IQB{`1@KjfL!$`_L#n%!sI+DyV>Hl z67(rwFcb7CJdww0li$6@?2~wuZ!^hzL~l39dvtHP$$O-4y~)283U3s@6mHSRh*I7a z$B0tjCC748-f_or6Mfe;G{KB9bNH#*-q_*01W5&HgFYPTfg5x18 z>Ax$$(!*RZs7^z|A3|7VFzYWZKtc-B1Xh=Y<__9m7$LO}mY$jZpx*_lz8MSb#uCBEXRM7I z$CwZj3%@2{GKuUiL)*t~ejP;7dElGfhJJsZ62!x0&uhxc_%7v z)a+5Y+qy*F%Ossqqq{L5GVE#dJKicjY#tk5q^uDpPv^F?AJg-%*oJ0NPQX#7QYY<)}~OWXqUO z=w!OdG^sN?ZmkLLR#5yte<-eu0&0m?NGp_D_t}*|kqdMlvSRt){RsxPXd4Ufn{IN`t-fxOa zGSXsB8OKCbPJg<0sSJ9KwnsFwth(Nz)XIfAo1~K7O8}N$9U=PaAic&SHUzO8oqe$2 zHnI$*&$cXEi+q&WeNRB(Po$OC;C)>v4u(1xcXaQjmb(ZCQ;9C$ZY;GS-JP=hN+^OV zEE4-^y#y0Us9;*iXGXoHp(%(V*>YZ#+pFkO%lq{q5BAKEqal}wtJZ;{_T#f04L5Sd_j66iWLyy5DU4$_GAu^1FKSid3wDH$ zaog*YY6dOgc`pjo5=OdN7-BLmBMkIW10Y3f#?9~!-$C@5@Pg05t&KAB*~P&^@YKkX ztRtM@F~pZ!i{6yjtPqyP3$0oiBM4Zglaiwp2iLL|!PtrrjGAdC8C0@73)vd^u$FE> zk*(*3;)mnxD%5JLA|`&o>n2y0>BC`~qYBq5otyEZDT1>SajCH25m|YsBxej@r9vE< z4sEf^YxJoGNFB)g)YD8eDnXuxul9BEG-KEwW=FXAT2S19FCzE9~&rR zZ=-e24wu;ahERSMZKsSVJ0i(B_pQdIlajt*?c1+TOB(ByBMzkkp;kQzvYnIUkuR1iM-db4zLbiZ2P7OXQno(=o?hLLPqLa)1~#wztuI z1|tLR0>$KXi=+i~(OCrdDcNH|WcrvQGj^G-6dlG6^~B}=eXy8DF^L({c*Wu%nK)R} zIy5%^Pmflmz=rc+BuXgEfW)L-n_%sR)W=5&qb>J&s#{JIon#iL{Y&@WrBI}b;)+z&;?wO zo24lZc{(QY6ihG+rd_rz zav6Z;43u;p%dN3F^OLo%L}Xiwky;+I+9}~@4d>x_ekeG zJ@ELpddGBV%vgv071uuk_@G0dpe~JT>(m|B(7P5$QM{+1TL#34HU%AP2TS_0T{_b3 zu1gkqliFjIw5fkbD{avHM)x$pzI^P{`?5k_1W)pcQ$kigN0s7*ihbLK^_YjAiMwt* z?8sG`Q9c*_{xe)kpCnd&?7&s3OR&6!`hmT8yLiz%iA$h7FzFSs*jKvziRJ;cn6GG2 zJn1zpiJ#<%U+G*v=`~6zSNXg)=@q~DLy+#1JcW_^fui_B_WLJEaxL|>^`vpsD}Q8E zqzpSQ2QKp6s|G_l4}cFqR&Ici?gM}{fwSDlsGs9w4^bL28CHt@h0Fk~Tlsm3_(&Oe zP<=yNIHof!U)WHlC#LP9DLVApj);l*+w@OU?rz-j^0L>eHs2$=cW7S~QmPc0KNd0@`Ya@sZ3=!;=t*uW;&k(wBx19DN1tFywOXF5^^k!m4v%Iu6P^`R;|E^SP8c6k0= z%vJO1M-B5{y(1hI)0m8RqZ6bvFM9-J^96v7{v#bH^8qNWUhH%vMStwDRS#bOFk1^d z{qUCHyJ7mdK^g3A?er?6$4Fkj6Hf2|q^`#xDa`_+>#(GUWA{EWA=r~TmmK6m=vy~Z z;vUZrA{-xV9VY)2`Mghum8P23rGkg~?*Xp97Dwf2{n7Y;iap%nObp@j@~p61DnUU&#Qj4|06U;}A7Xz3;^h%_wBn!z(q*|5Z8lw(kj`H1RC-V}I zj)QIWJ$~%t_r>|P^<_iV(Zitx=O;nJ{bwvye%S4da}pfQ-{4}ru)J(81OYznm;M2$ zvsx@O$!r|n!-Uj>XXsfM4ATs5J8+HCIxG>5PXco=tKfy=y*w+F)afUZQ}l%XZ+EMn zHSmpVCACl5{m+c%FvGT@HC`HU69zJ!1a}4)>&Ef649y2WsDscAc(M>wS0h;r_?GQ@ zU*Ts9QPp;TW8W?Jeld>Ib?e<2yy|)DY!37ubuH(6T&;u+icdeDaZ5JK7Lho5XX^j5 z`w&aIGk^N+occ^@L@y+mHQUpgt}XN>V+Gj!vMM&2(QYu ztB1SG%(I&;)caGZ*OIi?diFsJqfHLXqX!%aifaIg>=B3p6r?dIh5=H#bm5BH#e?u2 zg7|1a{m6#iq=xVjfzzM>>qOV(C>+&A>lG*Pd*1&JRdoz{jS9BUT?by*pp`P(d0{cTF_~h`@&YdYnPJ z8Nst=KmoBRKyaE}4iP_3m{agq1RALKE^weQt^qHy1~J6D1l%ey*tbBxA%PwKA-`V^ zAii|kW%!=GXe7H-^TA&JFb-&7gu#B|(jfe0+3+nC-j0YIl zbRx*d7U(nbn&mOV73+W;7TAZfSB51j=rWlBI2gMW$mh|IDIXGWok8%N?-1`waI4?J zc)&rmQ5@nSfKbr8J*E?rM!sPiL4Kd{3@o;!y+{x`A$}7SexI&%Ec#|Q+4$#K;+9?|4f$HaDd4~x!^asga zEYzkGNhxGN=UmaK>rg zjT5BNFL9x)b#a6$21}pU>`XY7Ro`Y zq^k8*g_<`?SMpPDrwp9eNLPweZ|4h~Zw*pn^HYtyLE|WqV7fBTU!rE_BbhTg0+m^X zI%hxqe%}1++)B&#p$n`yAZ~RpExs={4VYeTQFn?)_N*mHnRUYAT z#`T7j*Q^tiHH!~a*mYme=NRFDSWq7L;GJZ!3PU|!v$EDR0j~E>GT*iGzGdvkao2|%uxK$|%TA7dQZEBLW z2V)vPEc!mkAQ`(82(`3MG+sf9Hw^wN$LYIF+pX3)aaZj?*iEh>p4dSrYYomDG5O>V zsWo_hg8wH=v$pCC^6@1&AVv9~^;!QjOCu{}YH0T_swO(cS|48&Ba|u`O*+{Lvkk+d zkKMwy&ZD*^4kdG(BF-;DEBjKezxPTmZA~_uXbRgGgg>b#XN{m?EC*s2GV?G0$z;}q z&STH#=SwO|gWS4h!Tg|nd`H9!BX8!lQfl$2i`iRJv&C}09+~zH#S`AlN{o_;$wj}B zY%V-W{Dfp0{@(xLLTw_ouqshRIH&wS0sTiEG z;(`M4P=Oh?XYq)UKoeI-AKp@YZOA@yeLHayxoG6F6UbwBCQz|yO6q6SnXF0cpWZ%f zL#;e7>N%+DzZ4+GzY!r{-B?kCrMy=+LUa3L@`LhGINg}{0}zC-eF%O8pZaMlg|6zW zscQ{@ExeqKT>ZW>TX9~>Algi^VaTPq}Coc1t&=bNr&Hr;#0Qi=4)|!MS5@w-9P!zDNv6 z2GTHvHVdl#Jd&(&@@Ks5cWvuAIU>kUV;;U0k~glDdEq6{R#4wR6JsrdFK%S5p3f+B zUDDUztDr6#l0uZ1D8bG}lZ#xdTjvpF+-Qc|=3vSU9do_&KA>e8gS4shbj4iiqW9c9 zS)_sAQ!&UF>k{3!xaNwQ4%Q=SICWBlHKc3si#`gi1PLHgmT1py3NSc0^{3KBR>?(z-RGNw{?>{PP`X^Q=#QlbrA0xQ{-2~u76=*M>rbF)T~ zn!vM55Ot*VDa6}FAc?xe=64Nz_LVR$=&CD=My$X|hE~2|wF2Q6yvnmWzN+b>pdl#q zD`=VK!lO<3l{a4w2Yn{!b9G+-hSl%uPZ~>a-7wbbqi(JK&B3CD-Df{{ayKJ~S6agD zNH+y*3kl$jRs_`zT=9M!&uhjwT+d%yH{g~%5+_obna#|P1a(nmQZ=0;ZkxpZHI@mhYW%Zg>>Rq$8di(D%H5fHfI6`oa%vn|<$%_!)X{w~A zRqJMo+H`O+W#+K=9_cMob(OtA({=89ljt0}a{-54L27Se)W0ocqkp$$nYX2Fmkrs= z2wb3%We`y2OMZoido=4@SX>e>BW4la=FuLoN3GLg4?yCuprZ|CIJVu-7{Z1tbH6L!k(+034cOb85 zYy${p$~uE;;gbBDozjd1W5IFCSywC`G;q z`590FoQ!JmAAVaL1mZ^QISY3S97+p!3msYu=aAh-lkAY*W`B85-v*L!im)S&kts2y z+vUqdhP;Q3!V61~ij6ZK zt^_$nCGEuBaw~lh*P@N*TGaH!3B@Z3M~Geq^-J*PvyMs%?TsE|(3nd&dSPH=Ak%yjG~KnXHG_yKhg zhw>p5jDlFSOG+&$u?rDo;txRrxwXbg5%UfIh3Z-~Sfmdes1U{rO>JS}W+%3jbV`7d0W(7eiWRk12{8NYmdVl!scl&<>Hr) zcyb1IxNk2`!8I|Sl(mydtz~FZ{Y>B$m5QDb)`T_5vh1(B#uSyI*y>$?38h(|$gnZR z@d)V;&#Q>?T$A)unjV~7w9C*U32;};bG{Cl*b*lOf*)n*Zl5pyvx`k(I4JHPDv+Fp zpYjV5iSQrhPf@ihdt^6NRkmqmHyis~v>HY|2yZL3z{-LVL){~hI<(3)Pspw$i9qXW zgq7LDb2<<=`k(q$sf)wd|JlY`X>ZRTFd!hmFhM{B{)aZU{imswt*M<0qu`gk#Le_y zE?57!AZ%~%WMcUxW3qSpSMwLEzj$vhV)8Z+#PX;a0Zhm$!Q{^ASz^$^1|=g7C|s@N zqil_`Sc`6>Y-rQtOA>}3n-uZ{U=e49q_t1GOI*m{2buF{+u?0LlRjYo=IhTSnmw%| zG3{{3dtGn2U-O=9KW#64?KW&fgRI}w61&JiF=6()pe!+oIFp1y4{eB&p94V>K+^zK z#OHBvyV8QxOy`CJsEKw2^J(QHbjKzpgLe}~SF{D5q<&PUKB@?O6oWY_H&LfPvMxEv zH(94VM7=A4tB}IO@cW*Utc(%I_=4v>-+HA5FNY=odhs{1xH}0q6;UfDKH9_XCY=li z9S_fh-HZo_do!5;U*hGzOkqTOBcSi(ez{OU7TEkNaN$2Eq2BWMu~A5|xv_4Dk4_G| z0qljMXc?TCxQ@01S?5W0%^Ls$b(XCKEz)Y~GFc5}<#u|*H-Skhv4ncdh>Q627#J$j zK=5t46;&##Z?N3F$(5xN*r6GyNAO*Ns|uV=9v75~Bc&Ca2EU#3&13{hatcH#{% z83;>eoZbiCN|0-Pms5J$PS=I)`0~CQLP23R_>gY(mU0i>m-F|szXxU;RW)T>{q;$$ zE44gxaSoQL$=G1r+rAAiJ9^Z#{8D+hRkXRm-o|T?W?l*I#PSIr*0&1@zWc2SJFQfB}16uL0UOHFGL_a{8Ov52)BcoiNc zc!hbO-2z8wlIEER&xvIE2Y-0grb>5dY$+AhkgaFMgv#Auxf)$cbDKz&!zl|LyxbOLEzG)mGqK{x6ijQT%`%yrr`7f zz6~08DvzDqGJh|m(oY1b_Rm5U`sd^^#d2tAAuEV!^DrD*=)9eho!!{|dT5@xu{_~f z0y`YCu%&{R_P|*7Fk|c>Pk<#wYiq4l8^@cpt;N@ zo6opf^cLlo6u0MXH6Q30xsBy2>UOD`zJBWK=Y9uKqSq#zsYa#M~!@iR1zy1D-KQkUI83tN8h!> z=GLkwQg=78Ldf*~a=D!(6ckIuJ5VuIt{DXayn^YTh-+d(?yKmv0Xi~;j2mqY2}fpc zT{FnFZj~i7XkO|84Xhr?%25opXBV-LNYWOc99H^G!w1wt8pq=p8S*Z^Yz0L3lPphAy{%VfYU!Q3kOT_XOWH+!~UH1SekX z>}8Je;Z>v_>)oT|!{v)j34hbKpm<>4vdPcDHeV=AHK(&{Da5Mz$Vt53o{mWJ@z4B1 z6lcHT7pP7sec=CwPCKo%zTlpqG|E z_N_-pedweZ?8>OK8d4|c9uQi8PcZm7mNKbEy1L3CiuQYhzW^ zX=(Nr#TO zs3Q2E`DSxXbtG9oUtm^@z9E*!IREj7_=Z!*cfOQ71qNa1k;f-7#=6x`nw_5!6zjy;XNj&eLJ!T@Oju z8c8=3nGXN5zITng`*_}?e#(5Xz(*lXS6n5j2tdc&C>!E8^~o@V%QHw^_DjZY`(x|1v&Y37eV z&(SBC_;!!2N9yn$%Rj59`nQ zNl@GV=AT9@F|=v0cIO~GbN&qGyJtL=Cb}=Snz5A6eG9#xncZId5@Td%5za`OnVDZb zvAAD#vHa?J|0@q7>XRr2b+Vu_6l|z7NI_uT@F_A9k=03;`M?^p7x69G)R`^Vdj9y8 z$!@pA<~y2`^oT8iDgi!1Aa*eQJ6ni}oo}ijE%#fNVbgb;?lrqVj_xDt*7GtY=Zn?H zHAiqS1hQ5i{y-eH3fEH8=5y$jt=;3o1WkQk4OZ@PLO}@t>(nYhK#MG5E^>h#LjA^EB&6(jfF^x|14O- z_Z*0P6nwYyQjT3TN|JJR?cQmwsRUCgSC_LZ$OTJ%KP_d|0&8a)DpcM zo>i^e?zAT34KITKqsXg7>|?&=N{@ErwDkh}_j<~mRlGdrZUCRU6w@^WO_7bs#QVxZ zJ=tVCi(&_f&OVVJsrHc9X$^_bOSlnt*s(z5c`@d(NHfSGnZ zQzrO}Tg+EHTl@XtJ}XX@?)|LwIu&Ct7kL-~{(h#Cdcbk~=rfX~_5 zH_ik?a|azj zfbK)-`e!z&29LjEVfOwpxWLrHFPvwbkHRA7a}kP>>I;@wC{Gz<5L{<@Mj?uqzK?*q zkNt%FPke}Z#~so5TH7{!xs~w#KjFiFAr4&?`~KlE>=S8$i6JOT+y_t9+A4xX$U|c# z1Qub`>7g~z$k429(<1WDitOu0Wa>k&DpbVlGT*{-$JMC6LzD|L8x#Th29<!F)*6uSx5-8Ngj1Hl-?&Ie*ebrGD zJ>Z-_)QiZ2KGxGYSo#M_ibbQGgA1VoHquCmt&fwhhN8@z^Dq(Nvo&S6UI30v2XZxwm5i?RFN4 zSKtm8@!u>NtYkyR$-cU*^6U8izjxVx;U%KurvA}C!864Izp(`02YwGz!-t+K85j5s z7tM*(!@Dm4{1e=)@{YQ6zDl@(`cNNa7cl6wwV6+kxl?hR{F9b|=0>8kSzm3aw=EPc zyMIlMU4if-U2HGUF;z0}j&e4=0s99nar%hc%Iq&(mLtkFJ`KCvmoHE4zK~D4*dLSX7~9)2+8SFJ+L@a&x&auCSsa)c{|hrA;%R4SYia!7 z6CnTnNBYl+LeBgzj-pycTOM5y<0B+RF9ox%pnx>M&knxfXdiPQ93x7yoScnquJnw_ zGWBwL`A_qB;EY&d_eBqrA}ilB_`BjT3;cI%`|vH3nd!-wX^yYrx8^-QfA4Vx2qP_v z9Jl@anZXazW{-v7un{#zOX66V!pq4SD44T@rs7~Os+k5;|00gfs=Fl7{qC$lxVo*7rcEzkY}MZLFFfgpbkzL@jx)I-HD<7OG*wcR zyo7Yf!Y6$6$PU&+66j#fSzv_I7?IgI_2)ZD#^WpBwNz$VA;74C01)+#I373uPH`oQ zDQ1zn>BfohO_l6d)zsGC8tx@o8ke&A#M_F(ua5DMkfpzWl=J}z9bUzLV)`9Wukk`&UB zeDCJJ&(xMop10}?U;L8)CZF>{(2a>>UNs~6`=0LnVv55P;$<%jyZg0ra0dvA6>lyA>?zaVN)^lIswBzDKT zLMvu>%d2q(-o7oChOh=<=vVqfY&mKe3d#Yk-5T1_Ds>Mw|KL75ZBxu9TBbAUEN5M8 zA8}Gf30bd@>IvzROzFutAyrf|ebLM#HyC%0g~Ej&!W*v2n!-P% z5um0*9g&#vVnwnF2gAw^T`&UwTT*Y}1V7uaF9Petl|p_<&;VK}C1&0o_ph}Jjebvit+H{dU$&BH})nu)l;%vGiVf=W_=*HY#or0&mtw;p-BkVTm z5*s2y%AXj!ucu;jLrJ}TpJ!;NpT1jQZ4qsge|j1XLilB|KgmO(Q$ZG5;hFghU(#GEKSz!tOvVM^Pd!!`qD|Cnl<5&sD4bPg_95XoH-BFdfdDRN}g1|}4vx|xQ3 zy9&fIg#k}V*dZ`J4ShoTPaxx|ZKysa1_9ZS00H@W{eJ+me|NGrtdGjl690*r+4jU? zJtS$A4Y&x5rX~gjH4c~r1R6PvSQS%xXI%W4Oj>%KhV5^wrS*3Eyk;xa^W_GpIJmFR znB``*YU!=&-)hy(%SUgyPuntP39$Kp523HGPI9~-ov(qM@6s>tQU_CjX3_Q*xb2NYk&WUu;R7TZcdN?bsu}Q-qf9S|@MCo0WHb(L}Q^f|{>!sWAsT7VmY_v7@JjdKLSB^*-qNQ$}L%&~H5f zsk!^5M=CR?J_0A^#jjaW?{X(6Y#&`wpMod+=kEaseu3G>ZHC-h zi1QV_4>44Y5**p$I*}s~&Lc35qvd3A<&4y6<@OS%E*F2`tLV{^N=_<+5|oz;k?sRz zK}D|mgE}~C@^!H^{bRX*2HqiLFIX*C6k}XA)WkW7#`uQo5jsk!cX=)zTwC0X0-K8R zK&ML~D`oj!J08iAgzSsyFtu*<@)C|NCLATV$sL&so0{@Lr%NeCcZG!dL05%F@?p7> z>aprkr*1o~$quYVMfhzx`Oiei`}lwp#f*%C%0gGyD0NxY)K6R7m442i)g)ll%8R$TMjph8;p4CWHU zyTG~Sh-Cw5;)eMu4VH2+a7_4P?ZSn$PG@VgDZOq7#jSp?65qQSm?~J6CMu!52rm|Y z!!5jKDCd(!`UjITyN%lnFqu4MX!ZoNHly-l!gKdWqvR88$ThpDl1}t|6Pj^0_JBYes zxFC&#n(RdB-ffWC>N*&5(b?J#+kocTPu z4<>zMHk9>Iqb9U~K%wMggGY0XHunpiO)wUYS1{sI7M{xwS990oYK4i`2P3J7VNdVh zRT!+Y4K*3Yg0~}0pEDrtBu9al+&FWg&=N8@sj7M|`r`z%2}+BD0zV&@)5T!X3>z%+ zpp1BFJ}5&XN{#Y=IJ>K$$f7K5*pRrpySuwf;_eQGyB6;5?uEO%JB7QuLm`Db6jI1X z_sqrg#NRy;|3yaZh>W~hCv%<1z2EaJ#GFWu;OLR3`U#ANW*H>z!t@G5P9qliP*J(y z1=CJS5-%c*TW3i-?7^oOFgu%E}H*pxyfnf(xxkyoTgTDDEa& zsfpq%WT1??t=WXZZ>CAoF;9^>N{H@qs=eivuVF@~0Ys^g)toxJgtpp-lsbj-ry&<6 zwX#EieldMKOql1w+i+_(b=?zU3w`W}KxSh11vd$^SCnw;_=e`t)0<|rp{d`@?J7oj zBG_xzY;%j0x}fe1=9HLq4#~AjHoC%U(Ka_oe>*o03bO_5b`jQFTaeJUZ z(zKYojoll9CK1Cj8W!Y=JrHm)Ts7Bj*M~UDYCH)N6v2%_K!$Wh4*NvPSJZRA8}A1n z`@_lTo_M$zg-W%S_JV0k3t>h$s?9g%BBlk}SjS@fi#W@JD3DUw4t(zdYh^^30>~)D zM}F*(Ai}Sm%mnhfF8GRTboy5fp(vD*g16rl(vK>}6Z030WuDOPaSFlNPj*g<#e-jw z^3=AA%h#2_7J}_ZquB%|u~PN(iYLE@c5+xq6K|!S(HM5z&P_-W&l7^>O7H_yBryp> zaMJR|_3><3f~(AjsYHbvQN69`=OA4WQ3p;CBcw@*>|#;h@N+QGm-zLRm$BRAegtIT zK-Zq3hMwj;Yh4YrB4?^O?N_sWJC0;`oyGMCCuTb%rkBc>6gsC#Wm4%5>&@rMd?eauGAhz zQc|#rfzoL9pN$6n7Ghxn`)Ah8g`K^^q#YZm+dJ@96ZTp$tprV@ah--@-rCtNZPoqfk_?A0ilsbf&EscX=(B`z#1OomtftBV45x%b(u0^6dM~SU&G1x`x zZsr$DONMHRW~<9Covmc{1FC-8w|aN~v3C|lJ-{FUFdhX(_Cr3gEPc0!iuW#pi!tjKl}|uQVyJtV^rJ&qE)>n= z9aO4PTg(5sC@Gix2~}lVuEDb_bYcP&S6foDvu^2^x5a&c@wJ{4I=aX4jnb=Ll$k~t z(oN{MfwhRIOSufwDO$m`&e5r>U_*G+hmhvh^^LFa*UZFuD|qcKm{C5)J%c*q2jlSy9E|8e34SzKV0^ z)dDIp3@|vg;DubkW7CuoC1T5xc`t|%!nI*FX=E{FGj~IL1)HXRzqFGN4AHhPk3E9~ zZkO8!o!+_6&`Js?4d3CMm7VdHnmE;~Ru(3 zaMbS*MN-1ZPWpzf>aKmj*EXf=O(=1}rKLJ=>Y6{NXMPwGvoij2 zKn%RgZxrg}+(&X_^&El!+{aubiv97?^1J;9%>ML=ay?rknumxsj3^{7nA0Lt>9;## z|7M)-)T#{D3$u}l(4w|Jt7ef4r^3=&xa9Y3tV-SGS+)lcrzv&@f!=AQwkkgGJIde> z(K@^{tTR3NZL9LGrESO_k-9++5@Y5ifinZO8g_}${jk>(UPaZPtV`zenS@_MqroRA zbq|}C_s~2TRi$T1)VZk0&j%o%4rG9Ksuulu?%(Su@i{di2OLu`0Tk0tk1g#)Y+&+f z(i}@}EQ)+;;iYc4*6AAzn2&m5`JIX6@ZRjv}(o2x^DX;zI9Uy+jnR zlk>;wfW|u&x|;Q!QZ&Y}aEl4NUQ#aWwBEUO+wKl7tH~a5{_qZ-B<_iPXg@vAyz<1A zwpa!~gG^(4A7IK1>5R2&t!kh;i+vX0rJ*{DbLM{LDgVBcziMdb!2!Jb$p5e`$GR!t zDp9Nu!Z{OvL|tqLPKEs_H79b+jx6Ti=iS)EPoMWJbs}EkmhZ7G7pl_SYxABq{}K0> z=qXC~f_141Rr_5RnuASuDGAdHKd2VxjKejp)Uf@ta3{bG$~(c-aX9Vqp?2#>B=bs) z)b?fvs`DjQ;8`>NB04A50rEN}x(NBp zVSt5!ChRYGtD7v!6+|k(9TX}WFe)QFrE3U7!N82kQDmyW;p>|X2*jHHWC;IM%tFF+ zQ`NA@U^7^=^GWob&aBYK(01{YC&ssyc^RMxbnMD#6%E$masQJfrwN5D!jfA0wf$}% zDZU!zJSH{F=bfSO?1t*=!Tl}2g61!p_Ob7%2+;y~gyi=&Db;in(;Yn5Ny#$TjGco} z8SBp62uh+ENDQ+c51#I03j-xTJ7UZR4J^}5tYd6UHr*ndsoWD5cHn!bPIW`YF8qgOb~})Agi>rl35hvoASoindKVF zZ>s}E2s7Z!Ao`Rrt&}00D&T2(6zpT@a%r53N$R zRvPDI=@vKp&eqlzOaO|;PgHTraT^zE#+3;_aH9F?v9f6la_2eoOview^-H}xMho2( z@p(kQja-RjTXYINotE;}(m&v(>z@Q+>jDMs8L#WI=1iHf&o2qhq<`0Y?o7?MbNYPX znQ;B*(wAzn+D-v!mAUZA)bYoEX8q36G*=n4v|7roowf@Pk-jBywyCSIZW6jQj8veA zC`&qKL5Cb-!2rEP5l4uir1ht{9qfZyXOo-54VWp?BA5`yi`+Dh-75+77+KLS8zSDt zmfM_Hk}RR|Ix)HEvvc0H@8{%Ieyh4axpIgGL;=~-5VPoOqrx_^sP1ekJ!0Qp;e4Xi z`|&!WtVc90^sf4wCgnTV!n(yCOwWJw5Ig;-D%UAR6rXp-Pr`FZukxTuDIdp;JS-iG zIej)D)b;*DLL-u$DGqGvsJA7wm3rNnfg&K;Y!61`g>jW0c?VBHEgnJ9E&N50Zd~WlX0)Zh)jHE_ zUz-nP*nh9dLWG&iZr1|eQxhqK(^YN8&*nHts~67JI_B_z{Av5~XXwWM`UhB(%jT)} z6PJ8~iHpoJ(%lWuTRvLS1d*jo)J1(^a8wbvxQ0Yd_Rou-Eo1t^gnC`h8;1?AKXQvJ z-7%=gFkdFF5f0ADM4o>@7YLBI=iNUrj4+9%#sIFFIpqN@B7XM0 zQ4mF{8SHM4kQHTdJWG5{ooLNL}1;0oP76grdJ87= zGS$Bnp+VhGG*9P9DCdr?>@E8vw2tvfw(m$tBaczhz^bN>Rp(n-OW2sc)A0|z z;}V_s2yG`s8n=Q+qVI`#M`!yv#TfU93(-$X_Fy_Y1Sy(&jlnVd3j|AL?Y2;l44w(E zcEq!kytpkNc$UKBU`sze_>NrX0_54f=#H)n0ulJEl$@Y24vAJof@PIX^GUkK%b=M% z7LJ?+WC-(Yb}?-$wOVr#QzB{sq&76^jQN1hOvEx9OLBeLP#1yJIY`>FSQqqd;bj*z zj)mFsQ2SDi`ifY4Gb9ZnE21Edl^S4eD|VlTyjFg7CNl|?jWbXB(NC(wg4IxMS9TqP z1rh9oAr4S2kf=^1DmKUcSoCHaZYMD7a3Lw6lUs#=F!1sK32lLZG4IzfD~`))KFUIB zwov1m_M8ZrnZ~R2&lYp6*bR}Q8Y>Og7`1TSryAVt_rDn6|4Bu z1x7g=zH`i!i_%-U7PGF3A0jiJGUfhW$FrL5wq_Ichvhv!+gypOVt3RwBQ|(vZUG#u6gg$p=lOuxeP}6JD zqpO-;#Lemmh^#MczKld^YWE766o8(b*NejSR9sqL-wpfBBH^Hn@fDaT;&xrDEBngC zz+1P;#KSi3D0%^z?t5)S6VgLEiT47#Ewd(F`)bE*e2IQ;-lv^S`v zsyATQ_Y7A3V;q4$#J3(P-Icu@o>{Jo@LO>j_ZC%SxUhwk{p>B@-&??Txz zm;2lV!qRAZ*Q#rioIkQJ!^viZpn#BREH3sob#NO@0vm0Q;I)R1E0k5O{NY4KQn=C6 zwA#_+bViDL;B`KkPe*O;$ah(~Sosu(%S2sDS0qhb!2@O7&hP;Q!5rVPSvUs9u}$fk zRA0_{;VPnXF`o^ED2+e29lpM{U@pDkT)yu}&D(L0FnlXz2>x7U_){6kPC=g6a4a|@ z?}jjcRe3^87?FyHkwcCQeb|r+xPSCQUI=D|&%YSnV(`OWeG!+4C_AH}56JOFqwUc9 zx>La<%!3^%qmDT7$FNJ3w_>?d9Q+9TY{9{LeIyY{(5C|I0Z8G7u>ktu(Nb$?B|NZp z-|~#!eKO|4`E{iTCuAT&;X5rBXqI02sstet(p3r83F?KusHdKcB%cy4u^(qjNj4I{ z%vf;pNT4RqAHosJdb;rTxMNihfChDT4`F*;7+vpwFs;i zK-Lj(r{y%RpwpA@B81~jy%Hed^X=44W+}~8>8}KCL--0iw_BCi#j?((!DX@QUuF~E z61ZJ9E@UxVw2pgS+U*(BhP`0l+HAzvD@NX`;F&)idIS#w-mWE3x;{Tu&~`MR`L{%l zh3iQ+%5%CrMZzxebFBFM4Z{fmB}=T4-Y4B*3pp+yf^?MaLA4=f&7mfgkE0?s#9>rH z3HO%7s|(1rMTy zA^P|d(#+9kZeb%j^LZ8_iQ`)rW*bN%2VFwW`mC_|8^TTywdY?!*{2lVW$j^D?e-;M zNxzb5w}(Zq;Y3yiT$I6F#M~f@b56l zA(>bXB}5LzZ~OWW$+0PI;f%wljGI)T$oR)c-*1e(PhcZ&;mexjs>h3ST#n3PqB>`I zw@#;isIR%MIF>azW4dpY&ZAo2WvKO8kU$G$mEJz(r|y=4qf`L$y82WhshXo}E3stXrvHj^pIAqZP4J`==1KC(i0jh* z;@L8*e`%qJ8$8uCe#r`>xk6xX0U?@3_}tIfm)=MO#G7H%hN%m0w-hciS`HhdGH&Tn z8rWJ#9xPL$N2^h3mNBfT(8)SeYNPriIA8|vIY){kn}l?3R(A3Jt%=$9s1%)2i?uy8 zlX`A>s8$yYuS;S5u$Q?@Cw6X-qx=Q~=8K`_#Zm5w5p;W=KfkJq;Sh4TE9(5LA$4z; zu)cZ9+8bPZ^sR4rE7bDT-Yd>unhD5n@QdMr(V^(cvun6Ww!foyj$*UB>xA3D@Kl(P zcvU7OXpCXDk%kbKY^3d2A5t*-hb22y*HYlLJ$bW%0rchf1GP5Y#2C1Yq}7>-kX0I# zzbT51Vsh5ehA^q>y6^&%4b=%y0<8$VIIZ(ZKeA~~Fy40&&%G~$7T(UU^4+LnH-sVF z%$JZ%R>>Yu@)2}ZBGq#iwa-lzlc)!*Y#;iGViM?wWD28v?8)UxwXwVUp(x|gKW~V) zshy(#fNV#6WVNCXF4fgCICra8cvP`^&;_oG2u(j|mh9L0rTwmBZV0vyQ!>#^=Vns$ zb1q49(aQWGs+c)=SIk4-BZse1%cO~)cGZ|fl-FgD0;-H&SorreEexNB=5A8(`a;AR#fN$~qEpM|U(1?N`;-!sZ5!Q4)tNbp%_V&+Ab$7JQ7HMnX z$N=*4Johs%&Ft?-4J+Aa0(Qdg?O=~*KdDVYspsGypUC8IMnm7?NqcvYem?19*N>LR z5lIT)k>|`P_EQSUS3To^Ye9iL@d*2(B;BLNY)(eZd<(Vhl@K~wwc`3I9e<icK z&Ldp#!2ML#4=M5Ouih9DiP#G^;RBl1vm(mCTkh_8Wc5t_4sR*IgkC(T7B zquSuTRPBp&S4(WE+D3%+B; zDKeexFJ8C!bQ0khiI*yB;-1Qs4W^{ORWik@zn80FD23t*qb&<(7C_F!#&A{jW4<2) zjw5LluO#s)s4x`$G7rZ8E+(Z=IY?{gU{3l+Q+*30*5U8a^qami)f7MB5^j6jm+Y7& z>_n67u<1Q~*FCkD=DKQFjP0s%Ik?hyxduSLFlAUfm$vT>Z9&umo@(k*A!?D<#~~J zA?MzO@5m4r`jxr`!1*C5)XXkZBoRf*iY@>fxN9No{k;N#WR_Moo^sJH?Q3+1W#@Vl zGM9&6K=4CFF-vpoU<4IL;f(i*K%8*W2mE<*^qR^Q|9#@pA|}iXvk}ztA6I5+p$-(2B~xkDqH3B{Zj&*oFnj^-;I(ay^QA+ndErfaXJ{< z2BEIS>)ta5g3ptri;yI*2N)WhrCZp-cryRM{;<_OqmoD-aXrASJ33hbBHbV{y(Z%= z4)bSSrhZi=sE6R8PlC#GS3+op*9=RbT|PV7Rg=4p`;&yPhjHdpzVXhn@lL9-kzU)A zU3)#R`i)cD^J~qo?MbTb$*S!+QE^dN);4e6=4|xi(YQVwZt!JXc4nbEo%&_A9X}sx z2yJuok@;~wX~&#@^*mbCh+GJVj>+p4+8@VbZ@p zSKIv2!Tps2zma!J|DnuItp~#R4}$;5r^5O>UBz5y9#Js2J8w<|^>@ON--|TO0f4z! zwz(*>Re@-QLb!xseVIoWg8iecQ`1hg+ZzoXSUMM20kN`$cKRCEDZGnOO6XwIRcMix!05Dq`)m}HhMgwY#ABov~T zRE_y{sZVLaMPWQ40{vkCLdX+THN^ZUzO_3qd)_e10{sJO{@c%BA zf~&3Ve<)W@lC0uaxdJSXl*Q4-#3PXkBO%$HA}x)FJo-IE$pzb)E+NyJ^;IxY{nMz> zkUl{CQ=D{YmCGw`S+5;<*|wkJSGho_MHoR*w3dmh`ZFQV!S}HSFwc^Niem@2-@6UkQWMGdk70*mjI)|M9?Jqxz5DdJ}WMr^DB`|N}As|%k*`ia9Uay{J zu&2`@`tf^utw!b)d%#?V7X!dkir(gBol=*ESHic0>3hVFvUcMf--?m2{VKv)%--QN zjNX+FCOLW<724N92}gIelb9PAeesDvoREiY`+5+W=)|zaXZPt9P{fGWNIpcYuy^rO zlRUv~QwdGlYxC^8J_+L|+gj|Nng@|4j(;zhXla63C;Poc#gI$kcOl z36Pm7hWRX^DOT_ecDuZ?MJtPq(>bA65Z`hIcZyL& z!R?4!j|YNNx9g_1wvFV^_v>qa5JQ09RRGd2Pd@nmRi|f2g9IPh!i0;Ya&lZ4vUM_= z1axVaB;O=3)Zk(<<0LI|vm_vD))0x4G%dL#`6xM)w1Sj^bT8S9AY`5K4G`Wy7MZ~& z4t&sRnU+Gb!baUTby{lfRf@~iT_b2{Y`B#C4z-zH z2RAvNttQL1M`gpzO<|qGv6#=UA}UeSHYc|#n899oltLcrPBy9nT`Mw!5zBg-ZM}Vr z4&rwy`@{Tpa<*%q9E_I)>Z$LMlr(OHthv4}7u?BuXs+u(r^>*yKBCYH-@t6?6r&A7 z+_s1^Bs1*q9?J|$RsC(&9E#R5HF)<;BhEBK^2DTklb4c-iChjyAsOZqMHwqdH2LaI zdbMn{#L4#SM!U+eBWAln#sfcA`9nXr?ewQVV=hCit?K5j-i;oGxYbU>bRWNuqBvFA zX~i{!hTrP)@CL{32`7jKDh+I!RsA^5g^M`KxSEjBJ7%T_>GbC$5q&IXp1Bt zez2Z=kl~pcQfT~!Wh;?HniVu}%n|EqoLT-Z;E-e-o$^g=!5Ag}FMLIF+|xh}bO62AOqX&1i_$sn88Rv-n;6_+CCiNT{SCb5*iK&NA{!P=sr! zMNMe^jWD9QtF)fb*XKQIHMOgdhlyUjrUm>Ux0UTj8wu^^o~m5iV)%HD*3F*ruSt(d zi-%Blj>rzPBI;@5<_0C#tVjn`ok9!*2kt3J_uACZ3z#NcU!%X);X3HQdZ?dvE;vz0 z$j*AIe6AZ3p1!LNogHfrBd?@IJPOY8LK~ThSKIJU!W$il`SSNY-5NpL=r-4$zjbaQ zV}5*tGxzPwQy(R%wkX7RxZ%kSt9KKt7Ri024S6g%{#^e2*EYCUnHZ=16`AdU1OXBG z|J?@v$3qjbDZ46*!ssKj#s!#a!Za#0QWz!bV2XO^Pk=W6=S$Li==MPUpmbGNTD`c|<0N4Uex(MLJ+ zzL%H)Qu#K?l`_{hd*}vB;j9*)W<=oAb8}d>teD)WMSe6@jug=@T589(T7AuzmeX3}ql8+z{5E-DA!Ge#Ly!Z9 zk|{oNg1M5-m8Z(rZ;5J0T!q~E&-C-e<4xGYFNwheek&rV_PLT?4&LU|HOlNZ)9>-w zCvSA~aZ?kJuPLzBY@aT9$_;3jGKQ-UdV?JEdRaKZieWDu-?+B4j`uZ(o_8^yTgG>y z?;SL?aC)a$V0)d59*@X#K5ziwrNpl_$BvoAPyy!;mN|hw-GU*2GjrwCL080avRM9= zF|^pJ!5~r0UlpRc{Yj!xxY{dY&au_P(j-iV>Lg}0101o{Hisn=oa`#|V|20ID`Vz9 zuF2i=W4hA~40d_6OXznBlV1K=d;WNJWqX7F>uHf914UOPBoGkeuQ|m3&Th6d{<44m zlii#F<%2#DM73cQcIK=6`lk+%5ZzjE-AEYv%U)p6$3BI z7>lkvLTiqSGlg>Ys_E~AVAt$U-t6l|@2CG$J1gH{!Hdt`?s~?{=O4aHp(by|55HMo z5T#N3n+8zZ{B#WObz&mZMpV{dUt}W+1C28jt?az^ktzUXfy)<;vyL@Q#pj45>1SW`qYwp2N^3@cMa zszo_--V99EFBdu~L)siOgOjyse2RoEeTtt|G9g3J95jP$9AEsmCF^JcPui4|DLU(= zDZn(yRE?Fuly}@Eaej=RyeUF1LhgrLNQ^>h)|4?TBu;XSIHgQ!c$keeJnOhRoGG`QbK$fs7Oj6)S&YDu#nL zPN&^Y!6A9z$V6(yVXEMxGO=g{WbB~nR$8^gFi(fRGkLY0izJI+Fri~_>T7Na57+#| zUrxr5wOTBa5ElRG6qsO~d32&e=uC5sqpHAo^vg{>GKDL~uIAt!8=aDcJpmwd)cPo1 z&A7Y(SgVfI5oml5v|A+=f$XK}0d3h_c!)SPvtXvKb#%uKG_%P;+3vI8J?d#ep@=bS zSz3G~0jdZ2CO=q`W2X;>Gb4Ov)ms^rU>TA9$%l9RYqC5Q5ULJYlE!g@B750VzlIfy zT+3EXI9=PVYkfp{At4V#;d3XqoQatS=b1C^4n`*t`CG!jnq8X%EXlueG2jOmAp z+#^DbB*#TT?6Ts_7#!tQw=GX=2zStBAddvJ!&EWe^?(QL`4o#)t@ktmjp9-NooI2sl+3NQ>OPAU#<1RCETcCbxw816eD z)79}hyk8=!`E&$(h>L2Ax0#6Ci2g~1mhihud3!Xr7ebN!3K{u`-yLPxqe=UMws)

)m2r6~;hA!969R=X?VsQV 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%0DjU3S9- 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Ɉ`#+#RD|da}B=kRrA(3d3r-H_rlodc;Xd9H`=I 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%0Dq!>~^QbxJG>E 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 E035TBk^lez literal 0 HcmV?d00001 diff --git a/lib/craftbukkit-0.0.1-SNAPSHOT.jar b/lib/craftbukkit-0.0.1-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..747976e87df505652dc364f8b903a9b1ad857863 GIT binary patch literal 1458639 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