Compare commits

...

151 commits
v1.4 ... master

Author SHA1 Message Date
d46adfd957
Fix custom charts
Probably
2021-02-21 02:15:10 +01:00
12a8ccf3ce
Use bStats for metrics and remove Piwik integration
#4
2021-02-21 01:39:51 +01:00
dcd3ff31db
Fix WorldEdit integration stopping edits
It's been only more than a year, it's fine
2021-02-21 00:04:56 +01:00
e4548069dc
Update dependencies 2020-07-27 16:24:42 +02:00
3f9c2b99f9
Version update 2019-09-21 16:28:47 +02:00
6d5f42b2a5
Added ReflectionStorage (mostly version-independent)
(Started on 2019.08.29.)
This means it supports 1.14.4
It automatically falls back to the previous storage if the newer version is not found
2019-09-21 16:14:58 +02:00
14bdf0ebe0
Updated WorldEdit and WorldGuard to 7.0.0
It doesn't work without them atm because it tries to load a class from them
2019-08-28 23:29:40 +02:00
24ed3393d3
Giving 30 seconds max for the thread
The plugin will wait 30 seconds and if the thread is still alive then it interrupts the thread which should instantly end the loop.
Also other fixes
Also notifying all threads that could wait on the queue, though it should be the only 1 BS thread
2018-10-04 00:34:00 +02:00
cd7b7a550d
Might have fixed the stop delay
The theory is the following: multiple BS threads were created, one for each chunk, which caused long locks. If this isn't the case, I don't know what is.
#2
2018-08-31 17:08:06 +02:00
b84ecf8545
Added conversion in DB 2018-06-30 16:28:32 +02:00
ecaecd4136
Added name to UUID conversion 2018-06-27 21:59:12 +02:00
362d1d823c
Small fixes, ready to go 2018-06-27 17:53:04 +02:00
b8d21657ce
Merge remote-tracking branch 'remotes/origin/spigot-1.9'
# Conflicts:
#	pom.xml
#	src/main/java/de/jaschastarke/minecraft/limitedcreative/FeatureMetrics.java
#	src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/worldedit/LCEditSession_LogBlock.java
#	src/main/java/de/jaschastarke/minecraft/limitedcreative/limits/PlayerListener.java
2018-06-27 13:42:29 +02:00
d7e4eafc4d
Fixed thread stop & metrics fix
The thread will be restarted automatically after an error
2018-06-27 00:14:09 +02:00
f2af77b9b7
Resolved compile errors, LB removed
LogBlock support removed
2018-06-26 21:28:36 +02:00
pickernickel
8c1240cc24 Use UUID instead of player name. 2016-05-23 22:42:52 -05:00
pickernickel
05d37326e0 Circumvented some deprecated API usage. 2016-05-22 04:35:52 -05:00
pickernickel
b2e154be45 Slime block compatibility. 2016-05-18 03:34:19 -05:00
Jascha Starke
8cfc3b7f01 Spigot 1.9 Update 2016-03-02 22:47:46 +01:00
Jascha Starke
1efdf717b5 Incomplete Spectator-Support 2016-03-02 19:57:25 +01:00
Jascha Starke
256f165622 Spectator, chestOpen ^ Inventory
* Support for Spectator-Mode (always gets creative Inventory)
* Prevent Attack across Region borders
* chestOpen now allows Inventory again, to make /inv addons possible
* Placing into creative regions should now be handled again (survival regions may bugged? but no one uses them at all, or?)
2015-05-11 20:15:11 +02:00
Jascha Starke
d010249107 Spigot 1.8: Armor Stand Support (Somehow. Spigot Implementation is Buggy) 2015-04-11 14:09:41 +02:00
Jascha Starke
7b72e1d5cf WorldEdit 6.0 2015-04-11 01:47:40 +02:00
Jascha Starke
87cde8e182 WorldEdit 6.0 2015-04-11 01:36:58 +02:00
Jascha Starke
acb0717644 Spigot 1.8: More deprecation 2015-04-11 00:03:42 +02:00
Jascha Starke
648ef2070e Spigot 1.8.3-Update
+ Moved Metrics
+ Temporary disabled Worldedit-Integration
2015-04-10 23:02:32 +02:00
Jascha Starke
c387bcbf55 Spigot 1.8 compatibility
* 1.8 Spigot API
* 6.0 WorldGuard
2014-12-01 22:18:54 +01:00
Jascha Starke
47fb0e137a Quick-Hack: Disable WorldEdit-Integration for Performance-Reason 2014-01-04 21:03:31 +01:00
Jascha Starke
06e08c630e BlockState Hanging Punch in 1.7.2 2013-12-09 23:07:44 +01:00
Jascha Starke
8a76616969 Config Reload of cached lists 2013-12-09 22:14:17 +01:00
Jascha Starke
8c9be4f1f4 WorldEdit in transaction. (Better WE Performance with BlockState)
A special cookie for LordSaad, yummi.
2013-11-08 11:57:36 +01:00
Jascha Starke
aba6bf354d NPE-Fix for syncronized explosions 2013-11-07 08:43:35 +01:00
Jascha Starke
010c0434c4 Added /lc reload to command list 2013-11-06 09:44:40 +01:00
Jascha Starke
dfb289fdd9 Removed temporary sysouts 2013-11-04 16:45:20 +01:00
Jascha Starke
808b50fb61 CoreProtect WE-Integration support 2013-10-29 13:09:17 +01:00
Jascha Starke
fcb1e92f90 Give blockstate thread more time before warning 2013-10-26 20:33:54 +02:00
Jascha Starke
f545debb97 ItemFrame (Hanging) Handling 2013-10-26 18:19:35 +02:00
Jascha Starke
2477ec8f81 Workaround PlayerInteract with Air Event Bukkit-issue (eye of ender, etc.) 2013-10-26 14:49:26 +02:00
Jascha Starke
a1a041fc36 Add Eye of Ender to default use block 2013-10-26 11:00:41 +02:00
Jascha Starke
135fd5d9f8 Fixed config Defaults 2013-10-21 15:40:33 +02:00
Jascha Starke
31e5d5d6db Version-Number-Increase 2013-10-21 08:58:35 +02:00
Jascha Starke
e060fd359e Removed AuthMe3-Integration on Xephis explicit wish...
.. as everything now is handled by AuthMe without issues
2013-10-21 08:49:42 +02:00
Jascha Starke
175d399384 Give threaded startup 30s before warning about queue size 2013-10-19 18:11:16 +02:00
Jascha Starke
4498d8343f Slimmer BlockState-Database
- Default logSurvival to false
 - "/lcbs cleanup" command to delete survival items, with logSurvival: false

Rename TabCompletion
2013-10-19 16:29:40 +02:00
Jascha Starke
814c848e53 Official md5 LogBlock-Repository 2013-10-17 23:00:42 +02:00
Jascha Starke
57453ffce1 MethodContainer-TabCompletion, README-Update 2013-10-17 21:57:48 +02:00
Jascha Starke
9b3617ecba AuthMe 3.0 Support 2013-10-17 20:29:21 +02:00
Jascha Starke
18b90dedc9 TabCompletion for commands 2013-10-17 16:50:32 +02:00
Jascha Starke
2957233fbf BlockState-DB Migration: Import from CreativeControl
Limit-Config: Remove button/level default
2013-10-15 23:09:28 +02:00
Jascha Starke
9eba342758 Syncronized Update non-cached state fixed 2013-10-15 22:59:35 +02:00
Jascha Starke
65a50d30c0 Release 2.1
- Prevent Drops of Killed Mobs
 - Prevent Minecart-Drops (when TrainCarts is installed)
2013-10-13 23:04:57 +02:00
Jascha Starke
8e3b771d61 Fix of pickup-Permission 2013-10-05 14:16:00 +02:00
Jascha Starke
9275b9b4a5 Module reload fix, Better Thread-Performance-Warning 2013-10-01 16:58:01 +02:00
Jascha Starke
4b345cf880 Use of reworked Module-System. Dependend submodules 2013-10-01 15:57:04 +02:00
Jascha Starke
9061e18db9 Fixed: blockbreak in threaded mode requires cached value... 2013-09-30 19:35:43 +02:00
Jascha Starke
bd83e5b7cd Small Chunk loaded workaround, mabye 2013-09-29 22:29:37 +02:00
Jascha Starke
5fb285d0db Documentation-Update 2013-09-29 15:41:06 +02:00
Jascha Starke
b9e2da1b82 Use of new configuration styles 2013-09-29 13:15:08 +02:00
Jascha Starke
c7abaa7444 Armory load fix
use "current" to set InventoryArmor from ingame command
2013-09-28 23:53:43 +02:00
Jascha Starke
fd3c9da9ff 2 NPE fix 2013-09-28 17:25:06 +02:00
Jascha Starke
6db1664a7e BlockState Migration-Command 2013-09-26 20:29:43 +02:00
Jascha Starke
0a05ac75a4 Handle Fast falling replacement 2013-09-26 11:13:24 +02:00
Jascha Starke
23525692e1 Handle falling Blocks (Sand/Gravel) 2013-09-26 10:02:29 +02:00
Jascha Starke
49b528e352 Annotation instead of pom registration, with Configuration-Default generation 2013-09-25 23:52:43 +02:00
Jascha Starke
ea1921935e Per world disable of BlockState module 2013-09-25 19:25:24 +02:00
Jascha Starke
a704d9bc57 Fix/Reimplement removeDrops 2013-09-25 17:23:09 +02:00
Jascha Starke
f46f183dc5 Infinite Loop fix 2013-09-25 17:07:10 +02:00
Jascha Starke
e32bbbd105 Threaded BlockState DB-Connection 2013-09-25 16:35:41 +02:00
Jascha Starke
7506a7f1c1 ignoreCancelled via annotation 2013-09-24 17:47:02 +02:00
Jascha Starke
775ef40b1a Empty file hint 2013-09-22 14:27:57 +02:00
Jascha Starke
a3ab1fed16 additional debug-message 2013-09-22 13:32:35 +02:00
Jascha Starke
d53929a1b9 BlockState for breaking blocks by Water 2013-09-22 13:02:53 +02:00
Jascha Starke
c2ac988439 Scheduler Debug-Messages 2013-09-22 11:04:09 +02:00
Jascha Starke
c4fffc9059 Merge branch 'master' of ssh://git@github.com/possi/LimitedCreative.git 2013-09-22 00:08:19 +02:00
Jascha Starke
55a9b490a1 AuthMe downloaded repo version 2013-09-22 00:08:09 +02:00
Jascha Starke
1e24c18c6e WorldGuard Repo missing dependency 2013-09-21 23:26:33 +02:00
Jascha Starke
6101a62918 AuthMe correct API-Hook 2013-09-21 23:23:40 +02:00
Jascha Starke
f322468d40 Usage of AttachedBlock CustomEvents to prevent drop of torches and co
Disabled MultiWorld-GameMode-Hook (as MW-GameMode dosn't work at all)
plib 1.3 compatibilty to prevent NPE
Region-Command and Flag-Storage fixes
Creative-World-Suicide fix
2013-09-21 22:12:40 +02:00
Jascha Starke
d8cc4f2412 dow 2013-09-21 10:23:55 +02:00
Jascha Starke
ed809b5b18 Fix: NPE when moving non-saved-survival-state 2013-09-21 10:23:04 +02:00
Jascha Starke
acbe6838b7 Rely on the new inventory blocking, so that placing against chests while crouching is possible 2013-09-19 19:41:10 +02:00
Jascha Starke
2bb077f94f PistonGlitch Fixes
Ticket #147
2013-09-19 17:17:05 +02:00
Jascha Starke
9a6d57f2e2 Better Border-Check for collapsed regions 2013-09-15 18:35:56 +02:00
Jascha Starke
64eda8f1bd CommandBlocker ignore case 2013-09-15 15:04:59 +02:00
Jascha Starke
58742ee775 Permission node description line breaks 2013-09-14 23:10:23 +02:00
Jascha Starke
727b4914f3 Release 2013-09-14 16:25:44 +02:00
Jascha Starke
8e9dcd59f8 Reintegrated AuthMe Inventory-Events 2013-09-14 15:13:53 +02:00
Jascha Starke
57ad7aaa8d Fixed #146 by reverting event priority f*ckup 2013-09-14 14:30:09 +02:00
Jascha Starke
db97f869d7 Ticket #146 (possible fix)
- MultiWorld World GameMode support
 - EventPriority onGameModeChange fix
2013-09-14 13:53:49 +02:00
Jascha Starke
7385478e13 Small-Improvements
- Better .command-Permission documentation
 - JUKEBOX blocked by default
 - ignoreCancelled PlayerInteractEvent
2013-08-29 14:20:57 +02:00
Jascha Starke
b32b0109f0 BlockState-Improvements:
- Performance by using Metadata
 - Explosion checks
 - Disable Survival Database store.
2013-08-29 14:19:59 +02:00
Jascha Starke
23983ea6ad Missing file causing startup error 2013-08-17 00:32:48 +02:00
Jascha Starke
df373ab64c Fixed BlockState-Command documentation 2013-08-12 16:27:02 +02:00
Jascha Starke
77713a64ba plib 1.1 2013-08-12 15:57:02 +02:00
Jascha Starke
4d7507c557 ItemFrame support in BlockState
Reworked DocComments for plib-1.1
2013-08-12 15:50:05 +02:00
Jascha Starke
cdcf18cda5 Added entityInteract-limitation on region border 2013-07-31 14:27:04 +02:00
Jascha Starke
a622d4e405 WorldGaurd Typo-Fix (/lcr command) 2013-07-30 21:34:22 +02:00
Jascha Starke
93ee72e2c6 Fixed maxFallingHeight-Configuration Setting and added -1 to disable 2013-07-30 08:44:22 +02:00
Jascha Starke
aab42fcdca German Translation
and en. Localization fix
2013-07-29 12:25:24 +02:00
Jascha Starke
a33c4d4c51 New Inventory-Blocking, that doesn't require horse blocking any longer.
Can be bypassed with a dynamic permission (see http://dev.bukkit.org/bukkit-plugins/limited-creative/pages/permissions/#w-additional-dynamic-permissions)
2013-07-29 10:22:39 +02:00
Jascha Starke
58a092267a Riding animals buck off the player now on gamemode change 2013-07-29 08:47:25 +02:00
Jascha Starke
5d7dee727b Reworked DocComments for Better LineEnding parsing 2013-07-29 00:12:47 +02:00
Jascha Starke
cf028eb2dd Added XP-removing on drop prevention 2013-07-28 21:13:14 +02:00
Jascha Starke
b823dc24a1 BlockState-Command
BlockState loading fix
BlockState piston bypass prevention
Loading without WorldEdit dependency fix
2013-07-28 20:23:43 +02:00
Jascha Starke
86eeceb450 Added MCStats Metrics. Can be disabled together with Piwik,
or like descriped at http://mcstats.org/learn-more/
2013-07-28 11:07:27 +02:00
Jascha Starke
e7a794add7 WorldEdit Intergration for remember BlockState
(Should work with LogBlock, untested)
2013-07-27 17:44:30 +02:00
Jascha Starke
614a3e9007 Readded BlockState-Permission to plugin.yml 2013-07-27 00:28:59 +02:00
Jascha Starke
61cb058575 BlockState: Module Load fixed
BlockState: Config default disabled
2013-07-27 00:25:39 +02:00
Jascha Starke
1ef29ff8e6 Readded EXPERIMENTAL BlockState Feature with reworked DB. Merged from
branch 'remember_blocks'
2013-07-27 00:01:26 +02:00
Jascha Starke
1fbd0e14cf Complete switch from eBean to plib DBAL 2013-07-26 23:30:57 +02:00
Jascha Starke
54a0eb2224 Fixed Possible config updrade NPE 2013-07-26 18:21:26 +02:00
Jascha Starke
3cc2d3999f Fixed bukkit-version difference to plib 2013-07-26 17:34:16 +02:00
Jascha Starke
40233364aa Fixed ItemStack as Creative-Armor 2013-07-26 17:02:01 +02:00
Jascha Starke
536c5bfdcb Database-Rework 2013-07-26 17:00:47 +02:00
Jascha Starke
52dea4a793 Horse added to default config 2013-07-23 15:22:46 +02:00
Jascha Starke
0f2a978f75 New Limitation Features
to fix: #108/#121
Fixed #125
2013-07-02 11:43:13 +02:00
Jascha Starke
a013db180e removed block perm state 2013-04-27 11:15:41 +02:00
Jascha Starke
328929fb3f Removed not usable experimental feature 2013-04-20 10:35:53 +02:00
Jascha Starke
3a4f8a844b Default disabled experimental broken feature 2013-04-20 10:11:00 +02:00
Jascha Starke
73285de3c7 BlockState config description 2013-04-01 22:47:38 +02:00
Jascha Starke
d7280f6d69 Fix for #110 (NPE for empty BlackList-String-Entry) 2013-04-01 22:42:21 +02:00
Jascha Starke
76147c3c52 Merge branch 'remember_blocks' 2013-04-01 22:20:31 +02:00
Jascha Starke
85a0008fbe Improved tool usage 2013-04-01 22:19:58 +02:00
Jascha Starke
90cc0d0ccf Creating a block-database to store the gamemode of all created Blocks 2013-03-29 13:44:53 +01:00
Jascha Starke
7be648f552 Late loading/unloading of conflicting/depended plugins now disables the related modules
The opposite (if dependency are fixed again) is not implemented. A full server reload is required to re-enable the modules. (A reload with PluginManager works to, but is not recommended)
2013-03-29 11:14:10 +01:00
Jascha Starke
467653891f reverted chest recognition for beacon and enderchest 2013-03-28 09:46:03 +01:00
Jascha Starke
071279ff02 Fix for Ticket #102 (missing dependency -> NoClassDefFoundError) 2013-03-25 17:51:01 +01:00
Jascha Starke
ee0a78a2fe Experimental Feature: Per GameMode Permission (Vault, Perm-Groups)
Readme update
Removed dep. provided by plib
2013-03-24 22:26:53 +01:00
Jascha Starke
aa13a91c2c TinyUrl for config description link 2013-03-23 19:26:13 +01:00
Jascha Starke
694bde416e Removed unused dependency 2013-03-23 19:23:53 +01:00
Jascha Starke
4f11a2d604 Merge branch 'master' into plib 2013-03-23 19:07:50 +01:00
Jascha Starke
f688a2baed Merge branch 'master' into plib 2013-03-23 19:03:15 +01:00
Jascha Starke
fbcaf5f4f9 v2.0-3:
- Fixed #94 Minecart with Hopper
 - Fixed #97 pickup-Config option
 - Fixed #98 Region-Feature disabled failure
 - Fixed reload-command
 - Added entity interaction prevention (for #94)
2013-03-23 17:59:14 +01:00
Jascha Starke
89318a3658 Going for 1.5
Fixed missing strings
Fixed region interact
2013-03-20 21:33:52 +01:00
Jascha Starke
670908dc6a Missing commit
Cleanup (esp. Translation)
Fixed modules late load (confrom config cmd)
Optional GameMode per Region
2013-03-20 17:11:32 +01:00
Jascha Starke
cf9449aae5 base region general working 2013-02-10 22:12:31 +01:00
Jascha Starke
414a02f77c cleaned up pom 2013-02-10 10:15:40 +01:00
Jascha Starke
9ae49877ee repo deploy 2013-02-09 23:03:31 +01:00
Jascha Starke
fb62cc0545 fixed pom again <.< 2013-02-09 21:17:53 +01:00
Jascha Starke
3072aae358 POM fix 2013-02-09 20:34:24 +01:00
Jascha Starke
cd9dce04c5 Implemented (non functional) Regions 2013-02-09 20:09:57 +01:00
Jascha Starke
729c186b75 Better Configuration implementation and better working Limit Features 2013-02-05 21:04:05 +01:00
Jascha Starke
0d0a9bfaba Base impl. Feature Limits 2013-02-01 22:25:43 +01:00
Jascha Starke
dbce96a5ac Directory restructure (maven recommended layout) for Unit-Tests 2013-01-23 16:31:33 +01:00
Jascha Starke
de57c93844 Working commands 2013-01-22 18:38:48 +01:00
Jascha Starke
771d2a01f9 Neary full functional Inventory module. 2013-01-20 13:15:34 +01:00
Jascha Starke
672befc658 Working Inventory-Feature with some basic configuration 2013-01-18 22:51:08 +01:00
Jascha Starke
f80a88174c Complete rewrite beginning:
- removed any old implementation
 - basic modul setup
 - using new hook system
2013-01-16 12:33:14 +01:00
Jascha Starke
2501aed96a Working plugin yml generation 2013-01-13 14:40:32 +01:00
Jascha Starke
d09306a9b7 experimenting... 2012-11-20 08:41:41 +01:00
Jascha Starke
0587d6a6b7 Converted Permission-Nodes, but missing translation for now 2012-11-15 22:00:57 +01:00
152 changed files with 9298 additions and 4836 deletions

8
.gitignore vendored
View file

@ -1,10 +1,16 @@
/bin
# Eclipse stuff
# IDE stuff
/.project
/.classpath
/.settings
/.buildpath
/.checkstyle
/.idea
/LimitedCreative.iml
# maven
/target
# Mac stuff
.DS_Store

View file

@ -4,22 +4,25 @@ http://dev.bukkit.org/server-mods/limited-creative/
Required dependencies
---------------------
* [plib](https://github.com/possi/plib)
* [Bukkit](https://github.com/Bukkit/Bukkit)
Dependencies for optional integrations
--------------------------------------
* [WorldGuard](https://github.com/sk89q/worldguard)
* [WorldEdit](https://github.com/sk89q/worldedit)
* [xAuth](http://dev.bukkit.org/server-mods/xauth/)
* [AuthMe](http://dev.bukkit.org/server-mods/authme-reloaded/) ([GitSource](https://github.com/Multiplayer-italia/AuthMe-Reloaded))
* [Multiverse-Core](http://dev.bukkit.org/server-mods/multiverse-core/)
* [WorldGuard](http://dev.bukkit.org/bukkit-plugins/worldguard/)
* [WorldEdit](http://dev.bukkit.org/bukkit-plugins/worldedit/)
* [xAuth](http://dev.bukkit.org/bukkit-plugins/xauth/)
* [AuthMe](http://dev.bukkit.org/bukkit-plugins/authme-reloaded/)
* [Multiverse-Core](http://dev.bukkit.org/bukkit-plugins/multiverse-core/)
* [Vault](http://dev.bukkit.org/bukkit-plugins/vault/)
* [Multiworld](http://dev.bukkit.org/bukkit-plugins/multiworld-v-2-0/)
* [LogBlock](http://dev.bukkit.org/bukkit-plugins/logblock/)
----
Building
--------
Download and install xAuth and Multiworld into the local `repo` repository with a command like so:
To use Maven packaging
----------------------
For required development snapshots, that aren't found by maven, you have to clone the project and do:
$ mvn install
in the directory of the project
```bash
mvn install:install-file -Dfile=xAuth-2.0.26.jar -Dpackaging=jar -DlocalRepositoryPath=repo -DgroupId=de.luricos.bukkit -DartifactId=xAuth -Dversion=2.0.26
```

View file

@ -1,185 +0,0 @@
# --------------------------------
# Limited Creative - Configuration
# Full Default Configuration at:
# https://github.com/possi/LimitedCreative/blob/master/config.yml
#
# (YAML-Syntax: http://en.wikipedia.org/wiki/YAML)
# --------------------------------
store:
# SeparatedInventoryEnabled
# Use this option to disable the separated inventories feature, for the case you only need the other features.
# default: true
enabled: true
# StoreCreative
# Should the creative-inventory also be stored on disk, when switching to survival?
# If disabled, the inventory gets cleared every time on switching to creative.
# default: true
creative: true
# CreativeArmor
# When set, all creative Player automatically wears the given items as Armor. So they are better seen by other
# Players.
armor:
# CreativeArmorEnabled
# When disabled, the players Armor isn't swapped
# default: true
enabled: true
# CreativeArmor-Items
# Allows changing of the "Creative-Armor" to be wear when in creative mode
# *see Blacklist for details on Item-Types
head: CHAINMAIL_HELMET
chest: CHAINMAIL_CHESTPLATE
legs: CHAINMAIL_LEGGINGS
feet: CHAINMAIL_BOOTS
# InventoryFolder
# The folder inside the datadir-folder (plugin/LimitedCreative) where the inventories are saved to.
# By default the inventories are saved to "plugin/LimitedCreative/inventories".
# default: "inventories"
folder: "inventories"
# SeparateAdventureInventory
# When true, your players get a separate inventory when switching to adventure gamemode (2). Otherwise
# they have the default survival inventory while in adventure gamemode.
adventure: false
limit:
# LimitsEnabled
# Use this option to disable all drop/pvp/etc. preventions while in creative mode. While you also can get this
# by giving the "nolimit" permissions, using this option can save you CPU performance.
# default: true
enabled: true
# RemoveDrops
# When player not allowed to drop items, remove the item instead of putting it back to inventory/quickbar.
# You may disable this to get rid of the server.log-message: "Fetching addPacket for removed entity: CraftItem"
# default: true
remove_drops: true
# BlockPickup
# Prevents the pickup of items while in creative mode
# default: false
pickup: false
# RemovePickup
# Instead of blocking the pickup, you may want to disappear the item from world (good when destroying walls with
# signs or playing with minecarts). Only works when BlockPickup: false.
# The permission nolimit.pickup bypasses the removing.
# default: false
remove_pickup: true
# BlockSign
# Prevents interacting with signs (right-click), while in creative mode, so trading becomes more difficult.
# Attention: this will also block useful signs, like Lifts.
# default: true
sign: true
# BlockButtons
# When enabled also blocks usage of Buttons & Levers while in creative mode.
# default: false
button: false
# BlockWorkbenches
# When enabled also blocks usage of workbenches, anvils and vendor-villagers like chests.
# default: false
workbench: false
# BlockDamageToMobs
# Prevents dealing damage to all creatures in creative (friendly sheeps as well as hostile creepers).
# default: false
damagemob: false
# UseBlackList
# Prevents using or placing of the given blocks in creative mode (and only in creative).
# You can use the technical name (see http://jd.bukkit.org/doxygen/d6/d0e/enumorg_1_1bukkit_1_1Material.html)
# or the id of the block/item (better use the id, if you're not sure).
# To prevent Lava you need to add "LAVA_BUCKET", because lava-blocks aren't "placed", therefore Lava-Buckets are
# "used".
# You may add the data separated with a colon e.g.: "35:11" blocks blue wool. But be sure to put it in quotes, to
# not break yml-configuration! Also supporting Eggs (e.g: "MONSTER_EGG:56" blocks Ghasts-Eggs). If you don't add a
# data-value, all items/blocks of this material are blocked.
# You also may add the special block "*" (better add quotes to don't break yml) which prevents the usage of ANY
# item/block.
# default: [exp_bottle, bedrock]
use:
- EXP_BOTTLE
- bedrock
# BreakBlackList
# Prevents destroying of the given blocks in creative mode (and only in creative).
# You can use the technical name (see http://jd.bukkit.org/doxygen/d6/d0e/enumorg_1_1bukkit_1_1Material.html)
# or the id of the block/item (better use the id, if you're not sure).
# You may add the data separated with a colon e.g.: "WOOL:11" blocks blue wool. But be sure to put it in quotes, to
# not break yml-configuration! Named data values aren't supported yet. If you don't add a data-value, all blocks
# of this material are blocked.
# You also may add the special block "*" (better add quotes to don't break yml) which prevents the breaking of any
# block.
# default: [bedrock]
break:
- bedrock
region:
# RegionsEnabled
# Enables the feature for "creative-regions". This Feature is automatically disabled, if the required plugin
# "WorldGuard" (http://dev.bukkit.org/server-mods/worldguard/) isn't found.
# default: true
enabled: true
# RegionOptional
# Allows Players to use /lc creative|survival to switch between GameModes in creative-regions, even if they
# have no global permission to those commands
# default: true
optional: true
# RegionRememberOptional
# Remembers if s.o. disables the region gamemode, so the region doesn't change his mode automatically if he enters
# the region again.
# Hint: Is very confusing, if MultiVerse "enforce gamemode" swaps your state.
# default: false
remember: false
# RegionSafeMode
# When a player leaves a region he always will get back to the world gamemode, even if he entered the region already
# in the region-gamemode. So its the opposite analog to RegionRememberOptional.
# That means: If a GM in creative-mode walks/flies through a creative-region in a survival world, he will get back
# to survival on leaving the region.
# default: false
safemode: false
cmdblock:
# CommandBlockerEnabled
# Enables the feature for blocking certain commands in creative mode.
# default: true
enabled: true
# CommandBlockerList
# Defines the list of commands that are blocked while in creative mode. The leading / isn't included. By default
# the list-item is treated as simple string as typed in by the user after the /. All commands starting with
# this string are blocked, even if more parameteres are entered by the user.
# If the first Char is ^ the entry is interpreted as a regular expression (including the ^ for begin of the string).
# Only use regular expressions if you know them.
# default: []
commands:
# - logout
# - home
# - home second
# - ^chest (one|two|three)
# - ^(lc|limitedcreative) s(urvival)?
# Locale (Language)
# Uncomment the "locale: en_US"-Line, to override the locale which be used for localized messages. By default the
# System-Locale is used (selected by Java depending on LC_LANG-Environment-Variable
# default: none (Use System-Default Locale)
#locale: en_US
# Metrics
# This settings allows the Addon-Author to track the Servers using this plugin. It will not track any player
# related data like names, ips, online time or such. Please do not disable the option! As more servers are using
# the plugin and the author knows, as more he is willing to support the plugin! Its a win-win for both.
# Changing the option via command requires a reload to take effect.
# default: true
metrics: true

View file

@ -1,71 +0,0 @@
basic:
loaded:
worldguard: Erfolgreich mit WorldGuard-Integration geladen
no_worldguard: Erfolgreich geladen (ohne WorldGuard)
feature:
store: Getrennte Inventare
limit: Kreativ-Einschränkungen
region: Kreativ-Regionen
conflict: Wegen eines Konfliktes mit {0} ist die Funktion {1} deaktiviert
warning:
worldguard_not_found: WorldGuard wurd enicht gefunde, dahier ist die Funktion {0} deaktiviert
# double single-quote '' because of MessageFormater to insert {0}
command:
player: Spieler
switch:
survival: Ändert den Spiel-Modus des Charakters zu Überleben
creative: Ändert den Spiel-Modus des Charakters zu Kreativ
adventure: Ändert den Spiel-Modus des Charakters zu Abenteuer
config:
overview: "[Einstellung] - liste durch weglassen"
settings: "Verfügbare Einstellungen: "
reload: Lädt das Plugin neu (funktioniert nur teilweise)
gamemode:
changed: "{0}'s Spiel-Modus wurde geändert"
no_change: Bereits in diesem Spiel-Modus
option:
done: Option geändert.
worldguard:
alias: Alias für den //region-Befehl
unknown_flag: Unbekanntes Attribut
available_flags: Verfügbare Attribute
region_not_found: Keine Region mit dieser ID gefunden
world_not_found: Es konnte keine Welt mit diesem Namen gefunden werden
no_flag_given: Es muss ein Attribut angegeben werden, dass gesetzt werden soll
no_integration: Der worldguard-Befehl ist nicht verfügbar, da WorldGuard nicht gefunden wurde
flag_set: "Das Attribut {0} wurde gesetzt"
additional_flags: Zusätzliche Attribute
cmdblock:
blocked: Dieser Befehl ist im Kreativ-Modus blockiert.
exception:
command:
lackingpermission: Kein Zugriff auf diesen Befehl
toomuchparameter: Zuviele Argumente angegeben
missingparameter: Nicht genügen Argumente angegeben
playernotfound: Spieler nicht gefunden
invalidoption: Unbkeannte Option
config:
savefail: Die Konfiguration konnte nicht gespeichert werden
material_not_found: (Konfiguration) Material mit Name/ID "{0}" wurde nicht gefunden.
storage:
load: Fehler beim Laden des Inventars. Bitte einen Admin die Option "UnsafeStorege" in LimitedCreative zu aktivieren um ungültig verzauberte Gegenstände zu erlauben
region:
not_optional: "In dieser Region kannst du nicht im folgenden Modus sein: {0}"
blocked:
chest: Zugriff auf Truhen ist im Kreativ-Modus nicht erlaubt
sign: Im Kreativ-Modus kann nicht mit Schildern interagiert werden
button: Im Kreativ-Modus kann nicht mit Buttons interagiert werden
lever: Im Kreativ-Modus kann nicht mit Schaltern interagiert werden
survival_flying: Du solltest auf dem Boden stehen wenn du Kreativ-Regionen verlässt
outside_place: Du kannst keine Blöcke außerhalb von Spiel-Modus-Regionen setzen
outside_break: Du kannst keine Blöcke außerhalb von Spiel-Modus-Regionen zerstören
outside_interact: Du kannst nicht mit Blöcken außerhalb von Spiel-Modus-Regionen interagieren
inside_place: Du kannst keine Blöcke innerhalb von Spiel-Modus-Regionen setzen
inside_break: Du kannst keine Blöcke innerhalb von Spiel-Modus-Regionen zerstören
inside_interact: Du kannst nicht mit Blöcken innerhalb von Spiel-Modus-Regionen interagieren
use: Du darfst diese Art von Gegenständen im Kreativ-Modus verwenden
place: Du darfst diese Art von Blöcken im Kreativ-Modus nicht setzen
break: Du darfst diese Art von Blöcken im Kreativ-Modus nicht zerstören
piston: Verschieben von Block {0} aus einer Spiel-Modus-Region bei {1} wurde blockiert
piston_in: Verschieben von Block {0} in eine Spiel-Modus-Region bei {1} wurde blockiert

View file

@ -1,70 +0,0 @@
basic:
loaded:
worldguard: Successfully loaded with WorldGuard-Integration
no_worldguard: Successfully loaded (without WorldGuard)
feature:
store: separated inventories
limit: creative restrictions
region: creative regions
conflict: Due to conflict with the plugin {0}, the feature {1} is disabled
warning:
worldguard_not_found: WorldGuard isn''t found, the feature {0} is disabled
# double single-quote '' because of MessageFormater to insert {0}
command:
player: player
switch:
survival: Changes the game mode of a player to survival
creative: Changes the game mode of a player to creative
adventure: Changes the game mode of a player to adventure
config:
overview: "[setting] - empty for list of settings"
settings: "Available Settings: "
reload: Reloads plugin (doesn't work on update!)
gamemode:
changed: "{0}'s game mode has been changed"
no_change: Already in that game mode.
option:
done: Option changed.
worldguard:
alias: Alias for //region-command
unknown_flag: Unknown flag specified
available_flags: Available flags
region_not_found: Could not find a region by that ID
world_not_found: Could not find a world by that name
no_flag_given: You need to specify a flag to set
no_integration: The worldguard-commands are not available, because worldguard wasn't found
flag_set: "The flag {0} was set"
additional_flags: Additional flags
cmdblock:
blocked: This command is blocked while in creative mode.
exception:
command:
lackingpermission: You do not have access to this command
toomuchparameter: Too much arguments given
missingparameter: Not enough arguments given
playernotfound: Player not found
invalidoption: Unknown option
config:
savefail: Failed to write modified configuration to disk
material_not_found: (Config) Material with name/id "{0}" was not found.
storage:
load: Failed to load your Inventory. Ask your Admin to enable "UnsafeStorage" for LimitedCreative to allow invalid enchants on items
region:
not_optional: You can not be {0} in that area
blocked:
chest: Access to chests is not allowed in creative mode
sign: To interact with signs is not allowed in creative mode
button: To interact with buttons is not allowed in creative mode
lever: To interact with levers is not allowed in creative mode
survival_flying: You should stay on ground, when leaving a creative-area
outside_place: You can not place blocks outside of the gamemode-area
outside_break: You can not destroy blocks outside of the gamemode-area
outside_interact: You can not interact with blocks outside of the gamemode-area
inside_place: You can not place blocks inside of the gamemode-area
inside_break: You can not destroy blocks inside of the gamemode-area
inside_interact: You can not interact with blocks inside of the gamemode-area
use: You are not allowed to use this type of item
place: You are not allowed to place this type of block
break: You are not allowed to break this type of block
piston: Moving {0} block out of creative area was blocked at {1}
piston_in: Moving {0} block into creative area was blocked at {1}

View file

@ -1,78 +0,0 @@
name: LimitedCreative
main: de.jaschastarke.minecraft.limitedcreative.Core
version: 1.4.7c
softdepend: [WorldGuard, WorldEdit, MultiInv, xAuth, AuthMe, MultiInv, Multiverse-Inventories]
dev-url: http://dev.bukkit.org/server-mods/limited-creative/
commands:
limitedcreative:
description: "LimitedCreative: GameMode-Switch, Creative-Regions, Config"
aliases: lc
usage: /<command> - displays LimitedCreative-Help
/region:
description: "LimitedCreative-Region-Command: configure creative regions"
aliases: lcregion
usage: /<command> info|flag [<world>#]<region> - set/get region options
permissions:
limitedcreative.config:
description: Allows enabling/disabling of config options ingame
default: op
limitedcreative.regions:
description: Allows usage of the //region commands
default: op
limitedcreative.regions.bypass:
description: Ignores the force of a gamemode, when region optional is disabled
default: false
limitedcreative.switch_gamemode:
description: Allows switching of own game mode to creative/adventure and back
default: op
limitedcreative.switch_gamemode.backonly:
description: Allows switching of own game mode to default of the not world he is in, but not back
default: false
limitedcreative.switch_gamemode.survival:
description: Allows switching of own game mode to survival, but not to creative/adventure
default: false
limitedcreative.switch_gamemode.creative:
description: Allows switching of own game mode to creative, but not to survival/adventure
default: false
limitedcreative.switch_gamemode.adventure:
description: Allows switching of own game mode to adventure, but not to creative/survival
default: false
limitedcreative.switch_gamemode.other:
description: Allows switching of other users game mode
default: op
limitedcreative.keepinventory:
description: Allows bypassing the inventory separation
default: false
limitedcreative.nolimit.drop:
description: Allows bypassing the "do not drop anything"-limitation
default: false
limitedcreative.nolimit.pickup:
description: Allows bypassing the "do not pickup anything"-limitation
default: false
limitedcreative.nolimit.chest:
description: Allows bypassing the "do not open a chest"-limitation
default: false
limitedcreative.nolimit.sign:
description: Allows bypassing the "do not interact with signs"-limitation
default: false
limitedcreative.nolimit.button:
description: Allows bypassing the "do not interact with buttons"-limitation
default: false
limitedcreative.nolimit.lever:
description: Allows bypassing the "do not interact with levers"-limitation
default: false
limitedcreative.nolimit.pvp:
description: Allows bypassing the "no pvp"-limitation
default: false
limitedcreative.nolimit.mob_damage:
description: Allows bypassing the "no dealing damage to creatures"-limitation
default: false
limitedcreative.nolimit.use:
description: Allows bypassing the "block place/item use"-limitation
default: false
limitedcreative.nolimit.break:
description: Allows bypassing the "block break"-limitation
default: false
limitedcreative.cmdblock.all:
description: Allowy bypassting the "command block"-limitation
default: op

456
pom.xml
View file

@ -1,153 +1,303 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.jaschastarke</groupId>
<artifactId>LimitedCreative</artifactId>
<name>LimitedCreative</name>
<version>1.4.7c-SNAPSHOT</version>
<url>https://github.com/possi/LimitedCreative</url>
<scm>
<connection>scm:git:git://github.com/possi/LimitedCreative.git</connection>
<developerConnection>scm:git:git@github.com:possi/LimitedCreative.git</developerConnection>
<url>https://github.com/possi/LimitedCreative/tree/master</url>
</scm>
<distributionManagement>
<repository>
<id>de-jas-repo</id>
<url>scp://repo@ja-s.de/var/customers/webs/repo/mvn</url>
</repository>
</distributionManagement>
<ciManagement>
<system>jenkins</system>
<url>http://ci.ja-s.de:8080/</url>
</ciManagement>
<issueManagement>
<system>BukkitDev</system>
<url>http://dev.bukkit.org/server-mods/limited-creative/tickets/</url>
</issueManagement>
<repositories>
<!-- Possible public Maven Repository, containing LimitedCreative builds and other dependencies without own rep.
like AuthMe, etc.
Supports http only -->
<repository>
<id>de-jas-repo</id>
<url>http://repo.ja-s.de/mvn</url>
</repository>
<!-- Official (Craft-)Bukkit repository -->
<repository>
<id>bukkit-repo</id>
<url>http://repo.bukkit.org/content/groups/public</url>
</repository>
<!-- Official WorldGuard and WorldEdit repository -->
<repository>
<id>sk89q-mvn2</id>
<url>http://mvn2.sk89q.com/repo</url>
</repository>
<!-- Official Multiverse repository -->
<repository>
<id>onarandombox</id>
<url>http://repo.onarandombox.com/content/groups/public</url>
</repository>
<!-- Official Vault repository -->
<repository>
<id>vault-repo</id>
<url>http://ci.herocraftonline.com/plugin/repository/everything</url>
</repository>
<!-- Official xAuth repository; it is no good! we keep our own dep-files of it - ->
<repository>
<id>luricos.de-repo</id>
<url>http://repo.luricos.de/bukkit-plugins/</url>
</repository><!- - -->
</repositories>
<build>
<sourceDirectory>${basedir}/src</sourceDirectory>
<finalName>${project.artifactId}</finalName>
<resources>
<resource>
<targetPath>.</targetPath>
<filtering>true</filtering>
<directory>${basedir}/</directory>
<includes>
<include>plugin.yml</include>
<include>config.yml</include>
<include>settings.properties</include>
</includes>
</resource>
<resource>
<targetPath>lang/</targetPath>
<directory>${basedir}/lang/</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
<extensions>
<!-- Enabling the use of SCP -->
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ssh</artifactId>
<version>1.0</version>
</extension>
</extensions>
</build>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.4.7-R1.0</version>
</dependency>
<dependency>
<!-- http://dl.bukkit.org/ -->
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.4.7-R1.0</version>
</dependency>
<dependency>
<!-- http://dev.bukkit.org/server-mods/worldedit/ -->
<groupId>com.sk89q</groupId>
<artifactId>worldedit</artifactId>
<version>5.5</version>
<scope>compile</scope>
</dependency>
<dependency>
<!-- http://dev.bukkit.org/server-mods/worldguard/ -->
<groupId>com.sk89q</groupId>
<artifactId>worldguard</artifactId>
<version>5.7</version>
</dependency>
<dependency>
<!-- http://dev.bukkit.org/server-mods/authme-reloaded/ -->
<groupId>uk.org.whoami</groupId>
<artifactId>authme</artifactId>
<version>2.7.2</version>
</dependency>
<dependency>
<!-- http://dev.bukkit.org/server-mods/multiverse-core/ -->
<groupId>com.onarandombox.multiversecore</groupId>
<artifactId>Multiverse-Core</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<!-- http://dev.bukkit.org/server-mods/xauth/ -->
<groupId>com.cypherx</groupId>
<artifactId>xauth</artifactId>
<version>2.0.26</version>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.jaschastarke</groupId>
<artifactId>LimitedCreative</artifactId>
<name>LimitedCreative</name>
<version>2.5</version>
<url>https://github.com/possi/LimitedCreative</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<plib.version>1.4-SNAPSHOT</plib.version>
<bukkit.version>1.12.2-R0.1-SNAPSHOT</bukkit.version>
</properties>
<scm>
<connection>scm:git:git://github.com/possi/LimitedCreative.git</connection>
<developerConnection>scm:git:git@github.com:possi/LimitedCreative.git</developerConnection>
<url>https://github.com/possi/LimitedCreative/tree/plib</url>
</scm>
<distributionManagement>
<repository>
<id>de-jas-repo</id>
<url>scp://repo@ja-s.de/var/customers/webs/repo/mvn</url>
</repository>
</distributionManagement>
<ciManagement>
<system>jenkins</system>
<url>http://ci.ja-s.de:8080/</url>
</ciManagement>
<issueManagement>
<system>BukkitDev</system>
<url>http://dev.bukkit.org/server-mods/limited-creative/tickets/</url>
</issueManagement>
<repositories>
<!-- Possible public Maven Repository, containing LimitedCreative builds and other dependencies without own rep.
like AuthMe, etc.
Supports http only -->
<!-- <repository> - offline
<id>de-jas-rep</id>
<url>http://repo.ja-s.de/mvn</url>
</repository> -->
<!-- Local repository for plugins without a repo -->
<repository>
<id>localRepo</id>
<url>file://${project.basedir}/repo</url>
</repository>
<!-- Official (Craft-)Bukkit repository -->
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<!-- Official WorldGuard and WorldEdit repository -->
<repository>
<id>sk89q-mvn2</id>
<url>https://maven.enginehub.org/repo/</url>
</repository>
<!-- Official Multiverse repository -->
<repository>
<id>onarandombox</id>
<url>http://repo.onarandombox.com/content/groups/public</url>
</repository>
<!-- Official xAuth repository; it is no good! we keep our own dep-files of it - ->
<repository>
<id>luricos.de-repo</id>
<url>http://repo.luricos.de/repository/bukkit-plugins/</url>
</repository><!- - It points to dependencies that don't exist anymore -->
<!-- Official LogBlock repository -->
<repository>
<id>md5</id>
<url>http://repo.md-5.net/content/groups/public/</url>
</repository>
<!-- Official AuthMe Reloaded repository -->
<repository>
<id>codemc-repo</id>
<url>https://repo.codemc.org/repository/maven-public/</url>
</repository>
<!-- Official CoreProtect repository -->
<repository>
<id>coreprotect-repo</id>
<url>http://maven.playpro.com/</url>
</repository>
<!-- Official PermissionsEx repository -->
<repository>
<id>pex-repo</id>
<url>https://repo.glaremasters.me/repository/permissionsex/</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>de-jas-rep</id>
<url>http://repo.ja-s.de/mvn</url>
</pluginRepository>
</pluginRepositories>
<dependencies>
<dependency>
<groupId>de.jaschastarke</groupId>
<artifactId>plib</artifactId>
<version>${plib.version}</version>
</dependency>
<dependency>
<!-- http://dl.bukkit.org/ -->
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>${bukkit.version}</version>
</dependency>
<dependency>
<!-- http://dl.bukkit.org/ -->
<groupId>org.bukkit.</groupId> <!-- Needed for WE integration -->
<artifactId>bukkit</artifactId>
<version>1.14.4-R0.1-SNAPSHOT</version>
</dependency>
<dependency>
<!-- http://dev.bukkit.org/server-mods/worldguard/ -->
<groupId>com.sk89q.worldguard</groupId>
<artifactId>worldguard-bukkit</artifactId>
<version>7.0.0</version>
</dependency>
<dependency>
<!-- http://dev.bukkit.org/server-mods/worldguard/ -->
<groupId>com.sk89q.worldedit</groupId>
<artifactId>worldedit-bukkit</artifactId>
<version>7.0.0</version>
</dependency>
<dependency>
<!-- http://dev.bukkit.org/server-mods/authme-reloaded/ -->
<groupId>fr.xephi</groupId>
<artifactId>authme</artifactId>
<version>5.6.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<!-- http://dev.bukkit.org/server-mods/multiverse-core/ -->
<groupId>com.onarandombox.multiversecore</groupId>
<artifactId>Multiverse-Core</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<!-- http://dev.bukkit.org/bukkit-plugins/multiworld-v-2-0/ -->
<groupId>multiworld</groupId>
<artifactId>multiworld</artifactId>
<version>5.2.8</version>
</dependency>
<dependency>
<!-- http://dev.bukkit.org/server-mods/xauth/ -->
<groupId>de.luricos.bukkit</groupId>
<artifactId>xAuth</artifactId>
<version>2.0.26</version>
</dependency>
<dependency>
<!-- http://dev.bukkit.org/bukkit-plugins/coreprotect/ -->
<groupId>net.coreprotect</groupId>
<artifactId>coreprotect</artifactId>
<version>19.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.avaje/ebean -->
<dependency>
<groupId>org.avaje</groupId>
<artifactId>ebean</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.bstats</groupId>
<artifactId>bstats-bukkit</artifactId>
<version>2.2.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessors>
<!-- Needed to fetch DocComments from Source -->
<annotationProcessor>de.jaschastarke.maven.AnnotationProcessor</annotationProcessor>
</annotationProcessors>
</configuration>
</plugin>
<plugin>
<groupId>de.jaschastarke</groupId>
<artifactId>plib</artifactId>
<version>${plib.version}</version>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>pluginyaml</goal>
</goals>
<configuration>
<!-- plugin.yml -->
<mainClass>de.jaschastarke.minecraft.limitedcreative.LimitedCreative</mainClass>
<softdepend>
<param>WorldGuard</param>
<param>WorldEdit</param>
<param>Multiverse-Core</param>
<param>Multiworld</param>
<param>xAuth</param>
<param>AuthMe</param>
<param>MultiInv</param>
<param>Multiverse-Inventories</param>
<param>Vault</param>
<param>CoreProtect</param>
</softdepend>
<custom>
<dev-url>http://dev.bukkit.org/server-mods/limited-creative/</dev-url>
</custom>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<artifactSet>
<includes>
<include>de.jaschastarke:plib</include>
<include>org.bstats</include>
</includes>
</artifactSet>
<filters>
<filter>
<artifact>de.jaschastarke:plib</artifact>
<excludes>
<exclude>de/jaschastarke/maven/**</exclude>
<exclude>de/jaschastarke/bukkit/maven/**</exclude>
</excludes>
</filter>
</filters>
<relocations>
<relocation>
<pattern>org.bstats</pattern>
<shadedPattern>de.jaschastarke.minecraft.limitedcreative.bstats</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>de.jaschastarke</groupId>
<artifactId>plib</artifactId>
<versionRange>
[0.1-SNAPSHOT,)
</versionRange>
<goals>
<goal>pluginyaml</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore/>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<extensions>
<!-- Enabling the use of SCP -->
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ssh</artifactId>
<version>2.1</version>
</extension>
</extensions>
</build>
</project>

View file

@ -1,2 +0,0 @@
piwik_url = http://stats.ja-s.de/piwikProxy.php
piwik_site_id = 2

View file

@ -1,10 +0,0 @@
package de.jaschastarke.bukkit.tools.stats;
public interface IStatistics {
public static final String SEPERATOR = "/";
/**
* Use the {@see SEPERATOR} to create subgroup of events
* @param event
*/
public void trackEvent(String event);
}

View file

@ -1,245 +0,0 @@
package de.jaschastarke.bukkit.tools.stats;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Stack;
import java.util.UUID;
import org.bukkit.ChatColor;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
/**
* Use the piwik-Proxy https://gist.github.com/4664325 to track the online-count as seperate requests to get a propper
* graph of usage.
*
* Settings as Properties:
* - piwik_url : required; URL to the piwik.php or the proxy file (see above)
* - piwik_site_id : required; The Site-ID of the Piwik-Website to use for tracking
* - stats_interval : optional; seconds between tracking online count (defaults to 300 for 5 min)
*/
public class PiwikStatistics implements IStatistics {
private static final int TICKS_PER_SECOND = 20;
private static final long DEFAULT_WAIT = 6000L; // 6000 ticks or 300 seconds or 5 minutes
private static final int MAX_CVAR_SIZE = 200;
private static final int APIV = 1;
private URL apiUrl;
private int idSite;
private Plugin plugin;
private String pluginname;
private String version;
private String server;
private String serverid = getUniqueID();
private String servername;
private String servermotd;
private long wait = DEFAULT_WAIT;
private static final String PIWIK_FIELD_CVAR = "cvar";
/**
* Single call instantiate
*
* Also calls .register,
*/
public PiwikStatistics(final JavaPlugin plugin) {
Properties settings = new Properties();
try {
settings.load(plugin.getClass().getClassLoader().getResourceAsStream("settings.properties"));
init(settings);
register(plugin);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Single call instantiate
*
* Also calls .register,
*/
public PiwikStatistics(final JavaPlugin plugin, final InputStream settingsFile) {
Properties settings = new Properties();
try {
settings.load(settingsFile);
init(settings);
register(plugin);
} catch (IOException e) {
e.printStackTrace();
}
}
public PiwikStatistics(final Properties settings) {
init(settings);
}
private void init(final Properties settings) {
try {
String url = settings.getProperty("piwik_url");
if (url.isEmpty()) {
apiUrl = null;
return;
}
apiUrl = new URL(url);
idSite = Integer.parseInt(settings.getProperty("piwik_site_id"));
String seconds = settings.getProperty("stats_interval");
if (seconds != null && !seconds.isEmpty())
wait = Long.parseLong(seconds) * TICKS_PER_SECOND;
} catch (MalformedURLException e) {
throw new IllegalArgumentException("Invalid Piwik-URL defined", e);
}
}
public static String getUniqueID() {
return String.format("%016x", UUID.randomUUID().getMostSignificantBits());
}
public void register(final Plugin rplugin) {
if (apiUrl == null)
return;
plugin = rplugin;
//plugin.getServer().getPluginManager().registerEvents(new StatsListener(), plugin);
pluginname = plugin.getName();
version = plugin.getDescription().getVersion();
plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, new Runnable() {
@Override
public void run() {
// Well, we all know it isn't http, but as piwik is a website tracking, it doesn't tracks the url if it isn't a http url ;)
server = "http://" + StatsUtils.getIP(plugin.getServer()) + ":" + plugin.getServer().getPort();
servername = ChatColor.stripColor(plugin.getServer().getServerName().replace(SEPERATOR, "-"));
servermotd = ChatColor.stripColor(plugin.getServer().getMotd().replace(SEPERATOR, "-").replaceAll("\\s+", " "));
trackEnable();
}
}, wait);
plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
@Override
public void run() {
final int playercount = plugin.getServer().getOnlinePlayers().length;
if (playercount > 0) {
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() {
@Override
public void run() {
trackOnlineUsage(playercount);
}
});
}
}
}, wait, wait);
}
private void trackEnable() {
Plugin[] pluginlist = plugin.getServer().getPluginManager().getPlugins();
List<String[]> cdata = new ArrayList<String[]>();
cdata.add(new String[]{"Server-Name", servername});
cdata.add(new String[]{"Server-Version", (plugin.getServer().getName() + " " + plugin.getServer().getVersion())});
cdata.add(new String[]{"Plugin-Version", pluginname + " " + version});
Stack<StringBuilder> plugins = new Stack<StringBuilder>();
plugins.add(new StringBuilder(""));
for (Plugin cplugin : pluginlist) {
StringBuilder currentPlugins = plugins.lastElement();
if ((currentPlugins.length() + cplugin.getName().length() + 1) > MAX_CVAR_SIZE) {
plugins.add(new StringBuilder());
currentPlugins = plugins.lastElement();
}
if (currentPlugins.length() > 0)
currentPlugins.append(",");
currentPlugins.append(cplugin.getName());
}
for (int i = 0; i < plugins.size(); i++) {
String plname = i == 0 ? "Plugins" : ("Plugins " + (i + 1));
cdata.add(new String[]{plname, plugins.get(i).toString()});
}
cdata.add(new String[]{"Mode", plugin.getServer().getOnlineMode() ? "Online" : "Offline"});
JSONObject cvar = getCVar(cdata.toArray(new String[cdata.size()][]));
String[][] args = new String[][]{
{"action_name", servermotd},
{PIWIK_FIELD_CVAR, cvar.toJSONString()}
};
track(server + SEPERATOR + pluginname + "/load", args);
}
private void trackOnlineUsage(final int playercount) {
List<String[]> cdata = new ArrayList<String[]>();
cdata.add(new String[]{"Online-Count", Integer.toString(playercount)});
if (!plugin.getServer().getOnlineMode())
cdata.add(new String[]{"Offline-Mode", "yes"});
JSONObject cvar = getCVar(cdata.toArray(new String[cdata.size()][]));
track(server + SEPERATOR + pluginname + "/usage", new String[][]{
{"multiple", Integer.toString(playercount)}, // handled by piwikProxy.php to create a Batch-Request to simulate multiple hits
{PIWIK_FIELD_CVAR, cvar.toJSONString()}
});
}
@SuppressWarnings("unchecked")
public static JSONObject getCVar(final String[][] cvars) {
JSONObject cvar = new JSONObject();
for (int i = 0; i < cvars.length; i++) {
JSONArray t = new JSONArray();
t.add(cvars[i][0]);
t.add(cvars[i][1]);
cvar.put(Integer.toString(i + 1), t);
}
return cvar;
}
protected void track(final String target, final String[][] addargs) {
String[][] basicargs = new String[][]{
{"idsite", Integer.toString(idSite)},
{"rec", "1"},
{"url", target},
{"_id", serverid},
{"rand", Long.toString(System.currentTimeMillis())},
{"apiv", Integer.toString(APIV)},
};
String[][] arguments;
if (addargs.length > 0) {
arguments = new String[basicargs.length + addargs.length][2];
System.arraycopy(basicargs, 0, arguments, 0, basicargs.length);
System.arraycopy(addargs, 0, arguments, basicargs.length, addargs.length);
} else {
arguments = basicargs;
}
try {
URL req = StatsUtils.buildRequest(apiUrl, arguments);
URLConnection conn = req.openConnection();
//System.out.println(req.toString());
conn.setUseCaches(false);
conn.connect();
InputStream in = conn.getInputStream();
in.read();
in.close();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/*class StatsListener implements Listener {
@EventHandler
public void onJoin(final PlayerJoinEvent event) {
plugin.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, new Runnable() {
@Override
public void run() {
track(server + SEPERATOR + pluginname + "/join", new String[0][0]);
}
});
}
}*/
@Override
public void trackEvent(final String event) {
track(server + SEPERATOR + pluginname + SEPERATOR + event, new String[0][0]);
}
}

View file

@ -1,58 +0,0 @@
package de.jaschastarke.bukkit.tools.stats;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import org.bukkit.Server;
public final class StatsUtils {
private static final String ENCODING = "UTF-8";
private StatsUtils() {
}
public static String getIP(final Server server) {
String ip = server.getIp();
if (ip.isEmpty()) {
try {
URL getip = new URL("http://checkip.amazonaws.com/");
BufferedReader in = new BufferedReader(new InputStreamReader(getip.openStream()));
ip = in.readLine();
in.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return ip;
}
public static String enc(final String s) {
try {
return URLEncoder.encode(s, ENCODING);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return s;
}
public static URL buildRequest(final URL url, final String[][] arguments) {
StringBuilder u = new StringBuilder(url.toString());
for (int i = 0; i < arguments.length; i++) {
u.append(i == 0 ? "?" : "&");
u.append(arguments[i][0]);
u.append("=");
u.append(enc(arguments[i][1]));
}
try {
return new URL(u.toString());
} catch (MalformedURLException e) {
throw new IllegalArgumentException("Arguments couldn't build to a new URL");
}
}
}

View file

@ -1,89 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.integration;
//import java.util.HashMap;
//import java.util.Map;
import static de.jaschastarke.minecraft.utils.Util.compareVersion;
//import org.bukkit.event.EventHandler;
//import org.bukkit.event.Listener;
/*import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.event.server.PluginEnableEvent;*/
import org.bukkit.plugin.java.JavaPlugin;
abstract public class AbstractCommunicator /*implements Listener*/ {
protected JavaPlugin plugin;
//private Map<Class<?>, CommunicationBridge> bridges = new HashMap<Class<?>, CommunicationBridge>();
public AbstractCommunicator(JavaPlugin plugin) {
this.plugin = plugin;
//plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
protected boolean isPluginEnabled(String plugin) {
return this.plugin.getServer().getPluginManager().isPluginEnabled(plugin);
}
protected boolean isPluginEnabled(String plugin, String minVersion) {
if (isPluginEnabled(plugin)) {
String ver = this.plugin.getServer().getPluginManager().getPlugin(plugin).getDescription().getVersion();
return compareVersion(ver, minVersion) > 0;
}
return false;
}
/*@SuppressWarnings("unchecked")
protected <T extends CommunicationBridge> T getBridge(Class<T> cls) {
if (!bridges.containsKey(cls)) {
try {
bridges.put(cls, cls.newInstance());
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return (T) bridges.get(cls);
}*/
/*@EventHandler
public void onPluginEnable(PluginEnableEvent event) {
}
@EventHandler
public void onPluginDisable(PluginDisableEvent event) {
}
protected <T extends CommunicationBridge> boolean isPluginEnabled(String plugin, Class<T> cls) {
if (!bridges.containsKey(plugin)) {
if (this.plugin.getServer().getPluginManager().isPluginEnabled(plugin)) {
} else {
bridges.put(plugin, null);
}
}
return bridges.get(plugin) != null;
}
protected
protected <T extends CommunicationBridge> T whenPluginEnabled(String plugin, Class<T> cls) {
if (isPluginEnabled(plugin)) {
}
}*/
}

View file

@ -1,37 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.integration;
import org.bukkit.entity.Player;
import uk.org.whoami.authme.cache.auth.PlayerCache;
import uk.org.whoami.authme.cache.limbo.LimboCache;
import de.jaschastarke.minecraft.limitedcreative.Core;
public class AuthMe implements CommunicationBridge {
public static boolean isLoggedIn(Player player) {
boolean li = PlayerCache.getInstance().isAuthenticated(player.getName().toLowerCase());
Core.debug("AuthMe: "+player.getName()+": logged in: "+li);
return li;
}
public static boolean isLoggedInComplete(Player player) {
boolean li = isLoggedIn(player) && LimboCache.getInstance().getLimboPlayer(player.getName().toLowerCase()) == null;
Core.debug("AuthMe: "+player.getName()+": logged in complete: "+li);
return li;
}
}

View file

@ -1,51 +0,0 @@
package de.jaschastarke.minecraft.integration;
import org.bukkit.GameMode;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.plugin.java.JavaPlugin;
import uk.org.whoami.authme.events.RestoreInventoryEvent;
import uk.org.whoami.authme.events.StoreInventoryEvent;
import de.jaschastarke.minecraft.limitedcreative.Core;
import de.jaschastarke.minecraft.limitedcreative.LCPlayer;
import de.jaschastarke.minecraft.limitedcreative.Players;
public class AuthMeInventories implements Listener {
public AuthMeInventories(JavaPlugin plugin) {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@EventHandler
public void onStoreInventory(StoreInventoryEvent event) {
Core.debug("AuthMe Store Event: "+event.getPlayer().getName());
LCPlayer player = Players.get(event.getPlayer());
event.getPlayer().closeInventory();
GameMode cgm = event.getPlayer().getGameMode();
if (cgm == GameMode.ADVENTURE && !Core.plugin.config.getAdventureInv())
cgm = GameMode.SURVIVAL;
if (cgm != GameMode.CREATIVE || Core.plugin.config.getStoreCreative()) {
player.getInv().save(cgm);
}
}
@EventHandler
public void onRestoreInventory(RestoreInventoryEvent event) {
Core.debug("AuthMe Restore Event: "+event.getPlayer().getName());
LCPlayer player = Players.get(event.getPlayer());
event.getPlayer().closeInventory();
GameMode cgm = event.getPlayer().getGameMode();
if (cgm == GameMode.ADVENTURE && !Core.plugin.config.getAdventureInv())
cgm = GameMode.SURVIVAL;
if (player.getInv().isStored(cgm)) {
player.getInv().load(cgm);
event.setCancelled(true);
}
}
}

View file

@ -1,21 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.integration;
public interface CommunicationBridge {
}

View file

@ -1,78 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.integration;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import de.jaschastarke.minecraft.limitedcreative.Core;
public class Communicator extends AbstractCommunicator {
public Communicator(JavaPlugin plugin) {
super(plugin);
}
public boolean isLoggedIn(Player player) {
if (isPluginEnabled("AuthMe") && !AuthMe.isLoggedIn(player))
return false;
if (isPluginEnabled("xAuth") && !xAuth.isLoggedInNotGuest(player))
return false;
return true;
}
public boolean isLoggedInComplete(Player player) {
if (isPluginEnabled("AuthMe") && !AuthMe.isLoggedInComplete(player))
return false;
return true;
}
public void hookAuthInvs() {
if (isPluginEnabled("AuthMe", "2.7.0b2")) {
new AuthMeInventories(this.plugin);
}
}
public boolean isCreative(World world) {
boolean creative = Bukkit.getServer().getDefaultGameMode() == GameMode.CREATIVE;
if (isMultiVerse()) {
GameMode tmp = MultiVerse.getGameMode(world);
if (tmp != null)
creative = tmp == GameMode.CREATIVE;
}
Core.debug("com: "+world.getName()+": is creative: "+creative);
return creative;
}
public GameMode getDefaultGameMode(World world) {
GameMode def = Bukkit.getServer().getDefaultGameMode();
if (isMultiVerse()) {
GameMode tmp = MultiVerse.getGameMode(world);
if (tmp != null)
def = tmp;
}
Core.debug("com: "+world.getName()+": game mode: "+def);
return def;
}
public boolean isMultiVerse() {
return isPluginEnabled("Multiverse-Core");
}
}

View file

@ -1,42 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.integration;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.World;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import de.jaschastarke.minecraft.limitedcreative.Core;
public class MultiVerse implements CommunicationBridge {
public static GameMode getGameMode(World world) {
MultiverseWorld mvWorld = getMV().getMVWorldManager().getMVWorld(world);
if (mvWorld == null)
return null;
GameMode gm = mvWorld.getGameMode();
Core.debug("Multiverse: "+world.getName()+": game mode: "+gm);
return gm;
}
private static MultiverseCore getMV() {
return (MultiverseCore) Bukkit.getServer().getPluginManager().getPlugin("Multiverse-Core");
}
}

View file

@ -1,42 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.integration;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import com.cypherx.xauth.xAuthPlayer;
import de.jaschastarke.minecraft.limitedcreative.Core;
public class xAuth implements CommunicationBridge {
public static boolean isLoggedInNotGuest(Player player) {
xAuthPlayer xpl = getAuth().getPlayerManager().getPlayer(player);
boolean li = true;
if (!xpl.isAuthenticated())
li = false;
else if (xpl.isGuest())
li = false;
Core.debug("xAuth: "+player.getName()+": logged in not guest: "+li);
return li;
}
private static com.cypherx.xauth.xAuth getAuth() {
return (com.cypherx.xauth.xAuth) Bukkit.getServer().getPluginManager().getPlugin("xAuth");
}
}

View file

@ -1,80 +0,0 @@
package de.jaschastarke.minecraft.limitedcreative;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.MaterialData;
abstract public class BlackList {
abstract public boolean matches(Block b);
abstract public boolean matches(ItemStack item);
public static boolean isBlackListed(List<BlackList> list, Block block) {
for (BlackList bl : list) {
if (bl.matches(block))
return true;
}
return false;
}
public static boolean isBlackListed(List<BlackList> list, ItemStack item) {
for (BlackList bl : list) {
if (bl.matches(item))
return true;
}
return false;
}
public static class Some extends BlackList {
private Material mat;
private int data = -1;
public Some(Material material, int data) {
mat = material;
this.data = data;
}
public Some(Material material) {
mat = material;
}
public Some(MaterialData md) {
mat = md.getItemType();
if (md.getData() != 0)
this.data = md.getData();
}
public boolean matches(Block block) {
if (this.mat == null)
return true;
if (this.mat != block.getType())
return false;
if (this.data != -1 && this.data != block.getData())
return false;
return true;
}
public boolean matches(ItemStack item) {
if (this.mat == null)
return true;
if (this.mat != item.getType())
return false;
if (this.data != -1) {
if (this.mat == Material.MONSTER_EGG) {
if (this.data != item.getDurability())
return false;
} else {
if (this.data != item.getData().getData())
return false;
}
}
return true;
}
}
public static class All extends BlackList {
public boolean matches(Block b) {
return true;
}
public boolean matches(ItemStack item) {
return true;
}
}
}

View file

@ -1,229 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.limitedcreative;
import static de.jaschastarke.minecraft.utils.Locale.L;
import java.util.Arrays;
import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import de.jaschastarke.minecraft.utils.IPermission;
import de.jaschastarke.minecraft.utils.Util;
public class Commands {
private static Core plugin;
public static class MainCommandExecutor implements CommandExecutor {
public enum Action {
C, CREATIVE,
S, SURVIVAL,
A, ADVENTURE,
E, ENABLE,
D, DISABLE,
R, REGION,
RELOAD
};
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
Core.debug(sender.getName() + ": /" + label + " " + Util.join(args));
if (args.length > 0) {
Action act = null;
try {
act = Action.valueOf(args[0].toUpperCase());
} catch (IllegalArgumentException e) {}
if (act != null) {
try {
switch (act) {
case C:
case CREATIVE:
this.setGameMode(GameMode.CREATIVE, sender, args);
return true;
case S:
case SURVIVAL:
this.setGameMode(GameMode.SURVIVAL, sender, args);
return true;
case A:
case ADVENTURE:
this.setGameMode(GameMode.ADVENTURE, sender, args);
return true;
case E:
case ENABLE:
this.setOption(sender, args, true);
return true;
case D:
case DISABLE:
this.setOption(sender, args, false);
return true;
case R:
case REGION:
args = Arrays.copyOfRange(args, 1, args.length);
plugin.getCommand("/region").execute(sender, "/region", args);
return true;
case RELOAD:
//plugin.getServer().getPluginManager().disablePlugin(plugin); // disable removes classloader, so re-enabling causes problems
//plugin.getServer().getPluginManager().enablePlugin(plugin);
plugin.reload();
return true;
}
} catch (CommandException e) {
Core.debug("CommandException: "+e.getMessage());
sender.sendMessage(ChatColor.DARK_RED + e.getLocalizedMessage());
return true;
}
}
}
String c = label;
StringBuilder message = new StringBuilder();
message.append("/"+c+" s[urvival] ["+L("command.player")+"] - "+L("command.switch.survival")+"\n");
message.append("/"+c+" c[reative] ["+L("command.player")+"] - "+L("command.switch.creative")+"\n");
message.append("/"+c+" a[dventure] ["+L("command.player")+"] - "+L("command.switch.adventure")+"\n");
if (hasPermission(sender, Perms.CONFIG)) {
message.append("/"+c+" e[nable] "+L("command.config.overview")+"\n");
message.append("/"+c+" d[isable] "+L("command.config.overview")+"\n");
message.append("/"+c+" reload "+L("command.config.reload")+"\n");
}
if (hasPermission(sender, Perms.REGIONS))
message.append("/"+c+" r[egion] "+L("command.worldguard.alias")+"\n");
if (message.length() > 0) {
sender.sendMessage("Usage:");
for (String m : message.toString().split("\n")) {
sender.sendMessage(m);
}
return true;
}
return false;
}
private void setOption(CommandSender sender, String[] args, boolean b) throws CommandException {
if (sender instanceof Player && !hasPermission(sender, Perms.CONFIG)) {
throw new LackingPermissionException();
}
if (args.length > 2)
throw new InvalidCommandException("exception.command.tomuchparameter");
if (args.length < 2) {
StringBuilder str = new StringBuilder(L("command.config.settings"));
List<Configuration.Option> options = Configuration.Option.getAvailableOptions();
for (int i = 0; i < options.size(); i++) {
str.append(options.get(i).name().toLowerCase());
if (i < options.size() - 1)
str.append(", ");
if ((i - 1) % 4 == 0) {
sender.sendMessage(str.toString());
str = new StringBuilder();
}
}
if (str.length() > 0)
sender.sendMessage(str.toString());
return;
}
Configuration.Option opt = null;
try {
opt = Configuration.Option.valueOf(args[1].toUpperCase());
} catch (IllegalArgumentException e) {
throw new InvalidCommandException("exception.command.invalidoption");
}
plugin.config.set(opt, b);
sender.sendMessage(L("command.option.done"));
}
private void setGameMode(GameMode gm, CommandSender sender, String[] args) throws CommandException {
Player target = null;
if (args.length > 2)
throw new InvalidCommandException("exception.command.tomuchparameter");
if (args.length == 2)
target = plugin.getServer().getPlayer(args[1]);
else if (sender instanceof Player)
target = (Player) sender;
if (target == null) {
throw new InvalidCommandException("exception.command.playernotfound");
} else if (sender instanceof Player && sender != target && !hasPermission(sender, Perms.GM_OTHER)) {
throw new LackingPermissionException();
} else if (target.getGameMode() != gm) {
if ((hasPermission(sender, Perms.GM)) ||
Players.get(target).isGameModeAllowed(gm) ||
(gm == plugin.com.getDefaultGameMode(target.getWorld()) && hasPermission(sender, Perms.GM_BACKONLY)) ||
(gm == GameMode.CREATIVE && hasPermission(sender, Perms.GM_CREATIVE)) ||
(gm == GameMode.SURVIVAL && hasPermission(sender, Perms.GM_SURVIVAL)) ||
(gm == GameMode.ADVENTURE && hasPermission(sender, Perms.GM_ADVENTURE))) {
target.setGameMode(gm);
} else {
throw new LackingPermissionException();
}
if (target != sender) {
sender.sendMessage(L("command.gamemode.changed", target.getName()));
}
} else {
sender.sendMessage(L("command.gamemode.no_change"));
}
}
}
public static class NotAvailableCommandExecutor implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
sender.sendMessage(ChatColor.DARK_RED + L("command.worldguard.no_integration"));
return true;
}
}
public static void register(Core pplugin) {
plugin = pplugin;
plugin.getCommand("limitedcreative").setExecutor(new MainCommandExecutor());
if (plugin.worldguard == null) {
plugin.getCommand("/region").setExecutor(new NotAvailableCommandExecutor());
}
}
private static boolean hasPermission(CommandSender sender, IPermission permission) {
return plugin.perm.hasPermission(sender, permission);
}
abstract static public class CommandException extends Exception {
private static final long serialVersionUID = 1L;
public CommandException(String s) {super(s);}
@Override
public String getLocalizedMessage() {
return L(super.getLocalizedMessage());
}
}
public static class InvalidCommandException extends CommandException {
private static final long serialVersionUID = 1L;
public InvalidCommandException(String s) {super(s);}
}
public static class LackingPermissionException extends CommandException {
private static final long serialVersionUID = 1L;
public LackingPermissionException() {super("exception.command.lackingpermission");}
}
}

View file

@ -1,312 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.limitedcreative;
import static de.jaschastarke.minecraft.utils.Locale.L;
import static de.jaschastarke.minecraft.utils.Util.copyFile;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.material.MaterialData;
import de.jaschastarke.minecraft.limitedcreative.cmdblock.ICmdBlockEntry;
import de.jaschastarke.minecraft.limitedcreative.cmdblock.RegexpBlockEntry;
import de.jaschastarke.minecraft.limitedcreative.cmdblock.StringBlockEntry;
import de.jaschastarke.minecraft.limitedcreative.store.InvYamlStorage;
import de.jaschastarke.minecraft.limitedcreative.store.PlayerInventoryStorage;
public class Configuration {
private FileConfiguration c;
private File file;
public static Core plugin;
public enum Option {
STORECREATIVE("store.creative", true),
CREATIVEARMOR("store.armor.enabled", true),
ADVENTUREINV("store.adventure", false),
REGION_OPTIONAL("region.optional", true),
REGION_REMEMBER("region.remember", false),
REGION_SAFEMODE("region.safemode", false),
BLOCKPICKUP("limit.pickup", true),
BLOCKSIGN("limit.sign", true),
BLOCKBUTTON("limit.button", false),
BLOCKDAMAGEMOB("limit.damagemob", false),
BLOCKBENCHES("limit.workbench", false),
REMOVEDROP("limit.remove_drops", true),
REMOVEPICKUP("limit.remove_pickup", false),
PERM_WEPIF("permissions.wepif", true),
CMDBLOCKER("cmdblocker.enabled", true),
METRICS("metrics", true),
DEBUG("debug", false);
private String key;
private boolean _default;
private Option(String key, boolean def) {
this.key = key;
this._default = def;
}
public String getKey() {
return key;
}
public boolean getDefault() {
return _default;
}
public static List<Option> getAvailableOptions() {
List<Option> ret = new ArrayList<Option>(Arrays.asList(Option.values()));
ret.remove(Option.DEBUG); // keep it undocumented ;)
return ret;
}
}
public Configuration(Core pplugin) {
plugin = pplugin;
file = new File(plugin.getDataFolder(), "config.yml");
if (!file.exists())
//plugin.saveDefaultConfig();
copyFile(plugin.getResource("config.yml"), file);
c = plugin.getConfig();
}
public void set(Option opt, boolean value) {
/*if (!opt.isSetAble())
throw new IllegalArgumentException("Setting this option is not allowed");*/
this.reload();
c.set(opt.getKey(), value);
this.save();
}
public boolean getBoolean(Option opt) {
return c.getBoolean(opt.getKey(), opt.getDefault());
}
/**
* Intended to be undocumented ;)
*/
public boolean getDebug() {
return this.getBoolean(Option.DEBUG);
}
public boolean getStoreEnabled() {
return getTempStoreEnabled() && c.getBoolean("store.enabled", true);
}
public boolean getLimitEnabled() {
return c.getBoolean("limit.enabled", true);
}
public boolean getRegionEnabled() {
return c.getBoolean("region.enabled", true);
}
public boolean getStoreCreative() {
return this.getBoolean(Option.STORECREATIVE);
}
/*public boolean getUnsafeStorage() {
return c.getBoolean("store.unsafe", false);
}*/
public String getInventoryFolder() {
return c.getString("store.folder", "inventories");
}
public boolean getAdventureInv() {
return this.getBoolean(Option.ADVENTUREINV);
}
public boolean getBlockPickupInCreative() {
return this.getBoolean(Option.BLOCKPICKUP);
}
public boolean getSignBlock() {
return this.getBoolean(Option.BLOCKSIGN);
}
public boolean getBenchBlock() {
return this.getBoolean(Option.BLOCKBENCHES);
}
public boolean getButtonBlock() {
return this.getBoolean(Option.BLOCKBUTTON);
}
public boolean getRemoveDrop() {
return this.getBoolean(Option.REMOVEDROP);
}
public boolean getRemovePickup() {
return this.getBoolean(Option.REMOVEPICKUP);
}
public boolean getMobDamageBlock() {
return this.getBoolean(Option.BLOCKDAMAGEMOB);
}
public boolean getWEPIFEnabled() {
return this.getBoolean(Option.PERM_WEPIF);
}
public boolean getRegionOptional() {
return this.getBoolean(Option.REGION_OPTIONAL);
}
public boolean getRegionRememberOptional() {
return this.getRegionOptional() && this.getBoolean(Option.REGION_REMEMBER);
}
public boolean getRegionSafeMode() {
return this.getBoolean(Option.REGION_SAFEMODE);
}
public String getLocale() {
if (c.contains("locale") && c.getString("locale") != "none")
return c.getString("locale");
return null;
}
protected void reload() {
_block_break = null;
_block_use = null;
plugin.reloadConfig();
c = plugin.getConfig();
}
protected void save() {
plugin.saveConfig();
}
private List<BlackList> _block_break = null;
private List<BlackList> _block_use = null;
public List<BlackList> getBlockedBreaks() {
if (_block_break == null)
_block_break = parseMaterialList(c.getStringList("limit.break"));
return _block_break;
}
public List<BlackList> getBlockedUse() {
if (_block_use == null)
_block_use = parseMaterialList(c.getStringList("limit.use"));
return _block_use;
}
private List<BlackList> parseMaterialList(List<String> s) {
List<BlackList> list = new ArrayList<BlackList>();
if (s != null) {
for (String m : s) {
if (m.equals("*")) {
list.clear();
list.add(new BlackList.All());
break;
} else {
MaterialData md = parseMaterial(m);
if (md != null)
list.add(new BlackList.Some(md));
}
}
}
return list;
}
private MaterialData parseMaterial(String m) {
int d = -1;
if (m.contains(":")) {
String[] t = m.split(":");
m = t[0];
try {
d = Integer.parseInt(t[1]);
} catch (NumberFormatException ex) {
// TODO: try to find the data value by
if (d == -1)
plugin.warn(L("exception.config.materiak_data_not_found", t[1]));
}
}
Material e = null;
try {
e = Material.getMaterial(Integer.parseInt(m));
} catch (NumberFormatException ex) {
e = Material.matchMaterial(m);
}
if (e == null) {
plugin.warn(L("exception.config.material_not_found", m));
return null;
}
if (d != -1)
return new MaterialData(e, (byte) d);
else
return new MaterialData(e);
}
private boolean _store_enabled = true;
public void setTempStoreEnabled(boolean b) {
_store_enabled = b;
}
public boolean getTempStoreEnabled() {
return _store_enabled;
}
/**
* @return Milliseconds
*/
public long getRepeatingMessageTimeout() {
return 10000; // 10 sec. limit
}
/**
* The maximum height a player may fall down by leaving creative gamemode
* @return Block-Height
*/
public int getMaximumFloatingHeight() {
return 3;
}
public PlayerInventoryStorage getInvetoryStorage() {
return new InvYamlStorage(new File(plugin.getDataFolder(), getInventoryFolder()));
}
public Map<String, MaterialData> getCreativeArmor() {
if (c.contains("store.armor") && c.isConfigurationSection("store.armor")) {
ConfigurationSection sect = c.getConfigurationSection("store.armor");
if (sect.getBoolean("enabled")) {
Map<String, MaterialData> armor = new HashMap<String, MaterialData>();
for (Map.Entry<String, Object> entry : sect.getValues(false).entrySet()) {
if (!entry.getKey().equals("enabled")) {
MaterialData md = parseMaterial((String) entry.getValue());
if (md != null)
armor.put(entry.getKey(), md);
}
}
return armor;
}
}
return null;
}
public boolean getCommandBlockerEnabled() {
return this.getBoolean(Option.CMDBLOCKER);
}
private List<ICmdBlockEntry> _blocklist = null;
public List<ICmdBlockEntry> getCommandBlockList() {
if (_blocklist == null) {
_blocklist = new ArrayList<ICmdBlockEntry>();
for (String cmd : c.getStringList("cmdblock.commands")) {
if (cmd.startsWith("^")) {
_blocklist.add(new RegexpBlockEntry(cmd));
} else {
_blocklist.add(new StringBlockEntry(cmd));
}
}
}
return _blocklist;
}
}

View file

@ -1,151 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.limitedcreative;
import static de.jaschastarke.minecraft.utils.Locale.L;
import java.util.logging.Logger;
import org.bukkit.event.HandlerList;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.java.JavaPlugin;
import de.jaschastarke.bukkit.tools.stats.PiwikStatistics;
import de.jaschastarke.minecraft.integration.Communicator;
import de.jaschastarke.minecraft.limitedcreative.Configuration.Option;
import de.jaschastarke.minecraft.limitedcreative.cmdblock.CommandBlocker;
import de.jaschastarke.minecraft.limitedcreative.listeners.LimitListener;
import de.jaschastarke.minecraft.limitedcreative.listeners.MainListener;
import de.jaschastarke.minecraft.limitedcreative.regions.WorldGuardIntegration;
import de.jaschastarke.minecraft.utils.Locale;
import de.jaschastarke.minecraft.utils.Permissions;
public class Core extends JavaPlugin {
public final Logger logger = Logger.getLogger("Minecraft");
public Configuration config;
public Permissions perm;
public WorldGuardIntegration worldguard;
public Communicator com;
public static Core plugin;
public NoBlockItemSpawn spawnblock;
public CommandBlocker cmdblock;
@Override
public void onDisable() {
plugin.getServer().getScheduler().cancelTasks(this);
if (worldguard != null)
worldguard.unload();
try {
Locale.unload();
} catch (NoClassDefFoundError e) {} // prevent unload issue
plugin = null;
worldguard = null;
config = null;
spawnblock = null;
com = null;
cmdblock = null;
}
@Override
public void onEnable() {
plugin = this;
config = new Configuration(this);
perm = new Permissions(this);
com = new Communicator(this);
new Locale(this, config.getLocale());
spawnblock = new NoBlockItemSpawn();
// 1st Feature: Separated Inventories Storage
if (config.getStoreEnabled() && getServer().getPluginManager().isPluginEnabled("MultiInv")) {
warn(L("basic.conflict", "MultiInv", L("basic.feature.store")));
config.setTempStoreEnabled(false);
} else if (config.getStoreEnabled() && getServer().getPluginManager().isPluginEnabled("Multiverse-Inventories")) {
warn(L("basic.conflict", "Multiverse-Inventories", L("basic.feature.store")));
config.setTempStoreEnabled(false);
}
if (config.getStoreEnabled()) {
com.hookAuthInvs();
}
getServer().getPluginManager().registerEvents(new MainListener(this), this);
// 2nd Feature: Creative Limitations (Restrictions)
if (config.getLimitEnabled())
getServer().getPluginManager().registerEvents(new LimitListener(this), this);
// 3rd Feature: WorldGuard Region-Support
if (config.getRegionEnabled() && getServer().getPluginManager().isPluginEnabled("WorldGuard")) {
worldguard = new WorldGuardIntegration(this);
} else if(config.getRegionEnabled()) {
warn(L("basic.warning.worldguard_not_found", L("basic.feature.region")));
}
// 4th Feature: Command Blocker
if (config.getCommandBlockerEnabled())
cmdblock = new CommandBlocker(this);
debug("Store: " + config.getStoreEnabled());
debug("Limit: " + config.getLimitEnabled());
debug("Region: " + (worldguard != null));
debug("CmdBlock: " + config.getCommandBlockerEnabled());
Commands.register(this);
if (config.getBoolean(Option.METRICS))
new PiwikStatistics(this);
/*plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
@Override
public void run() {
Players.cleanUp();
}
}, Players.CLEANUP_TIMEOUT / 50L, Players.CLEANUP_TIMEOUT / 50L); // 50 = 1000ms / 20ticks*/
PluginDescriptionFile df = this.getDescription();
if (worldguard != null)
logger.info("["+df.getName() + " v" + df.getVersion() + "] "+L("basic.loaded.worldguard"));
else
logger.info("["+df.getName() + " v" + df.getVersion() + "] "+L("basic.loaded.no_worldguard"));
}
public void reload() {
getServer().getScheduler().cancelTasks(this);
getServer().getServicesManager().unregisterAll(this);
HandlerList.unregisterAll(this);
setEnabled(false);
setEnabled(true);
}
public void info(String s) {
logger.info("["+this.getDescription().getName()+"] " + s);
}
public void warn(String s) {
logger.warning("["+this.getDescription().getName()+"] " + s);
}
public void error(String s) {
logger.severe("["+this.getDescription().getName()+"] " + s);
}
public static void debug(String s) {
if (isDebug())
plugin.info("DEBUG: " + s);
}
public static boolean isDebug() {
return plugin.config.getDebug();
}
}

View file

@ -1,539 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.limitedcreative;
import static de.jaschastarke.minecraft.utils.Locale.L;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Creature;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.Lever;
import org.bukkit.material.MaterialData;
import de.jaschastarke.minecraft.utils.IPermission;
import de.jaschastarke.minecraft.worldguard.events.PlayerAreaEvent;
import de.jaschastarke.minecraft.worldguard.events.PlayerChangedAreaEvent;
public class LCPlayer {
private static Core plugin = Core.plugin;
private Player player;
//private String name;
private Inventory _inv;
private GameMode _permanent_gamemode = null;
//private long _timestamp;
public LCPlayer(Player player) {
this.player = player;
//name = player.getName();
//touch();
if (!this.isActiveRegionGameMode(player.getGameMode()) && plugin.com.isLoggedInComplete(getPlayer())) {
setInPermanentGameMode(player.getGameMode());
}
}
public void updatePlayer(Player player) {
this.player = player;
}
public Player getPlayer() {
return player;
//return plugin.getServer().getPlayerExact(name); (doesn't work will revive)
}
public String getName() {
return player.getName();
}
public Inventory getInv() {
if (_inv == null)
_inv = new Inventory(this);
return _inv;
}
/*public void touch() {
_timestamp = System.currentTimeMillis();
}
public boolean isOutdated() {
return (getPlayer() == null || !getPlayer().isOnline()) &&
_timestamp < (System.currentTimeMillis() - Players.CLEANUP_TIMEOUT);
}*/
private Map<String, Object> options = new HashMap<String, Object>();
public void storeActiveRegionGameMode(final GameMode gm) {
options.remove("region");
Core.debug(getName()+": set region game mode: " + gm);
Players.getOptions().setRegionGameMode(getName(), gm);
}
public GameMode getActiveRegionGameMode() {
if (!options.containsKey("region")) {
options.put("region", Players.getOptions().getRegionGameMode(getName()));
}
Core.debug(getName()+": get region game mode: " + options.get("region"));
return (GameMode) options.get("region");
}
public boolean isActiveRegionGameMode(final GameMode gm) {
return gm.equals(getActiveRegionGameMode());
}
public boolean isActiveRegionGameMode() {
return getActiveRegionGameMode() != null;
}
public boolean isOptionalRegionGameMode() {
return getOptionalRegionGameMode() != null;
}
public boolean isOptionalRegionGameMode(final GameMode gm) {
return gm.equals(getOptionalRegionGameMode());
}
public boolean isOptionalRegionGameMode(final String region, final GameMode gm) {
return gm.equals(getOptionalRegionGameMode(region));
}
private GameMode getOptionalRegionGameMode() {
String region = plugin.worldguard.getRegionManager().getRegionsHash(getPlayer().getLocation());
return getOptionalRegionGameMode(region);
}
private GameMode getOptionalRegionGameMode(String region) {
if (!plugin.config.getRegionRememberOptional())
return null;
if (!options.containsKey("region_opt#"+region)) {
options.put("region_opt#"+region, Players.getOptions().getOptionalRegionGameMode(getName(), region));
}
Core.debug(getName()+": get optional region game mode: "+region+" - " + options.get("region_opt#"+region));
return (GameMode) options.get("region_opt#"+region);
}
public void setOptionalRegionGameMode(GameMode gm) {
String region = plugin.worldguard.getRegionManager().getRegionsHash(getPlayer().getLocation());
setOptionalRegionGameMode(region, gm);
}
public void setOptionalRegionGameMode(String region, GameMode gm) {
if (!plugin.config.getRegionRememberOptional())
return;
options.remove("region_opt#"+region);
Core.debug(getName()+": set optional region game mode: "+region+" - " + gm);
Players.getOptions().setOptionalRegionGameMode(getName(), region, gm);
}
public void setInPermanentGameMode(GameMode temp) {
Core.debug(getName()+": set permanent game mode: " + temp);
if (temp != null) {
if (temp.equals(plugin.com.getDefaultGameMode(getPlayer().getWorld()))) {
temp = null;
} else {
storeActiveRegionGameMode(null);
}
}
_permanent_gamemode = temp;
}
public boolean isInPermanentGameMode() {
if (plugin.config.getRegionSafeMode())
return false;
return isInPermanentGameMode(getPlayer().getGameMode());
}
public boolean isInPermanentGameMode(GameMode temp) {
if (plugin.config.getRegionSafeMode())
return false;
Core.debug(getName()+": get permanent game mode: " + _permanent_gamemode);
return temp.equals(_permanent_gamemode);
}
public boolean onSetGameMode(GameMode gm) {
Core.debug(getName() + " going into " + gm);
if (plugin.com.isLoggedInComplete(getPlayer())) { // if authme is changing GameMode before going to teleport, this should be remembered
if (isActiveRegionGameMode()) { // change to the other gamemode as the area defines
if (!isActiveRegionGameMode(gm)) { // only when we are not switching to the mode the region allows
if (!plugin.config.getRegionOptional() && !hasPermission(Perms.REGIONS_BYPASS)) {
getPlayer().sendMessage(ChatColor.RED + L("exception.region.not_optional", gm.toString().toLowerCase()));
Core.debug("... denied");
return false;
} else {
setOptionalRegionGameMode(gm);
}
} else {
// we are changing to the mode the region defines, thats not permanent
setOptionalRegionGameMode(null);
setInPermanentGameMode(null);
}
} else {
setInPermanentGameMode(gm); // we are not in a region, so the mode change is permanent
}
}
/*
* Feature 1: Separated Inventories / Storage
*/
if (plugin.config.getStoreEnabled()) {
if (hasPermission(Perms.KEEPINVENTORY))
return true;
getPlayer().closeInventory();
GameMode cgm = getPlayer().getGameMode();
if (gm == GameMode.ADVENTURE && !plugin.config.getAdventureInv())
gm = GameMode.SURVIVAL;
if (cgm == GameMode.ADVENTURE && !plugin.config.getAdventureInv())
cgm = GameMode.SURVIVAL;
if (gm != cgm) {
if (gm != GameMode.CREATIVE || plugin.config.getStoreCreative()) {
getInv().save(cgm);
}
if (gm == GameMode.CREATIVE) {
if (plugin.config.getStoreCreative() && getInv().isStored(GameMode.CREATIVE)) {
getInv().load(GameMode.CREATIVE);
} else {
getInv().clear();
}
setCreativeArmor();
} else if (gm == GameMode.SURVIVAL) {
if (getInv().isStored(GameMode.SURVIVAL))
getInv().load(GameMode.SURVIVAL);
} else if (gm == GameMode.ADVENTURE) {
if (getInv().isStored(GameMode.ADVENTURE))
getInv().load(GameMode.ADVENTURE);
else
getInv().clear();
}
}
}
return true;
}
public void onRevive() {
if (getPlayer().getGameMode() == GameMode.CREATIVE) {
setCreativeArmor();
}
}
public void setCreativeArmor() {
Map<String, MaterialData> armor = plugin.config.getCreativeArmor();
if (armor != null) {
ItemStack[] is = new ItemStack[4];
if (armor.containsKey("feet"))
is[0] = armor.get("feet").toItemStack(1);
if (armor.containsKey("legs"))
is[1] = armor.get("legs").toItemStack(1);
if (armor.containsKey("chest"))
is[2] = armor.get("chest").toItemStack(1);
if (armor.containsKey("head"))
is[3] = armor.get("head").toItemStack(1);
getPlayer().getInventory().setArmorContents(is);
}
}
public void onDropItem(PlayerDropItemEvent event) {
Core.debug(getName() + " ("+getPlayer().getGameMode()+") drops items " + event.getItemDrop().getItemStack().getType());
if (getPlayer().getGameMode() == GameMode.CREATIVE) {
if (hasPermission(Perms.NoLimit.DROP))
return;
Core.debug("removed");
if (plugin.config.getRemoveDrop())
event.getItemDrop().remove();
else
event.setCancelled(true);
}
}
public void onPickupItem(PlayerPickupItemEvent event) {
if (getPlayer().getGameMode() == GameMode.CREATIVE) {
if (hasPermission(Perms.NoLimit.PICKUP))
return;
if (plugin.config.getBlockPickupInCreative()) {
event.setCancelled(true);
} else if(plugin.config.getRemovePickup()) {
event.getItem().remove();
event.setCancelled(true);
}
}
}
public void onDie(EntityDeathEvent event) {
if (getPlayer().getGameMode() == GameMode.CREATIVE) {
if (!hasPermission(Perms.NoLimit.DROP)) {
event.getDrops().clear();
//getInv().storeTemp();
}
}
}
/* removed, because much to insecure. also we can save memory with out this
public void onRespawn(PlayerRespawnEvent event) {
if (getPlayer().getGameMode() == GameMode.CREATIVE) {
if (!plugin.config.getPermissionsEnabled() || !hasPermission(Perms.NoLimit.DROP)) {
getInv().restoreTemp();
}
}
getInv().clearTemp();
}*/
public void onDamage(Entity from, EntityDamageByEntityEvent event) { // receives damage
if (from instanceof Player) {
// its PVP
Player attacker = (Player) from;
if (attacker.getGameMode() == GameMode.CREATIVE) {
if (!Players.get(attacker).hasPermission(Perms.NoLimit.PVP)) {
event.setCancelled(true);
return; // skip next check
}
}
if (getPlayer().getGameMode() == GameMode.CREATIVE) {
if (!hasPermission(Perms.NoLimit.PVP)) {
event.setCancelled(true);
}
}
}
}
public void onDealDamage(EntityDamageByEntityEvent event) { // deals damage
if (event.getEntity() instanceof Creature) {
if (getPlayer().getGameMode() == GameMode.CREATIVE && plugin.config.getMobDamageBlock()) {
if (!hasPermission(Perms.NoLimit.MOB_DAMAGE)) {
event.setCancelled(true);
}
}
}
}
/**
* don't let the player be target by creatures he can't kill
*/
public void onTarget(EntityTargetEvent event) {
if (event.getEntity() instanceof Creature) {
if (((Player) event.getTarget()).getGameMode() == GameMode.CREATIVE && plugin.config.getMobDamageBlock()) {
if (!hasPermission(Perms.NoLimit.MOB_DAMAGE)) {
event.setCancelled(true);
}
}
}
}
public void onChestAccess(PlayerInteractEvent event) {
if (event.getPlayer().getGameMode() != GameMode.CREATIVE)
return;
if (hasPermission(Perms.NoLimit.CHEST))
return;
event.getPlayer().sendMessage(L("blocked.chest"));
event.setCancelled(true);
}
public void onChestAccess(PlayerInteractEntityEvent event) { // chest-minecarts are different events
if (getPlayer().getGameMode() != GameMode.CREATIVE)
return;
if (hasPermission(Perms.NoLimit.CHEST))
return;
event.getPlayer().sendMessage(L("blocked.chest"));
event.setCancelled(true);
}
public void onBenchAccess(PlayerInteractEvent event) {
if (!plugin.config.getBenchBlock() || event.getPlayer().getGameMode() != GameMode.CREATIVE)
return;
if (hasPermission(Perms.NoLimit.CHEST))
return;
event.getPlayer().sendMessage(L("blocked.chest"));
event.setCancelled(true);
}
public void onBenchAccess(PlayerInteractEntityEvent event) {
if (!plugin.config.getBenchBlock() || event.getPlayer().getGameMode() != GameMode.CREATIVE)
return;
if (hasPermission(Perms.NoLimit.CHEST))
return;
event.getPlayer().sendMessage(L("blocked.chest"));
event.setCancelled(true);
}
public void onSignAccess(PlayerInteractEvent event) {
if (!plugin.config.getSignBlock() || event.getPlayer().getGameMode() != GameMode.CREATIVE)
return;
if (hasPermission(Perms.NoLimit.SIGN))
return;
event.getPlayer().sendMessage(L("blocked.sign"));
event.setCancelled(true);
}
public void onButtonAccess(PlayerInteractEvent event) {
if (!plugin.config.getButtonBlock() || event.getPlayer().getGameMode() != GameMode.CREATIVE)
return;
if (event.getClickedBlock().getState() instanceof Lever) {
if (hasPermission(Perms.NoLimit.LEVER))
return;
event.getPlayer().sendMessage(L("blocked.lever"));
event.setCancelled(true);
} else {
if (hasPermission(Perms.NoLimit.BUTTON))
return;
event.getPlayer().sendMessage(L("blocked.button"));
event.setCancelled(true);
}
}
private boolean checkSwitchFlight(PlayerMoveEvent event) {
if (event != null && getPlayer().getGameMode() == GameMode.CREATIVE && getFloatingHeight(event.getTo()) > plugin.config.getMaximumFloatingHeight()) {
// but not if he is too high
this.sendTimeoutMessage(L("blocked.survival_flying"));
Location newloc = event.getTo().clone();
newloc.setX(event.getFrom().getX());
newloc.setY(event.getFrom().getY()); // well, otherwise flying high out of the region is possible
newloc.setZ(event.getFrom().getZ());
event.setTo(newloc);
return false;
}
return true;
}
private boolean checkSwitchFlight(PlayerAreaEvent area_event) {
if (area_event instanceof PlayerChangedAreaEvent) {
if (!checkSwitchFlight(((PlayerChangedAreaEvent) area_event).getMoveEvent())) {
((PlayerChangedAreaEvent) area_event).setCancelled(true);
return false;
}
}
return true;
}
public void setRegionGameMode(GameMode region_gamemode, PlayerAreaEvent area_event) {
Core.debug(getName()+": changed region: "+region_gamemode+": " + area_event);
PlayerMoveEvent event = null;
if (area_event instanceof PlayerChangedAreaEvent)
event = ((PlayerChangedAreaEvent) area_event).getMoveEvent();
GameMode CURRENT_GAMEMODE = getPlayer().getGameMode();
GameMode DEFAULT_GAMEMODE = plugin.com.getDefaultGameMode(event != null ? event.getTo().getWorld() : getPlayer().getWorld());
if (region_gamemode != null && CURRENT_GAMEMODE != region_gamemode && !this.isActiveRegionGameMode(region_gamemode)) {
Core.debug(getName()+": entering creative area");
// 1. the region allows "the other (temporary) gamemode"
// 2. but the player is not in that mode
// 3. and the player is not aware of that
// result: change him to that mode
boolean isOptional = isOptionalRegionGameMode(area_event.getRegionHash(), CURRENT_GAMEMODE);
if (isOptional || checkSwitchFlight(area_event)) {
storeActiveRegionGameMode(region_gamemode); // have to be set, before setGameMode
if (!isOptional) {
getPlayer().setGameMode(region_gamemode);
}
}
} else if (region_gamemode == null && getPlayer().getGameMode() != DEFAULT_GAMEMODE && !isInPermanentGameMode(CURRENT_GAMEMODE) && getActiveRegionGameMode() != null) {
Core.debug(getName()+": leaving creative area");
// 1. the region doesn't allow "the other gamemode"
// 2. but the player is in that mode
// 3. and the player isn't global (permanent) in that mode
// 4. and the player isn't temporary in that mode (that means its maybe a world teleport, and the mode changes afterwards)
// result: change him back to default mode
if (checkSwitchFlight(area_event)) {
storeActiveRegionGameMode(null);
getPlayer().setGameMode(DEFAULT_GAMEMODE);
}
} else if (region_gamemode == null && this.isActiveRegionGameMode()) {
Core.debug(getName()+": leaving creative area (while already in default gamemode)");
// 1. the region doesn't allow "the other gamemode"
// 2. but he thinks he is still allowed
// 3. (because of else) we are not longer in that mode
// result: advise him to not longer allowed to that region
storeActiveRegionGameMode(null);
} else if (region_gamemode == CURRENT_GAMEMODE && !this.isInPermanentGameMode(CURRENT_GAMEMODE)) {
if (!isActiveRegionGameMode(region_gamemode)) {
// we have no information why we are already in this gamemode, so this may be because of an AuthMe change-and-teleport
storeActiveRegionGameMode(region_gamemode);
}
}
/** At the moment, in permanent game mode, it ignores all regions
else if (this.isRegionGameMode()) {
Core.debug(getName()+": entering creative area (while already in region gamemode)");
// 1. the region allow "the other gamemode"
// 2. (inherit) the player is already in that mode
GameMode rgm = getOptionalRegionGameMode(area_event.getRegionHash());
if (rgm != null && rgm != CURRENT_GAMEMODE) {
Core.debug(getName()+": switching to optional remembered gamemode");
// 3. but he remembered optional want the other gamemode in that region
// * this inherits, that the option is allowed
// result: change to the optional remembered game mode
getPlayer().setGameMode(rgm);
}
}*/
}
private Map<String, Long> timeout_msgs = new HashMap<String, Long>();
public void sendTimeoutMessage(String msg) {
Iterator<Map.Entry<String, Long>> i = timeout_msgs.entrySet().iterator();
while (i.hasNext()) {
Map.Entry<String, Long> entry = i.next();
if (entry.getValue() < (System.currentTimeMillis() - plugin.config.getRepeatingMessageTimeout())) {
i.remove();
}
}
if (!timeout_msgs.containsKey(msg)) {
timeout_msgs.put(msg, System.currentTimeMillis());
getPlayer().sendMessage(msg);
}
}
public int getFloatingHeight() {
return getFloatingHeight(getPlayer().getLocation());
}
public int getFloatingHeight(Location loc) {
Block b = loc.getBlock();
int steps = 0;
while (b.getType() == Material.AIR) {
steps++;
b = b.getRelative(BlockFace.DOWN);
}
return steps;
}
public void goToFloor() {
Block b = getPlayer().getLocation().getBlock();
int steps = 0;
while (b.getType() == Material.AIR) {
steps++;
b = b.getRelative(BlockFace.DOWN);
}
if (steps > 2) {
getPlayer().teleport(new Location(getPlayer().getWorld(),
getPlayer().getLocation().getX(),
b.getY()+1,
getPlayer().getLocation().getZ()));
}
}
public boolean hasPermission(IPermission permission) {
return plugin.perm.hasPermission(this.getPlayer(), permission);
}
public boolean isGameModeAllowed(GameMode gm) {
if (plugin.config.getRegionOptional() && isActiveRegionGameMode(gm)) {
return true;
}
return false;
}
}

View file

@ -1,94 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.limitedcreative;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack;
/**
* The "Block" means a Minecraft-Block, not "blocking". So this Class is used to prevent ItemSpawn which are Drops from
* specified Blocks.
*/
public class NoBlockItemSpawn {
public final static long TIME_OFFSET = 250;
private List<BlockItemDrop> list = new ArrayList<BlockItemDrop>();
public boolean isBlocked(Location l, Material type) {
cleanup();
for (BlockItemDrop block : list) {
if (block.getLocation().equals(l) && block.getType().equals(type))
return true;
}
return false;
}
private void cleanup() {
Iterator<BlockItemDrop> i = list.iterator();
while (i.hasNext()) {
BlockItemDrop block = i.next();
if (block.getTimestamp() < System.currentTimeMillis() - TIME_OFFSET)
i.remove();
}
}
private class BlockItemDrop {
public BlockItemDrop(Location l, Material type) {
this.l = l;
this.type = type;
this.timestamp = System.currentTimeMillis();
}
private Location l;
private Material type;
private long timestamp;
public Location getLocation() {
return l;
}
public Material getType() {
return type;
}
public long getTimestamp() {
return timestamp;
}
}
public void block(Block block, LCPlayer player) {
if (player.getPlayer().getItemInHand().containsEnchantment(Enchantment.SILK_TOUCH)) {
block(block.getLocation(), block.getType());
} else {
// doesn't include silktouch
for (ItemStack i : block.getDrops(player.getPlayer().getItemInHand())) {
block(block.getLocation(), i.getType());
}
}
}
public void block(Block block) {
block(block, null);
}
public void block(Location l, Material type) {
list.add(new BlockItemDrop(l, type));
}
}

View file

@ -1,78 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.limitedcreative;
import de.jaschastarke.minecraft.utils.IPermission;
public enum Perms implements IPermission {
CONFIG("config"),
REGIONS("regions"),
REGIONS_BYPASS("regions_bypass"),
GM("switch_gamemode"),
GM_BACKONLY("switch_gamemode.backonly"),
GM_SURVIVAL("switch_gamemode.survival"),
GM_CREATIVE("switch_gamemode.creative"),
GM_ADVENTURE("switch_gamemode.adventure"),
GM_OTHER("switch_gamemode.other"),
KEEPINVENTORY("keepinventory");
private static final String NS = "limitedcreative";
private String perm;
private Perms(String permission) {
perm = permission;
}
@Override
public String toString() {
return NS + SEP + perm;
}
public enum NoLimit implements IPermission {
DROP("drop"),
PICKUP("pickup"),
CHEST("chest"),
SIGN("sign"),
BUTTON("button"),
LEVER("lever"),
PVP("pvp"),
MOB_DAMAGE("mob_damage"),
USE("use"),
BREAK("break");
private static final String NS = "nolimit";
private String perm;
private NoLimit(String permission) {
perm = permission;
}
@Override
public String toString() {
return Perms.NS + SEP + NoLimit.NS + SEP + perm;
}
}
public static final class CmdBlock { // not the best way, but this matches to everything in this plugin ;)
public static final String NS = "cmdblock";
public static IPermission ALL = new IPermission() {
public String toString() {
return Perms.NS + SEP + CmdBlock.NS + SEP + "all";
}
};
}
}

View file

@ -1,82 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.limitedcreative;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.entity.Player;
import de.jaschastarke.minecraft.limitedcreative.store.PlayerOptions;
public class Players {
public static final long CLEANUP_TIMEOUT = 300000; // 300s = 5m
private static Map<String, LCPlayer> players = new HashMap<String, LCPlayer>();
private static PlayerOptions options = new PlayerOptions();
public static LCPlayer get(Player player) {
Core.debug("player: " + player.getName() + " - " + ((Object)player).hashCode() + " - " + player.getEntityId() + " - " + player.getUniqueId());
if (!players.containsKey(player.getName())) {
LCPlayer p = new LCPlayer(player);
players.put(player.getName(), p);
return p;
} else {
LCPlayer p = players.get(player.getName());
if (player != p.getPlayer())
p.updatePlayer(player);
//p.touch();
return p;
}
}
public static LCPlayer get(String player) {
if (players.containsKey(player)) {
return players.get(player);
}
return null;
}
public static void remove(String player) {
players.remove(player);
}
/*public static void clear(String player) {
if (players.containsKey(player)) {
LCPlayer p = players.get(player);
p.updatePlayer(null);
p.touch(); // keep meta data alive till cleanup, but remove player bukkit assoc.
}
}*/
/*public static void cleanUp() {
int count = players.size();
Iterator<Map.Entry<String, LCPlayer>> i = players.entrySet().iterator();
while (i.hasNext()) {
Map.Entry<String, LCPlayer> entry = i.next();
if (entry.getValue().isOutdated()) {
Core.debug("removing "+entry.getValue().getName());
i.remove();
}
}
Core.debug("cleanup done: player count: "+count+" / "+players.size());
}*/
public static PlayerOptions getOptions() {
return options;
}
}

View file

@ -1,45 +0,0 @@
package de.jaschastarke.minecraft.limitedcreative.cmdblock;
import static de.jaschastarke.minecraft.utils.Locale.L;
import org.bukkit.GameMode;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import de.jaschastarke.minecraft.limitedcreative.Core;
import de.jaschastarke.minecraft.limitedcreative.LCPlayer;
import de.jaschastarke.minecraft.limitedcreative.Perms;
import de.jaschastarke.minecraft.limitedcreative.Players;
public class CommandBlocker {
private Core plugin;
public CommandBlocker(Core plugin) {
this.plugin = plugin;
plugin.getServer().getPluginManager().registerEvents(new Listener(), plugin);
}
class Listener implements org.bukkit.event.Listener {
@EventHandler
public void onPreCommand(PlayerCommandPreprocessEvent event) {
if (event.getPlayer().getGameMode() == GameMode.CREATIVE) {
String cmd = event.getMessage();
if (cmd.startsWith("/")) { // just to be sure ;)
cmd = cmd.substring(1);
for (ICmdBlockEntry blockentry : plugin.config.getCommandBlockList()) {
if (blockentry.test(cmd)) {
LCPlayer player = Players.get(event.getPlayer());
if (!player.hasPermission(Perms.CmdBlock.ALL)) {
Core.debug("CmdBlock: "+event.getPlayer().getName()+": '/"+cmd+"' blocked by rule '"+blockentry.toString()+"'");
event.setCancelled(true);
event.getPlayer().sendMessage(L("cmdblock.blocked"));
return;
}
}
}
}
}
}
}
}

View file

@ -1,255 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.limitedcreative.listeners;
import static de.jaschastarke.minecraft.utils.Locale.L;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Sign;
import org.bukkit.entity.Entity;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.StorageMinecart;
import org.bukkit.entity.Villager;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.material.Button;
import org.bukkit.material.Lever;
import de.jaschastarke.minecraft.limitedcreative.BlackList;
import de.jaschastarke.minecraft.limitedcreative.Core;
import de.jaschastarke.minecraft.limitedcreative.LCPlayer;
import de.jaschastarke.minecraft.limitedcreative.Perms;
import de.jaschastarke.minecraft.limitedcreative.Players;
public class LimitListener implements Listener {
private Core plugin;
public LimitListener(Core plugin) {
this.plugin = plugin;
}
@EventHandler
public void onPlayerDropItem(PlayerDropItemEvent event) {
Players.get(event.getPlayer()).onDropItem(event);
}
@EventHandler
public void onPlayerPickupItem(PlayerPickupItemEvent event) {
Players.get(event.getPlayer()).onPickupItem(event);
}
@EventHandler(priority=EventPriority.LOWEST)
public void onPlayerInteract(PlayerInteractEvent event) {
if (MainListener.isCancelled(event) || event.getPlayer().getGameMode() != GameMode.CREATIVE)
return;
LCPlayer player = Players.get(event.getPlayer());
if (!player.hasPermission(Perms.NoLimit.USE)) {
if (event.getItem() != null && BlackList.isBlackListed(plugin.config.getBlockedUse(), event.getItem())) {
event.setCancelled(true);
event.setUseItemInHand(Event.Result.DENY);
event.getPlayer().sendMessage(L("blocked.use"));
return;
}
}
if (event.getAction() != Action.RIGHT_CLICK_BLOCK)
return;
Block block = event.getClickedBlock();
if (block.getState() instanceof InventoryHolder || block.getType() == Material.ENDER_CHEST || block.getType() == Material.BEACON) { // Workaround, Bukkit not recognize a Enderchest
player.onChestAccess(event);
} else if (block.getState() instanceof Sign) {
player.onSignAccess(event);
} else if (block.getState() instanceof Lever || block.getState() instanceof Button) {
player.onButtonAccess(event);
} else if (block.getType() == Material.WORKBENCH || block.getType() == Material.ANVIL || block.getType() == Material.ENCHANTMENT_TABLE) {
player.onBenchAccess(event);
}
}
@EventHandler(priority=EventPriority.LOWEST)
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
if (event.isCancelled() || event.getPlayer().getGameMode() != GameMode.CREATIVE)
return;
LCPlayer player = Players.get(event.getPlayer());
if (!player.hasPermission(Perms.NoLimit.USE)) {
if (event.getPlayer().getItemInHand() != null && BlackList.isBlackListed(plugin.config.getBlockedUse(), event.getPlayer().getItemInHand())) {
event.setCancelled(true);
event.getPlayer().sendMessage(L("blocked.use"));
return;
}
}
Entity entity = event.getRightClicked();
// Temporary Solution: While dropping of Items is prevented we don't allow Interaction with ItemFrames, so no
// Items can be "placed" anywhere.
// TODO: Improve Configuration
if (!player.hasPermission(Perms.NoLimit.DROP)) {
if (entity instanceof ItemFrame && plugin.config.getRemoveDrop()) {
event.setCancelled(true);
event.getPlayer().sendMessage(L("blocked.use"));
return;
}
}
if (entity instanceof StorageMinecart) {
player.onChestAccess(event);
} else if (entity instanceof Villager) {
player.onBenchAccess(event);
}
}
@EventHandler
public void onEntityDamage(EntityDamageEvent event) {
if (event instanceof EntityDamageByEntityEvent)
onEntityDamageByEntity((EntityDamageByEntityEvent) event);
}
/*
* Registering to that event works, but causes a SEVERE:
* Plugin attempted to register delegated event class class org.bukkit.event.entity.EntityDamageByEntityEvent.
* It should be using class org.bukkit.event.entity.EntityDamageEvent!
*/
protected void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
if (event.isCancelled())
return;
Entity source = event.getDamager();
if (source instanceof Projectile)
source = ((Projectile) source).getShooter();
if (event.getEntity() instanceof Player) {
Players.get((Player) event.getEntity()).onDamage(source, event);
}
if (!event.isCancelled() && source instanceof Player) {
Players.get((Player) source).onDealDamage(event);
}
}
@EventHandler
public void onEntityTarget(EntityTargetEvent event) {
if (event.isCancelled())
return;
if (event.getTarget() instanceof Player) {
Players.get((Player) event.getTarget()).onTarget(event);
}
}
@EventHandler(priority=EventPriority.LOW)
public void onEntityDeath(EntityDeathEvent event) {
if (event.getEntity() instanceof Player) {
Player player = (Player) event.getEntity();
Players.get(player).onDie(event);
}
}
/*@EventHandler
public void onPlayerRespawn(PlayerRespawnEvent event) {
Players.get(event.getPlayer()).onRespawn(event);
}*/
private void whenBlockBreak(Cancellable event, Block block, Player eventPlayer) {
if (eventPlayer.getGameMode() == GameMode.CREATIVE) {
LCPlayer player = Players.get(eventPlayer);
if (!player.hasPermission(Perms.NoLimit.BREAK)) {
if (BlackList.isBlackListed(plugin.config.getBlockedBreaks(), block)) {
event.setCancelled(true);
eventPlayer.sendMessage(L("blocked.break"));
}
}
if (player.hasPermission(Perms.NoLimit.DROP))
return;
// Prevent dropping of doors and beds when destroying the wrong part
// TODO: Fix, Remove, or make it god like, but this little thing is crap ;)
Material mat = block.getType();
switch (block.getType()) {
case WOODEN_DOOR:
mat = Material.WOOD_DOOR;
plugin.spawnblock.block(block.getRelative(BlockFace.DOWN).getLocation(), mat);
break;
case IRON_DOOR_BLOCK:
mat = Material.IRON_DOOR;
plugin.spawnblock.block(block.getRelative(BlockFace.DOWN).getLocation(), mat);
break;
case BED_BLOCK:
mat = Material.BED;
plugin.spawnblock.block(block.getRelative(BlockFace.NORTH).getLocation(), mat);
plugin.spawnblock.block(block.getRelative(BlockFace.EAST).getLocation(), mat);
plugin.spawnblock.block(block.getRelative(BlockFace.SOUTH).getLocation(), mat);
plugin.spawnblock.block(block.getRelative(BlockFace.WEST).getLocation(), mat);
break;
default:
plugin.spawnblock.block(block.getLocation(), mat);
}
}
}
/* Doesn't make sense yet, as the block always will be Air. whenBlockBreak should be changed to use Material
* instead. Maybe in the Feature.
@EventHandler
public void onHangingBreak(HangingBreakByEntityEvent event) {
if (event.getRemover() instanceof Player) {
Player eventPlayer = (Player) event.getRemover();
whenBlockBreak(event, event.getEntity().getLocation().getBlock(), eventPlayer);
}
}*/
@EventHandler
public void onBlockBreak(BlockBreakEvent event) {
if (event.isCancelled())
return;
whenBlockBreak(event, event.getBlock(), event.getPlayer());
}
@EventHandler
public void onBlockPlace(BlockPlaceEvent event) {
if (event.isCancelled())
return;
if (event.getPlayer().getGameMode() == GameMode.CREATIVE) {
LCPlayer player = Players.get(event.getPlayer());
if (!player.hasPermission(Perms.NoLimit.USE)) {
if (BlackList.isBlackListed(plugin.config.getBlockedUse(), event.getBlock())) {
event.setCancelled(true);
event.getPlayer().sendMessage(L("blocked.place"));
}
}
}
}
}

View file

@ -1,87 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.limitedcreative.listeners;
import org.bukkit.entity.Item;
import org.bukkit.event.Event;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.event.player.PlayerGameModeChangeEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import de.jaschastarke.minecraft.limitedcreative.Core;
import de.jaschastarke.minecraft.limitedcreative.Players;
public class MainListener implements Listener {
private Core plugin;
public MainListener(Core plugin) {
this.plugin = plugin;
}
/**
* The isCancelled in PlayerInteractEvent doesn't check useItemInHand, even this decides (when clicking on
* entity with e.g. a bucket)
* @param event
* @return The relevant "isCancelled"
*/
public static boolean isCancelled(PlayerInteractEvent event) {
return event.useInteractedBlock() == Event.Result.DENY && event.useItemInHand() == Event.Result.DENY;
}
@EventHandler
public void onPlayerGameModeChange(PlayerGameModeChangeEvent event) {
if (Core.isDebug()) {
Core.debug("onPlayerGameModeChange: "+event.getPlayer().getName());
Core.debug("Current GameMode: "+event.getPlayer().getGameMode());
Core.debug("New GameMode: "+event.getNewGameMode());
Core.debug("isLoggedin: "+plugin.com.isLoggedIn(event.getPlayer()));
Core.debug("isCancelled: "+event.isCancelled());
}
if (!plugin.com.isLoggedIn(event.getPlayer()))
return;
if (!Players.get(event.getPlayer()).onSetGameMode(event.getNewGameMode()))
event.setCancelled(true);
}
@EventHandler
public void onPlayerRespawn(PlayerRespawnEvent event) {
Players.get(event.getPlayer()).onRevive();
}
/**
* Also needed if WorldGuard-Feature is enabled, so can not moved to optional Listener "Limit".
*/
@EventHandler
public void onItemSpawn(ItemSpawnEvent event) {
if (event.isCancelled())
return;
if (event.getEntity() instanceof Item) {
if (plugin.spawnblock.isBlocked(event.getLocation().getBlock().getLocation(), ((Item) event.getEntity()).getItemStack().getType())) {
event.setCancelled(true);
}
}
}
public void onLogout(PlayerQuitEvent event) {
// what? i can't cancel a logout event? but how to chain the user to the server than? xD
Players.remove(event.getPlayer().getName());
}
}

View file

@ -1,219 +0,0 @@
package de.jaschastarke.minecraft.limitedcreative.regions;
import static de.jaschastarke.minecraft.utils.Locale.L;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.Sign;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPistonExtendEvent;
import org.bukkit.event.block.BlockPistonRetractEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.material.Button;
import org.bukkit.material.Lever;
import de.jaschastarke.minecraft.limitedcreative.Core;
import de.jaschastarke.minecraft.limitedcreative.LCPlayer;
import de.jaschastarke.minecraft.limitedcreative.Players;
import de.jaschastarke.minecraft.limitedcreative.listeners.MainListener;
import de.jaschastarke.minecraft.utils.Util;
import de.jaschastarke.minecraft.worldguard.ApplicableRegions;
import de.jaschastarke.minecraft.worldguard.CRegionManager;
import de.jaschastarke.minecraft.worldguard.events.PlayerNewLocationAreaEvent;
import de.jaschastarke.minecraft.worldguard.events.PlayerSetAreaEvent;
import de.jaschastarke.minecraft.worldguard.events.PlayerUpdateAreaEvent;
public class RegionListener implements Listener {
private static Core plugin = WorldGuardIntegration.plugin;
private CRegionManager rm;
public RegionListener(WorldGuardIntegration wgi) {
rm = wgi.getRegionManager();
}
private ApplicableRegions regionSet(Location loc) {
return rm.getRegionSet(loc);
}
private ApplicableRegions regionSet(Block block) {
return rm.getRegionSet(block);
}
@EventHandler
public void onBlockBreak(BlockBreakEvent event) {
if (event.isCancelled())
return;
whenBlockBreak(event, event.getBlock(), event.getPlayer());
}
@EventHandler
public void onHangingBreak(HangingBreakByEntityEvent event) {
if (event.getRemover() instanceof Player) {
Player eventPlayer = (Player) event.getRemover();
whenBlockBreak(event, event.getEntity().getLocation().getBlock(), eventPlayer);
}
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
if (MainListener.isCancelled(event))
return;
if (event.getAction() != Action.RIGHT_CLICK_BLOCK)
return;
Block block = event.getClickedBlock();
if (block.getState() instanceof InventoryHolder || block.getType() == Material.ENDER_CHEST || // Workaround, Bukkit not recognize a Enderchest
block.getState() instanceof Sign ||
block.getState() instanceof Lever || block.getState() instanceof Button ||
block.getType() == Material.WORKBENCH || block.getType() == Material.ANVIL) {
LCPlayer player = Players.get(event.getPlayer());
boolean diffrent_region = rm.isDiffrentRegion(event.getPlayer(), block.getLocation());
if (player.isActiveRegionGameMode() && diffrent_region) {
// do not break outside of "gamemod-change-region" when in the region
if (rm.getRegionSet(block).getFlag(Flags.GAMEMODE, event.getPlayer()) != player.getActiveRegionGameMode()) {
event.getPlayer().sendMessage(L("blocked.outside_interact"));
event.setCancelled(true);
}
} else if (diffrent_region) {
// do not break inside of "survial-region in creative world" when outside
if (rm.getRegionSet(block).getFlag(Flags.GAMEMODE) != null) {
event.getPlayer().sendMessage(L("blocked.inside_interact"));
event.setCancelled(true);
}
}
}
}
private void whenBlockBreak(Cancellable event, Block block, Player eventPlayer) {
LCPlayer player = Players.get(eventPlayer);
boolean diffrent_region = rm.isDiffrentRegion(eventPlayer, block.getLocation());
if (player.isActiveRegionGameMode() && diffrent_region) {
// do not break outside of "gamemod-change-region" when in the region
if (rm.getRegionSet(block).getFlag(Flags.GAMEMODE, eventPlayer) != player.getActiveRegionGameMode()) {
eventPlayer.sendMessage(L("blocked.outside_break"));
event.setCancelled(true);
}
} else if (diffrent_region) {
// do not break inside of "survial-region in creative world" when outside
if (rm.getRegionSet(block).getFlag(Flags.GAMEMODE) != null) {
eventPlayer.sendMessage(L("blocked.inside_break"));
event.setCancelled(true);
}
}
if (!event.isCancelled()) {
// prevent any drops for survival players in creative regions
if (eventPlayer.getGameMode() != GameMode.CREATIVE && rm.getRegionSet(block).getFlag(Flags.GAMEMODE) == GameMode.CREATIVE) {
plugin.spawnblock.block(block, player);
}
}
}
@EventHandler
public void onBlockPlace(BlockPlaceEvent event) {
if (event.isCancelled())
return;
LCPlayer player = Players.get(event.getPlayer());
boolean diffrent_region = rm.isDiffrentRegion(event.getPlayer(), event.getBlock().getLocation());
if (player.isActiveRegionGameMode() && diffrent_region) {
// do not build outside of "gamemod-change-region" when in the region
if (rm.getRegionSet(event.getBlock()).getFlag(Flags.GAMEMODE, event.getPlayer()) != player.getActiveRegionGameMode()) {
event.getPlayer().sendMessage(L("blocked.outside_place"));
event.setCancelled(true);
}
} else if (diffrent_region) {
// do not build inside of "survial-region in creative world" when outside
if (rm.getRegionSet(event.getBlock()).getFlag(Flags.GAMEMODE) != null) {
event.getPlayer().sendMessage(L("blocked.inside_place"));
event.setCancelled(true);
}
}
}
@EventHandler
public void onPlayerChangedArea(PlayerNewLocationAreaEvent event) {
Players.get(event.getPlayer()).setRegionGameMode(event.getRegionSet().getFlag(Flags.GAMEMODE, event.getPlayer()), event);
}
@EventHandler
public void onPlayerSetArea(PlayerSetAreaEvent event) {
Players.get(event.getPlayer()).setRegionGameMode(event.getRegionSet().getFlag(Flags.GAMEMODE, event.getPlayer()), event);
}
@EventHandler
public void onPlayerUpdateArea(PlayerUpdateAreaEvent event) {
Players.get(event.getPlayer()).setRegionGameMode(event.getRegionSet().getFlag(Flags.GAMEMODE, event.getPlayer()), event);
}
@EventHandler
public void onPistonExtend(BlockPistonExtendEvent event) {
if (event.isCancelled())
return;
Block source = event.getBlock().getRelative(event.getDirection());
Core.debug("PistonExtend "+source.getType()+" "+event.getDirection());
if (source.getType() != Material.AIR) {
if (regionSet(source).getFlag(Flags.GAMEMODE) == GameMode.CREATIVE) {
for (int i = 1; i <= 12; i++) {
Block dest = source.getRelative(event.getDirection(), i);
Core.debug("dest "+i+": "+dest.getType());
if (regionSet(dest).getFlag(Flags.GAMEMODE) != GameMode.CREATIVE) {
plugin.logger.warning(L("blocked.piston", source.getRelative(event.getDirection(), i - 1).getType().toString(), Util.toString(source.getLocation())));
event.setCancelled(true);
break;
} else if (dest.getType() == Material.AIR) {
break;
}
}
}
}
}
@EventHandler
public void onPistonRetract(BlockPistonRetractEvent event) {
if (event.isCancelled())
return;
Block source = event.getBlock().getRelative(event.getDirection(), 2);
Block dest = source.getRelative(event.getDirection().getOppositeFace());
Core.debug("PistonRetract "+source.getType()+" "+event.getDirection() + " " + event.isSticky());
if (event.isSticky() && source.getType() != Material.AIR) {
Core.debug("dest "+dest.getType());
if (regionSet(source).getFlag(Flags.GAMEMODE) == GameMode.CREATIVE) {
if (regionSet(dest).getFlag(Flags.GAMEMODE) != GameMode.CREATIVE) {
plugin.logger.warning(L("blocked.piston", source.getType().toString(), Util.toString(source.getLocation())));
event.setCancelled(true);
}
} else if (regionSet(dest).getFlag(Flags.GAMEMODE) == GameMode.CREATIVE) {
// source isn't creative
plugin.logger.warning(L("blocked.piston_in", source.getType().toString(), Util.toString(source.getLocation())));
event.setCancelled(true);
}
}
}
@EventHandler
public void onItemSpawn(ItemSpawnEvent event) {
if (event.isCancelled())
return;
if (event.getEntity() instanceof Item) {
if (!regionSet(event.getLocation()).allows(Flags.SPAWNDROPS))
event.setCancelled(true);
}
}
}

View file

@ -1,64 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.limitedcreative.regions;
import java.util.List;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.flags.Flag;
import de.jaschastarke.minecraft.limitedcreative.Core;
import de.jaschastarke.minecraft.worldguard.CRegionManager;
import de.jaschastarke.minecraft.worldguard.Integration;
import de.jaschastarke.minecraft.worldguard.Interface;
public class WorldGuardIntegration implements Integration {
public static Core plugin;
public static WorldGuardPlugin wg;
public WorldGuardIntegration(Core plugin) {
WorldGuardIntegration.plugin = plugin;
wg = (WorldGuardPlugin) plugin.getServer().getPluginManager().getPlugin("WorldGuard");
/*
* This should be only done by the "API"-Plugin itself (when its done). You don't need to that again if you
* like to interact with LimitedCreative's WorldGuard-Integration
*/
new Interface(plugin);
/*
* You only need to do this one, to make your Flags available.
*/
Interface.getInstance().register(this);
plugin.getServer().getPluginManager().registerEvents(new RegionListener(this), plugin);
}
public CRegionManager getRegionManager() {
return Interface.getInstance().getRegionManager();
}
@Override
public List<Flag<?>> getFlags() {
return Flags.getList();
}
public void unload() {
Interface.unload();
}
}

View file

@ -1,47 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.limitedcreative.store;
import org.bukkit.configuration.MemoryConfiguration;
import de.jaschastarke.minecraft.limitedcreative.Inventory;
import de.jaschastarke.minecraft.limitedcreative.Inventory.Target;
public class InvMemStorage extends InvConfStorage {
private MemoryConfiguration storage = new MemoryConfiguration();
@Override
public void store(Inventory pinv, Target target) {
store(pinv, storage.createSection(pinv.getPlayer().getName()));
}
@Override
public void load(Inventory pinv, Target target) {
load(pinv, storage.getConfigurationSection(pinv.getPlayer().getName()));
}
@Override
public void remove(Inventory pinv, Target target) {
storage.set(pinv.getPlayer().getName(), null);
}
@Override
public boolean contains(Inventory pinv, Target target) {
return storage.contains(pinv.getPlayer().getName());
}
}

View file

@ -1,72 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.limitedcreative.store;
import java.io.File;
import java.io.IOException;
import org.bukkit.configuration.file.YamlConfiguration;
import de.jaschastarke.minecraft.limitedcreative.Core;
import de.jaschastarke.minecraft.limitedcreative.Inventory;
import de.jaschastarke.minecraft.limitedcreative.Inventory.Target;
public class InvYamlStorage extends InvConfStorage {
private static final String SUFFIX = ".yml";
private File dir;
public InvYamlStorage(File file) {
dir = file;
}
@Override
public void load(Inventory pinv, Target target) {
load(pinv, YamlConfiguration.loadConfiguration(getFile(pinv, target)));
}
@Override
public void store(Inventory pinv, Target target) {
YamlConfiguration yml = new YamlConfiguration();
yml.options().header("DO NOT MODIFY THIS FILE");
store(pinv, yml);
try {
yml.save(getFile(pinv, target));
} catch (IOException e) {
Core.plugin.warn("Failed to save Inventory for Player " + pinv.getPlayer().getName());
e.printStackTrace();
}
}
@Override
public void remove(Inventory pinv, Target target) {
getFile(pinv, target).delete();
}
@Override
public boolean contains(Inventory pinv, Target target) {
return getFile(pinv, target).exists();
}
protected File getFile(Inventory pinv, Target target) {
if (target != default_target) {
return new File(dir, pinv.getPlayer().getName() + "_" + target.toString().toLowerCase() + SUFFIX);
} else {
return new File(dir, pinv.getPlayer().getName() + SUFFIX);
}
}
}

View file

@ -1,89 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.limitedcreative.store;
import java.io.File;
import java.io.IOException;
import org.bukkit.GameMode;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import de.jaschastarke.minecraft.limitedcreative.Core;
public class PlayerOptions {
private File _store_file = new File(Core.plugin.getDataFolder(), "players.yml");
private YamlConfiguration store = YamlConfiguration.loadConfiguration(_store_file);
{
store.options().header("DO NOT MODIFY THIS FILE");
}
public void setRegionGameMode(String player, GameMode gm) {
if (gm == null) {
store.set(player + ".region_gamemode", null);
cleanUp(player);
} else {
store.set(player + ".region_gamemode", gm.name());
}
save();
}
public GameMode getRegionGameMode(String player) {
if (store.contains(player + ".region_gamemode")) {
return GameMode.valueOf(store.getString(player + ".region_gamemode"));
} else if (store.contains(player + ".region_creative")) { // compatibility fallback
return store.getBoolean(player + ".region_creative") ? GameMode.CREATIVE : null;
}
return null;
}
public GameMode getOptionalRegionGameMode(String player, String region) {
if (store.contains(player+".region")) {
ConfigurationSection sect = store.getConfigurationSection(player+".region");
if (sect.contains(region)) {
return GameMode.valueOf(sect.getString(region));
}
}
return null;
}
public void setOptionalRegionGameMode(String player, String region, GameMode gm) {
ConfigurationSection sect = store.contains(player+".region") ? store.getConfigurationSection(player+".region") : store.createSection(player+".region");
String mode = gm == null ? null : gm.name();
sect.set(region, mode);
if (sect.getKeys(true).size() == 0) {
store.set(sect.getCurrentPath(), null);
cleanUp(player);
}
save();
}
protected void cleanUp(String player) {
if (store.contains(player) && store.getConfigurationSection(player).getValues(true).size() == 0) {
store.set(player, null);
}
}
protected void save() {
try {
store.save(_store_file);
} catch (IOException e) {
Core.plugin.logger.severe("Failed to save players.yml");
e.printStackTrace();
}
}
}

View file

@ -1,23 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.utils;
public interface IPermission {
public static final String SEP = ".";
}

View file

@ -1,95 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.utils;
import java.io.File;
import java.text.MessageFormat;
import java.util.List;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import de.jaschastarke.minecraft.limitedcreative.Core;
public class Locale {
protected YamlConfiguration lang;
private YamlConfiguration fallback_lang;
private static Locale inst = null;
private JavaPlugin plugin;
private final static String DEFAULT_LANG = "en_US";
public Locale(JavaPlugin plugin) {
this(plugin, null);
}
public Locale(JavaPlugin plugin, String lang) {
if (inst == null)
inst = this;
this.plugin = plugin;
if (lang == null)
lang = java.util.Locale.getDefault().toString();
String fn = getFilename(lang);
Core.debug("Using Locale: " + lang);
File localefile = new File(plugin.getDataFolder(), fn);
if (localefile.exists())
this.lang = YamlConfiguration.loadConfiguration(localefile);
else if (plugin.getResource(fn) != null)
this.lang = YamlConfiguration.loadConfiguration(plugin.getResource(fn));
}
private String getFilename(String locale) {
return "lang/"+locale+".yml";
}
private YamlConfiguration getLang(String msg) {
if (lang != null && lang.contains(msg)) {
return lang;
} else {
if (fallback_lang == null)
fallback_lang = YamlConfiguration.loadConfiguration(plugin.getResource(getFilename(DEFAULT_LANG)));
return fallback_lang;
}
}
public String get(String msg, Object... objects) {
YamlConfiguration lang = getLang(msg);
if (lang.contains(msg)) {
if (lang.isList(msg)) {
List<String> list = lang.getStringList(msg);
String[] lines = new String[list.size()];
list.toArray(lines);
msg = Util.join(lines, "\n");
} else {
msg = lang.getString(msg);
}
}
if (objects.length > 0)
msg = MessageFormat.format(msg, objects);
return msg.replaceAll("&([0-9a-f])", "\u00A7$1");
}
/**
* Static localization-access only works for first locale instance. if used by another plugin, you need to
* access the Locale-Instance get-Method
*/
public static String L(String msg, Object... objects) {
return (inst != null) ? inst.get(msg, objects) : msg;
}
public static void unload() {
inst = null;
}
}

View file

@ -1,71 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.utils;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import de.jaschastarke.minecraft.limitedcreative.Core;
import de.jaschastarke.minecraft.worldedit.PermissionsBridge;
public class Permissions {
protected JavaPlugin plugin = null;
protected PermissionsBridge pif = null;
public Permissions(JavaPlugin plugin) {
this.plugin = plugin;
try {
if (Core.plugin.config.getWEPIFEnabled()) {
// because worldedit may be not loaded as plugin, just as library, we check that way
Class.forName("com.sk89q.wepif.PermissionsResolverManager", false, plugin.getClass().getClassLoader());
pif = new PermissionsBridge(plugin);
}
} catch (ClassNotFoundException e) {}
}
public boolean hasPermission(Player player, String permission) {
boolean ret = false;
if (pif != null) {
ret = pif.hasPermission(player, permission);
} else {
// bukkit permission fallback
ret = player.hasPermission(permission);
}
debug(player, permission, ret);
return ret;
}
public boolean hasPermission(CommandSender player, IPermission permission) {
return hasPermission(player, permission.toString());
}
public boolean hasPermission(CommandSender sender, String permission) {
if (sender instanceof Player) {
return hasPermission((Player) sender, permission);
} else {
debug(sender, permission, true);
return true;
}
}
private void debug(CommandSender player, String permission, boolean result) {
if (plugin instanceof Core && ((Core) plugin).config.getDebug())
Core.debug("hasPermission: " + player.getName() + " - " + permission + " - " + result);
}
}

View file

@ -1,129 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.bukkit.Location;
final public class Util {
public static int versionCompare(String vers1, String vers2) {
String[] v1 = vers1.split("\\.");
String[] v2 = vers2.split("\\.");
int i = 0;
while (i < v1.length && i < v2.length && v1[i].equals(v2[i])) {
i++;
}
if (i < v1.length && i < v2.length) {
int diff = new Integer(v1[i]).compareTo(new Integer(v2[i]));
return diff < 0 ? -1 : (diff == 0 ? 0 : 1);
}
return v1.length < v2.length ? -1 : (v1.length == v2.length ? 0 : 1);
}
public static void copyFile(InputStream is, File to) {
try {
if (to.getParentFile() != null && !to.getParentFile().exists())
to.getParentFile().mkdirs();
OutputStream os;
os = new FileOutputStream(to);
byte[] buffer = new byte[512];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
os.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void copyFile(File from, File to) {
try {
copyFile(new FileInputStream(from), to);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public static String join(String[] list, String sep, int from, int range) {
StringBuilder result = new StringBuilder();
for (int i = from; i >= 0 && i < from + range && i < list.length; i++) {
if (result.length() > 0)
result.append(sep);
result.append(list[i]);
}
return result.toString();
}
public static String join(String[] list, int from, int range) {
return join(list, " ", from, range);
}
public static String join(String[] list, int from) {
return join(list, " ", from, list.length - from);
}
public static String join(String[] list) {
return join(list, " ", 0, list.length);
}
public static String join(String[] list, String sep) {
return join(list, sep, 0, list.length);
}
public static String toString(Location loc) {
return "{X: "+loc.getBlockX()+", Y: "+loc.getBlockY()+", Z: "+loc.getBlockZ()+"}";
}
/**
* Compares 2 Version Strings
*
* Only Numbers are interpreted. Any non-numeric char separates sub-versions.
*
* @param v1 First version String
* @param v2 Version String to compare with
* @return -1 when v1 < v2; 1 when v1 > v2; 0 when equal
*/
public static int compareVersion(String v1, String v2) {
String[] ver1 = v1.split("[^0-9]+");
String[] ver2 = v2.split("[^0-9]+");
for (int i = 0; i < Math.min(ver1.length, ver2.length); i++) {
int diff = new Integer(ver1[i]).compareTo(new Integer(ver2[i]));
if (diff != 0)
return diff < 0 ? -1 : 1;
}
return ver1.length == ver2.length ? 0 : ver1.length < ver2.length ? -1 : 1;
/*String[] vals1 = v1.split("\\.");
String[] vals2 = v2.split("\\.");
int i=0;
while (i < vals1.length && i < vals2.length && vals1[i].equals(vals2[i])) {
i++;
}
if (i < vals1.length && i < vals2.length) {
int diff = new Integer(vals1[i]).compareTo(new Integer(vals2[i]));
return diff < 0 ? -1 : diff == 0 ? 0 : 1;
}
return vals1.length < vals2.length ? -1 : vals1.length == vals2.length ? 0 : 1;*/
}
}

View file

@ -1,34 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.worldedit;
import org.bukkit.OfflinePlayer;
import org.bukkit.plugin.java.JavaPlugin;
import com.sk89q.wepif.PermissionsResolverManager;
public class PermissionsBridge {
protected com.sk89q.wepif.PermissionsResolverManager pif;
public PermissionsBridge(JavaPlugin plugin) {
PermissionsResolverManager.initialize(plugin);
pif = PermissionsResolverManager.getInstance();
}
public boolean hasPermission(OfflinePlayer sender, String permission) {
return pif.hasPermission(sender, permission);
}
}

View file

@ -1,41 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.worldguard;
import org.bukkit.plugin.java.JavaPlugin;
/**
* This Namespace may be used as a Standalone-Plugin just providing the WorldGuard-API
* TODO: Not done yet
*/
@Deprecated // NOT READY YET
public class API extends JavaPlugin {
@Override
public void onDisable() {
// TODO Auto-generated method stub
}
@Override
public void onEnable() {
throw new IllegalArgumentException("Not yet supported");
// TODO Auto-generated method stub
}
}

View file

@ -1,202 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.worldguard;
import static de.jaschastarke.minecraft.utils.Locale.L;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandPermissionsException;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.InvalidFlagFormat;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.GlobalProtectedRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import de.jaschastarke.minecraft.utils.Util;
public class CCommand implements CommandExecutor {
public enum Action {
FLAG,
INFO
}
private CRegionManager rm;
private JavaPlugin plugin;
private WorldGuardPlugin wg;
public CCommand(JavaPlugin plugin, CRegionManager mgr, WorldGuardPlugin wg) {
this.plugin = plugin;
this.rm = mgr;
this.wg = wg;
}
public CCommand(JavaPlugin plugin, CRegionManager mgr) {
this.plugin = plugin;
this.rm = mgr;
this.wg = (WorldGuardPlugin) plugin.getServer().getPluginManager().getPlugin("WorldGuard");
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (args.length < 2) {
return false;
}
if (!wg.hasPermission(sender, "limitedcreative.regions")) {
sender.sendMessage(ChatColor.DARK_RED + L("exception.command.lackingpermission"));
return true;
}
Player player = sender instanceof Player ? (Player) sender : null;
World world = null;
Action act;
String rid;
try {
act = Action.valueOf(args[0].toUpperCase());
} catch (IllegalArgumentException e) {
return false;
}
String[] wr = args[1].split("#");
if (wr.length == 2) {
world = plugin.getServer().getWorld(wr[0]);
rid = wr[1];
} else {
rid = args[1];
if (player != null) {
world = player.getWorld();
} else {
sender.sendMessage(ChatColor.DARK_RED + L("command.worldguard.world_not_found"));
return true;
}
}
RegionManager mgr = wg.getGlobalRegionManager().get(world);
ProtectedRegion region = mgr.getRegion(rid);
if (region == null) {
if (rid.equalsIgnoreCase("__global__")) {
region = new GlobalProtectedRegion(rid);
mgr.addRegion(region);
} else {
sender.sendMessage(ChatColor.DARK_RED + L("command.worldguard.region_not_found"));
return true;
}
}
CRegion reg = rm.world(world).region(region);
try {
switch (act) {
case INFO:
onInfo(sender, player, reg);
return true;
case FLAG:
onFlag(sender, player, reg, args);
return true;
}
} catch (CommandException ex) { // worldedit command exception!
sender.sendMessage(ChatColor.DARK_RED + ex.getMessage());
return true;
}
return false;
}
private void onInfo(CommandSender sender, Player player, CRegion region) throws CommandPermissionsException {
/* not optimal yet
if (player != null) {
if (region.getProtectedRegion().isOwner(wg.wrapPlayer(player))) {
hasPermission(sender, Perms.INFO_OWN);
} else if (region.getProtectedRegion().isMember(wg.wrapPlayer(player))) {
hasPermission(sender, Perms.INFO_MEMBER);
} else {
hasPermission(sender, Perms.INFO);
}
} else {
hasPermission(sender, Perms.INFO);
}*/
/*
* WorldEdits intercepting Servers privates commandMap via Reflections realy sucks!
* Just because they are to lazy to add all the lines commands to plugin.yml
*/
Bukkit.getServer().dispatchCommand(sender, "region info "+region.getWorld().getName()+ " "+region.getProtectedRegion().getId());
StringBuilder list = new StringBuilder();
for (FlagValue data : region.getFlags()) {
if (list.length() > 0)
list.append(", ");
list.append(data.getFlag().getName());
list.append(": ");
list.append(data.getValue().toString());
}
sender.sendMessage(ChatColor.GREEN + L("command.worldguard.additional_flags") + ": " + list.toString());
}
private void onFlag(CommandSender sender, Player player, CRegion region, String[] args) {
if (args.length < 3) {
sender.sendMessage(ChatColor.DARK_RED + L("command.worldguard.no_flag_given"));
sender.sendMessage(ChatColor.DARK_RED + L("command.worldguard.available_flags") + ": " + FlagList.getStringListAvailableFlags(sender));
return;
}
String flagName = args[2];
String value = null;
Flag<?> flag = FlagList.getFlag(flagName);
if (args.length > 3 && args[3].equalsIgnoreCase("-g")) {
flag = flag.getRegionGroupFlag();
if (args.length > 4)
value = Util.join(args, 4);
} else {
if (args.length > 3)
value = Util.join(args, 3);
}
if (flag == null) {
sender.sendMessage(ChatColor.DARK_RED + L("command.worldguard.unknown_flag") + ": " + flagName);
sender.sendMessage(ChatColor.DARK_RED + L("command.worldguard.available_flags") + ": " + FlagList.getStringListAvailableFlags(sender));
return;
}
try {
if (value != null) {
region.setFlag(flag, flag.parseInput(wg, sender, value));
} else {
region.setFlag(flag, null);
}
} catch (InvalidFlagFormat e) {
sender.sendMessage(ChatColor.DARK_RED + e.getLocalizedMessage());
return;
}
CPlayer.updateAll();
sender.sendMessage(L("command.worldguard.flag_set", flag.getName()));
}
/*private boolean hasPermission(CommandSender sender, IPermission permission) throws CommandPermissionsException {
wg.checkPermission(sender, permission.toString());
return true;
}*/
}

View file

@ -1,60 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.worldguard;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import de.jaschastarke.minecraft.worldguard.events.PlayerUpdateAreaEvent;
public class CPlayer {
private static Map<String, CPlayer> players = new HashMap<String, CPlayer>();
public static CPlayer get(Player p) {
if (!players.containsKey(p.getName())) {
CPlayer pl = new CPlayer();
players.put(p.getName(), pl);
return pl;
} else {
return players.get(p.getName());
}
}
public static void remove(Player p) {
players.remove(p.getName());
}
private String hash = null;
public String getHash() {
return hash;
}
public void setHash(String hash) {
this.hash = hash;
}
public static void clear() {
players.clear();
}
public static void updateAll() {
for (Map.Entry<String, CPlayer> entry : players.entrySet()) {
Bukkit.getServer().getPluginManager().callEvent(new PlayerUpdateAreaEvent(entry.getKey(), entry.getValue().getHash()));
}
}
}

View file

@ -1,26 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.worldguard;
import java.util.List;
import com.sk89q.worldguard.protection.flags.Flag;
public interface Integration {
public List<Flag<?>> getFlags();
}

View file

@ -1,61 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.worldguard;
import java.io.File;
import org.bukkit.plugin.java.JavaPlugin;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
public class Interface {
//private JavaPlugin plugin;
private CRegionManager mgr;
private WorldGuardPlugin wg;
private static Interface _instance = null;
public Interface(JavaPlugin plugin) {
if (_instance != null)
throw new RuntimeException("The Interface is Singleton!");
//this.plugin = plugin;
_instance = this;
wg = (WorldGuardPlugin) plugin.getServer().getPluginManager().getPlugin("WorldGuard");
mgr = new CRegionManager(new File(plugin.getDataFolder(), "regions.yml"));
plugin.getCommand("/region").setExecutor(new CCommand(plugin, mgr, wg));
plugin.getServer().getPluginManager().registerEvents(new CListener(this), plugin);
}
public static Interface getInstance() {
return _instance;
}
public void register(Integration integration) {
FlagList.addFlags(integration.getFlags());
}
public WorldGuardPlugin getWorldGuard() {
return wg;
}
public CRegionManager getRegionManager() {
return mgr;
}
public static void unload() {
_instance = null;
}
}

View file

@ -1,38 +0,0 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.worldguard;
import de.jaschastarke.minecraft.utils.IPermission;
@Deprecated // NOT USED YET
public enum Perms implements IPermission {
INFO("info"),
INFO_OWN("info.own"),
INFO_MEMBER("info.member");
private static final String NS = "worldguard.region";
private String perm;
private Perms(String permission) {
perm = permission;
}
@Override
public String toString() {
return NS + SEP + perm;
}
}

View file

@ -0,0 +1,68 @@
package de.jaschastarke.minecraft.limitedcreative;
import de.jaschastarke.bukkit.lib.Core;
import de.jaschastarke.bukkit.lib.configuration.ConfigurationContainer;
import de.jaschastarke.bukkit.lib.configuration.PluginConfiguration;
import de.jaschastarke.configuration.IConfigurationNode;
import de.jaschastarke.configuration.InvalidValueException;
import de.jaschastarke.configuration.annotations.IsConfigurationNode;
import de.jaschastarke.maven.ArchiveDocComments;
import de.jaschastarke.maven.PluginConfigurations;
import de.jaschastarke.modularize.IModule;
import de.jaschastarke.modularize.ModuleEntry;
/**
* Limited Creative - Configuration
*
* (YAML-Syntax: http://en.wikipedia.org/wiki/YAML)
*
* This configuration-file is automatically written when changed via ingame-commands. So any manual added comments are
* removed.
*/
@ArchiveDocComments
@PluginConfigurations
public class Config extends PluginConfiguration {
public Config(ConfigurationContainer container) {
super(container);
}
public Config(Core plugin) {
super(plugin);
}
@Override
public void setValue(IConfigurationNode node, Object pValue) throws InvalidValueException {
super.setValue(node, pValue);
if (node.getName().equals("metrics")) {
ModuleEntry<IModule> metricsEntry = plugin.getModule(FeatureMetrics.class).getModuleEntry();
metricsEntry.setEnabled(getMetrics());
}
}
/**
* Metrics
*
* This settings allows the Addon-Author to track the Servers using this plugin. It will not track any player
* related data like names, ips, online time or such. Please do not disable the option! As more servers are using
* the plugin and the author knows, as more he is willing to support the plugin! Its a win-win for both.
*
* default: true
* @TODO Move to a sub-class modular configuration
*/
@IsConfigurationNode(order = 1000)
public boolean getMetrics() {
return config.getBoolean("metrics", true);
}
/**
* Debug
*
* The debug modus spams much details about the plugin to the server-log (console) which can help to solve issues.
*
* default: false
*/
@IsConfigurationNode(order = 9999)
public boolean getDebug() {
return config.getBoolean("debug", false);
}
}

View file

@ -0,0 +1,48 @@
package de.jaschastarke.minecraft.limitedcreative;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.event.server.PluginEnableEvent;
import de.jaschastarke.modularize.ModuleEntry.ModuleState;
/**
* @Todo may be abstract to some per-module-definitions that are checked onEnabled and here automaticly
*/
public class DependencyListener implements Listener {
private LimitedCreative plugin;
public DependencyListener(LimitedCreative plugin) {
this.plugin = plugin;
}
@EventHandler
public void onPluginLoaded(PluginEnableEvent event) {
ModInventories mod = plugin.getModule(ModInventories.class);
if (mod != null && mod.getModuleEntry().getState() == ModuleState.ENABLED) {
String incomp = Hooks.InventoryIncompatible.test();
if (incomp != null) {
mod.getLog().warn(plugin.getLocale().trans("inventory.warning.conflict", incomp, mod.getName()));
mod.getModuleEntry().deactivateUsage();
}
}
}
@EventHandler
public void onPluginUnloaded(PluginDisableEvent event) {
if (event.getPlugin().getName().equals("Vault")) {
ModGameModePerm mod = plugin.getModule(ModGameModePerm.class);
if (mod != null && mod.getModuleEntry().getState() == ModuleState.ENABLED) {
mod.getLog().warn(plugin.getLocale().trans("gmperm.warning.vault_not_found", mod.getName()));
mod.getModuleEntry().deactivateUsage();
}
} else if (event.getPlugin().getName().equals("WorldGuard")) {
ModRegions mod = plugin.getModule(ModRegions.class);
if (mod != null && mod.getModuleEntry().getState() == ModuleState.ENABLED) {
mod.getLog().warn(plugin.getLocale().trans("region.warning.worldguard_not_found", mod.getName()));
mod.getModuleEntry().deactivateUsage();
}
}
}
}

View file

@ -0,0 +1,141 @@
package de.jaschastarke.minecraft.limitedcreative;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.inventory.ItemStack;
import de.jaschastarke.bukkit.lib.CoreModule;
public class FeatureBlockItemSpawn extends CoreModule<LimitedCreative> implements Listener {
public FeatureBlockItemSpawn(LimitedCreative plugin) {
super(plugin);
}
private CleanUp cleanup = new CleanUp();
public final static long TICK_OFFSET = 1;
private List<BlockItemDrop> list = new ArrayList<BlockItemDrop>();
public boolean isBlocked(Location l, Material type) {
if (isDebug())
getLog().debug("Checking ItemBlocked: " + l.toString() + " - " + type.toString());
for (BlockItemDrop block : list) {
if (isDebug())
getLog().debug(" - " + block.toString());
if (block.getLocation().equals(l) && (block.getType() == null || block.getType().equals(type))) {
if (isDebug())
getLog().debug(" blocked!");
return true;
}
}
if (isDebug())
getLog().debug(" allowed");
return false;
}
private void scheduleCleanUp() {
if (cleanup.maxTime == 0) { // if not scheduled yet
cleanup.maxTime = System.currentTimeMillis();
Bukkit.getScheduler().runTaskLater(plugin, cleanup, TICK_OFFSET);
}
}
private class BlockItemDrop {
public BlockItemDrop(Location l, Material type) {
this.l = l;
this.type = type;
this.timestamp = System.currentTimeMillis();
}
private Location l;
private Material type;
private long timestamp;
public Location getLocation() {
return l;
}
public Material getType() {
return type;
}
public long getTimestamp() {
return timestamp;
}
public String toString() {
return Long.toString(timestamp) + ": " + l.toString() + (type != null ? " - " + type.toString() : "");
}
}
public void block(Block block, Player player) {
if (player.getInventory().getItemInMainHand().containsEnchantment(Enchantment.SILK_TOUCH)) {
block(block.getLocation(), block.getType());
} else {
// doesn't include silktouch
for (ItemStack i : block.getDrops(player.getInventory().getItemInMainHand())) {
block(block.getLocation(), i.getType());
}
}
}
public void block(Block block) {
block(block.getLocation());
}
public void block(Location l) {
list.add(new BlockItemDrop(l, null));
scheduleCleanUp();
}
public void block(Location l, Material type) {
list.add(new BlockItemDrop(l, type));
scheduleCleanUp();
}
public void block(Location l, ItemStack item) {
if (item != null)
block(l, item.getType());
}
@EventHandler(ignoreCancelled = true)
public void onItemSpawn(ItemSpawnEvent event) {
if (event.getEntity() != null) {
if (this.isBlocked(event.getLocation().getBlock().getLocation(), event.getEntity().getItemStack().getType())) {
event.setCancelled(true);
}
}
}
/**
* Don't default Plugin-debug to this mod. Because it is too spammy.
*/
public boolean isDebug() {
return debug;
}
private class CleanUp implements Runnable {
public long maxTime = 0;
@Override
public void run() {
if (plugin.isDebug())
plugin.getLog().debug("Scheduler: Synchronous Task run: Cleanup");
Iterator<BlockItemDrop> i = list.iterator();
while (i.hasNext()) {
BlockItemDrop block = i.next();
if (block.getTimestamp() <= maxTime) {
if (isDebug())
getLog().debug("Removing outdated BlokItemDrop: " + block.toString());
i.remove();
}
}
maxTime = 0;
if (list.size() > 0)
scheduleCleanUp();
}
}
}

View file

@ -0,0 +1,46 @@
package de.jaschastarke.minecraft.limitedcreative;
import de.jaschastarke.bukkit.lib.CoreModule;
import de.jaschastarke.modularize.IModule;
import de.jaschastarke.modularize.ModuleEntry;
import de.jaschastarke.modularize.ModuleEntry.ModuleState;
import org.bstats.bukkit.Metrics;
import org.bstats.charts.AdvancedPie;
import org.bukkit.event.Listener;
import java.util.HashMap;
public class FeatureMetrics extends CoreModule<LimitedCreative> implements Listener {
public FeatureMetrics(LimitedCreative plugin) {
super(plugin);
}
private Metrics bstats = null;
@Override
public void onEnable() {
super.onEnable();
if (bstats == null) {
bstats = new Metrics(plugin, 10413);
bstats.addCustomChart(new AdvancedPie("module_usage", () -> {
HashMap<String, Integer> ret = new HashMap<>();
for (final ModuleEntry<IModule> mod : plugin.getModules())
if (mod.getModule() instanceof CoreModule<?>)
ret.put(((CoreModule<?>) mod.getModule()).getName(), mod.getState() == ModuleState.ENABLED ? 1 : 0);
return ret;
}));
bstats.addCustomChart(new AdvancedPie("dependencies", () -> {
HashMap<String, Integer> ret = new HashMap<>();
for (final String dep : plugin.getDescription().getSoftDepend())
ret.put(dep, plugin.getServer().getPluginManager().isPluginEnabled(dep) ? 1 : 0);
return ret;
}));
}
}
@Override
public void onDisable() {
super.onDisable();
}
}

View file

@ -0,0 +1,155 @@
package de.jaschastarke.minecraft.limitedcreative;
import java.util.Arrays;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.World;
import org.bukkit.entity.Player;
import de.jaschastarke.IHasName;
import de.jaschastarke.bukkit.lib.CoreModule;
import de.jaschastarke.bukkit.lib.commands.AbstractCommandList;
import de.jaschastarke.bukkit.lib.commands.CommandContext;
import de.jaschastarke.bukkit.lib.commands.CommandException;
import de.jaschastarke.bukkit.lib.commands.ICommand;
import de.jaschastarke.bukkit.lib.commands.MethodCommand;
import de.jaschastarke.bukkit.lib.commands.IMethodCommandContainer;
import de.jaschastarke.bukkit.lib.commands.MissingPermissionCommandException;
import de.jaschastarke.bukkit.lib.commands.NeedsPlayerArgumentCommandException;
import de.jaschastarke.bukkit.lib.commands.annotations.Alias;
import de.jaschastarke.bukkit.lib.commands.annotations.Description;
import de.jaschastarke.bukkit.lib.commands.annotations.IsCommand;
import de.jaschastarke.bukkit.lib.commands.annotations.NeedsPermission;
import de.jaschastarke.bukkit.lib.commands.annotations.Usages;
import de.jaschastarke.bukkit.lib.commands.parser.TabCompletion;
import de.jaschastarke.minecraft.lib.permissions.IAbstractPermission;
import de.jaschastarke.minecraft.lib.permissions.IPermission;
import de.jaschastarke.modularize.ModuleEntry.ModuleState;
public class FeatureSwitchGameMode extends CoreModule<LimitedCreative> {
public FeatureSwitchGameMode(LimitedCreative plugin) {
super(plugin);
}
protected Commands commands = null;
@Override
public String getName() {
return "SwitchGameMode";
}
@Override
public void onEnable() {
super.onEnable();
if (commands == null)
commands = new Commands();
plugin.getMainCommand().getHandler().registerCommands(commands.getCommandList());
}
@Override
public void onDisable() {
super.onDisable();
if (commands != null)
plugin.getMainCommand().getHandler().removeCommands(commands.getCommandList());
}
public class Commands extends AbstractCommandList implements IMethodCommandContainer, IHasName {
private MethodCommand[] commands = MethodCommand.getMethodCommandsFor(this);
public List<ICommand> getCommandList() {
return Arrays.asList((ICommand[]) commands);
}
@Override
public String getName() {
return plugin.getName() + " - " + plugin.getLang().trans("basic.feature.gamemodecommands");
}
@Override
public IPermission getPermission(String subPerm) {
return SwitchGameModePermissions.ALL.getPermission(subPerm);
}
@SuppressWarnings("deprecation")
protected boolean changeGameMode(CommandContext context, String player, GameMode tgm, IAbstractPermission permission) throws MissingPermissionCommandException, CommandException {
Player target = null;
if (player != null && !player.isEmpty()) {
target = Bukkit.getPlayer(player);
if (target == null)
throw new CommandException("Player " + player + " not found");
} else if (context.isPlayer()) {
target = context.getPlayer();
}
if (target == null)
throw new NeedsPlayerArgumentCommandException();
if (!target.equals(context.getSender()) && !context.checkPermission(SwitchGameModePermissions.OTHER))
throw new MissingPermissionCommandException(SwitchGameModePermissions.OTHER);
GameMode wgm = this.getDefaultGameMode(target.getWorld());
if (!this.regionOptional(target, tgm)) {
if (!context.checkPermission(permission) && (wgm != tgm || !context.checkPermission(SwitchGameModePermissions.BACKONLY)))
throw new MissingPermissionCommandException(permission);
}
if (target.getGameMode() != tgm) {
target.setGameMode(tgm);
if (!context.isPlayer() || !target.equals(context.getPlayer())) {
context.response(context.getFormatter().getString("command.gamemode.changed", target.getName()));
}
} else {
context.response(context.getFormatter().getString("command.gamemode.no_change"));
}
return true;
}
private GameMode getDefaultGameMode(World world) {
return Hooks.DefaultWorldGameMode.get(world);
}
private boolean regionOptional(Player player, GameMode tgm) {
ModRegions mod = plugin.getModule(ModRegions.class);
return mod != null && mod.getModuleEntry().getState() == ModuleState.ENABLED
&& mod.getWorldGuardIntegration().isRegionOptional(player, tgm);
}
@IsCommand("survival")
@Alias("s")
@Description(value = "command.switch.survival", translate = true)
@NeedsPermission(value={"survival", "backonly"}, optional = true)
@Usages("[player]")
public boolean survival(CommandContext context, String player) throws MissingPermissionCommandException, CommandException {
return changeGameMode(context, player, GameMode.SURVIVAL, SwitchGameModePermissions.SURVIVAL);
}
@IsCommand("creative")
@Alias("c")
@Description(value = "command.switch.creative", translate = true)
@NeedsPermission(value={"creative", "backonly"}, optional = true)
@Usages("[player]")
public boolean creative(CommandContext context, String player) throws MissingPermissionCommandException, CommandException {
return changeGameMode(context, player, GameMode.CREATIVE, SwitchGameModePermissions.CREATIVE);
}
@IsCommand("adventure")
@Alias("a")
@Description(value = "command.switch.adventure", translate = true)
@NeedsPermission(value={"adventure", "backonly"}, optional = true)
@Usages("[player]")
public boolean adventure(CommandContext context, String player) throws MissingPermissionCommandException, CommandException {
return changeGameMode(context, player, GameMode.ADVENTURE, SwitchGameModePermissions.ADVENTURE);
}
@IsCommand("spectator")
@Alias("sp")
@Description(value = "command.switch.spectator", translate = true)
@NeedsPermission(value={"spectator", "backonly"}, optional = true)
@Usages("[player]")
public boolean spectator(CommandContext context, String player) throws MissingPermissionCommandException, CommandException {
return changeGameMode(context, player, GameMode.SPECTATOR, SwitchGameModePermissions.SPECTATOR);
}
@Override
public List<TabCompletion> getTabCompleter(MethodCommand cmd) {
return null;
}
}
}

View file

@ -0,0 +1,75 @@
package de.jaschastarke.minecraft.limitedcreative;
import de.jaschastarke.hooking.BooleanHooker;
import de.jaschastarke.hooking.GetHooker;
import de.jaschastarke.minecraft.limitedcreative.hooks.MultiVerseHooks;
import de.jaschastarke.minecraft.limitedcreative.hooks.PlayerCheckHooker;
import de.jaschastarke.minecraft.limitedcreative.hooks.WorldTypeHooker;
import de.jaschastarke.minecraft.limitedcreative.hooks.xAuthHooks;
import org.bukkit.Bukkit;
public final class Hooks {
public static PlayerCheckHooker IsLoggedIn = new PlayerCheckHooker(true);
public static WorldTypeHooker DefaultWorldGameMode = new WorldTypeHooker();
public static BooleanHooker IsMultiVerse = new BooleanHooker(false);
public static GetHooker<String> InventoryIncompatible = new GetHooker<String>();
public static boolean isPluginEnabled(String pluginName) {
return Bukkit.getServer().getPluginManager().isPluginEnabled(pluginName);
}
@SuppressWarnings("deprecation")
public static void inizializeHooks(LimitedCreative plugin) {
IsLoggedIn.clearHooks();
DefaultWorldGameMode.clearHooks();
IsMultiVerse.clearHooks();
InventoryIncompatible.clearHooks();
if (isAuthMePresent()) {
new de.jaschastarke.minecraft.limitedcreative.hooks.AuthMeHooks(plugin);
}
if (isXAuth20Present()) {
new xAuthHooks(plugin);
}
if (isPluginEnabled("Multiverse-Core")) {
new MultiVerseHooks(plugin);
}/* else if (isPluginEnabled("MultiWorld")) { // MultiWord suckz, the Creative-World-Setting doesn't affect anything
new MultiWorldHooks(plugin);
}*/
InventoryIncompatible.register(new GetHooker.Check<String>() {
@Override
public String test() {
if (isPluginEnabled("MultiInv"))
return "MultiInv";
if (isPluginEnabled("Multiverse-Inventories"))
return "Multiverse-Inventories";
return null;
}
});
}
public static boolean isAuthMePresent() {
if (isPluginEnabled("AuthMe")) {
try {
Class.forName("uk.org.whoami.authme.api.API");
return true;
} catch (ClassNotFoundException e) {
return false;
}
}
return false;
}
public static boolean isXAuth20Present() {
if (isPluginEnabled("xAuth")) {
try {
Class.forName("com.cypherx.xauth.xAuth");
return true;
} catch (ClassNotFoundException e) {
return false;
}
}
return false;
}
}

View file

@ -0,0 +1,76 @@
package de.jaschastarke.minecraft.limitedcreative;
import de.jaschastarke.I18n;
import de.jaschastarke.bukkit.lib.Core;
import de.jaschastarke.bukkit.lib.PluginLang;
import de.jaschastarke.bukkit.lib.configuration.command.ConfigCommand;
import de.jaschastarke.bukkit.lib.modules.AdditionalBlockBreaks;
import de.jaschastarke.bukkit.lib.modules.InstantHangingBreak;
import de.jaschastarke.utils.ClassDescriptorStorage;
public class LimitedCreative extends Core {
protected Config config = null;
protected MainCommand command = null;
@Override
public void onInitialize() {
super.onInitialize();
config = new Config(this);
setLang(new PluginLang("lang/messages", this));
command = new MainCommand(this);
ConfigCommand cc = new ConfigCommand(config, Permissions.CONFIG);
cc.setPackageName(this.getName() + " - " + this.getLocale().trans(cc.getPackageName()));
command.registerCommand(cc);
commands.registerCommand(command);
Hooks.inizializeHooks(this);
modules.addSharedModule(new AdditionalBlockBreaks(this));
modules.addSharedModule(new InstantHangingBreak(this));
modules.addSharedModule(new FeatureBlockItemSpawn(this));
addModule(new FeatureSwitchGameMode(this));
addModule(new ModInventories(this));
addModule(new ModCreativeLimits(this));
addModule(new ModRegions(this));
addModule(new ModCmdBlocker(this));
addModule(new ModGameModePerm(this));
addModule(new ModBlockStates(this));
addModule(new FeatureMetrics(this)).setDefaultEnabled(config.getMetrics());
listeners.addListener(new DependencyListener(this));
config.saveDefault();
try {
Class.forName("de.jaschastarke.hooking.CaptainHook");
} catch(Exception e) {}
}
@Override
public ClassDescriptorStorage getDocCommentStorage() {
if (cds == null) {
cds = new ClassDescriptorStorage();
cds.getResourceBundle().addResourceBundle("lang.doccomments");
}
return cds;
}
@Override
public boolean isDebug() {
return config.getDebug();
}
public Config getPluginConfig() {
return config;
}
public I18n getLocale() {
return getLang();
}
public MainCommand getMainCommand() {
return command;
}
}

View file

@ -0,0 +1,103 @@
package de.jaschastarke.minecraft.limitedcreative;
import java.util.List;
import de.jaschastarke.LocaleString;
import de.jaschastarke.bukkit.lib.commands.BukkitCommand;
import de.jaschastarke.bukkit.lib.commands.CommandContext;
import de.jaschastarke.bukkit.lib.commands.IHelpDescribed;
import de.jaschastarke.bukkit.lib.commands.IMethodCommandContainer;
import de.jaschastarke.bukkit.lib.commands.MethodCommand;
import de.jaschastarke.bukkit.lib.commands.annotations.Description;
import de.jaschastarke.bukkit.lib.commands.annotations.IsCommand;
import de.jaschastarke.bukkit.lib.commands.annotations.NeedsPermission;
import de.jaschastarke.bukkit.lib.commands.annotations.Usages;
import de.jaschastarke.bukkit.lib.commands.parser.TabCompletion;
import de.jaschastarke.maven.ArchiveDocComments;
import de.jaschastarke.maven.PluginCommand;
import de.jaschastarke.minecraft.lib.permissions.IAbstractPermission;
import de.jaschastarke.minecraft.lib.permissions.IPermission;
/**
* LimitedCreative: GameMode-Switch, Creative-Regions, Config and more
* @usage /<command> - displays LimitedCreative-Help
* @permission limitedcreative.command
*/
@ArchiveDocComments
@PluginCommand
public class MainCommand extends BukkitCommand implements IHelpDescribed, IMethodCommandContainer {
private LimitedCreative plugin;
public MainCommand() {
}
public MainCommand(LimitedCreative plugin) {
super(plugin);
this.plugin = plugin;
}
@Override
public String getName() {
return "limitedcreative";
}
@Override
public String[] getAliases() {
return new String[]{"lc"};
}
/**
* @internal has no effect, as not tested by any command handler
* @see IHelpDescribed
*/
@Override
public IAbstractPermission[] getRequiredPermissions() {
return new IAbstractPermission[]{Permissions.COMMAND};
}
@Override
public String[] getUsages() {
return null;
}
@Override
public CharSequence getDescription() {
return new LocaleString("command.general");
}
@Override
public String getPackageName() {
return plugin.getName();
}
@Override
public IPermission getPermission(String subPerm) {
return Permissions.CONTAINER.getPermission(subPerm);
}
@IsCommand("reload")
@Usages("")
@Description(value = "command.config.reload", translate = true)
@NeedsPermission(value={"config"})
public boolean doReload(final CommandContext context) {
plugin.getServer().getScheduler().runTask(plugin, new Runnable() {
@Override
public void run() {
if (plugin.isDebug())
plugin.getLog().debug("Scheduler: Synchronous Task run: Disable");
plugin.onDisable();
plugin.getPluginConfig().reload();
plugin.getServer().getScheduler().runTask(plugin, new Runnable() {
@Override
public void run() {
if (plugin.isDebug())
plugin.getLog().debug("Scheduler: Synchronous Task run: Enable");
plugin.onEnable();
context.response(context.getFormatter().getString("command.config.reload.success"));
}
});
}
});
return true;
}
@Override
public List<TabCompletion> getTabCompleter(MethodCommand cmd) {
return null;
}
}

View file

@ -0,0 +1,117 @@
package de.jaschastarke.minecraft.limitedcreative;
import org.bukkit.event.Listener;
import org.bukkit.scheduler.BukkitRunnable;
import com.sk89q.worldedit.WorldEdit;
import de.jaschastarke.bukkit.lib.CoreModule;
import de.jaschastarke.bukkit.lib.commands.AliasHelpedCommand;
import de.jaschastarke.bukkit.lib.modules.AdditionalBlockBreaks;
import de.jaschastarke.bukkit.lib.modules.BlockFall;
import de.jaschastarke.bukkit.lib.modules.InstantHangingBreak;
import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockListener;
import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockStateCommand;
import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockStateConfig;
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBModel;
import de.jaschastarke.minecraft.limitedcreative.blockstate.HangingStandingListener;
import de.jaschastarke.minecraft.limitedcreative.blockstate.PlayerListener;
import de.jaschastarke.minecraft.limitedcreative.blockstate.SyncronizedModel;
import de.jaschastarke.minecraft.limitedcreative.blockstate.ThreadedModel;
import de.jaschastarke.minecraft.limitedcreative.blockstate.worldedit.EditSessionListener;
import de.jaschastarke.modularize.IModule;
import de.jaschastarke.modularize.ModuleEntry;
public class ModBlockStates extends CoreModule<LimitedCreative> {
private BlockStateConfig config;
private FeatureBlockItemSpawn blockDrops;
private BlockStateCommand command;
private DBModel model;
public ModBlockStates(LimitedCreative plugin) {
super(plugin);
}
@Override
public String getName() {
return "BlockState";
}
@Override
public void initialize(ModuleEntry<IModule> entry) {
super.initialize(entry);
config = new BlockStateConfig(this, entry);
plugin.getPluginConfig().registerSection(config);
blockDrops = modules.linkSharedModule(FeatureBlockItemSpawn.class, plugin.getModules());
modules.linkSharedModule(AdditionalBlockBreaks.class, plugin.getModules());
modules.linkSharedModule(InstantHangingBreak.class, plugin.getModules());
this.addModule(new BlockFall(plugin));
listeners.addListener(new BlockListener(this));
listeners.addListener(new HangingStandingListener(this));
listeners.addListener(new PlayerListener(this));
command = new BlockStateCommand(this);
}
@Override
public void onEnable() {
try {
if (model == null) {
if (config.getUseThreading())
model = new ThreadedModel(this);
else
model = new SyncronizedModel(this);
}
if (model instanceof Listener)
listeners.addListener((Listener) model);
model.onEnable();
} catch (Exception e) {
e.printStackTrace();
getLog().warn(plugin.getLocale().trans("block_state.error.sql_connection_failed", getName()));
entry.deactivateUsage();
return;
}
super.onEnable();
if (plugin.getServer().getPluginManager().isPluginEnabled("WorldEdit") && config.getWorldeditIntegration()) {
new BukkitRunnable() {
@Override
public void run() {
try {
WorldEdit.getInstance().getEventBus().register(new EditSessionListener(ModBlockStates.this));
} catch (Exception e) {
getLog().warn(plugin.getLocale().trans("block_state.warning.worldedit_sessionfactory_failed", e.getMessage()));
}
}
}.runTaskLater(plugin, 1L);
}
plugin.getCommandHandler().registerCommand(command);
plugin.getMainCommand().registerCommand(new AliasHelpedCommand<BlockStateCommand>(command, "blockstate", new String[]{"bs"}));
getLog().info(plugin.getLocale().trans("basic.loaded.module"));
}
@Override
public void onDisable() {
if (model != null)
model.onDisable();
super.onDisable();
if (model != null && model instanceof Listener)
listeners.removeListener((Listener) model);
model = null;
plugin.getCommandHandler().removeCommand(command);
plugin.getMainCommand().removeCommand(command);
}
public BlockStateConfig getConfig() {
return config;
}
public FeatureBlockItemSpawn getBlockSpawn() {
return blockDrops;
}
public DBModel getModel() {
return model;
}
}

View file

@ -0,0 +1,35 @@
package de.jaschastarke.minecraft.limitedcreative;
import de.jaschastarke.bukkit.lib.CoreModule;
import de.jaschastarke.minecraft.limitedcreative.cmdblocker.CmdBlockerConfig;
import de.jaschastarke.minecraft.limitedcreative.cmdblocker.CommandListener;
import de.jaschastarke.modularize.IModule;
import de.jaschastarke.modularize.ModuleEntry;
public class ModCmdBlocker extends CoreModule<LimitedCreative> {
private CmdBlockerConfig config;
public ModCmdBlocker(LimitedCreative plugin) {
super(plugin);
}
@Override
public String getName() {
return "CmdBlocker";
}
@Override
public void initialize(ModuleEntry<IModule> entry) {
super.initialize(entry);
listeners.addListener(new CommandListener(this));
config = new CmdBlockerConfig(this, entry);
plugin.getPluginConfig().registerSection(config);
}
@Override
public void onEnable() {
super.onEnable();
getLog().info(plugin.getLocale().trans("basic.loaded.module"));
}
public CmdBlockerConfig getConfig() {
return config;
}
}

View file

@ -0,0 +1,64 @@
package de.jaschastarke.minecraft.limitedcreative;
import de.jaschastarke.bukkit.lib.CoreModule;
import de.jaschastarke.bukkit.lib.modules.AdditionalBlockBreaks;
import de.jaschastarke.bukkit.lib.modules.InstantHangingBreak;
import de.jaschastarke.minecraft.limitedcreative.limits.BlockListener;
import de.jaschastarke.minecraft.limitedcreative.limits.EntityListener;
import de.jaschastarke.minecraft.limitedcreative.limits.EntityNoDrop;
import de.jaschastarke.minecraft.limitedcreative.limits.LimitConfig;
import de.jaschastarke.minecraft.limitedcreative.limits.PlayerListener;
import de.jaschastarke.minecraft.limitedcreative.limits.VehicleListener;
import de.jaschastarke.modularize.IModule;
import de.jaschastarke.modularize.ModuleEntry;
public class ModCreativeLimits extends CoreModule<LimitedCreative> {
protected LimitConfig config;
private EntityNoDrop noDropsMobs = null;
public ModCreativeLimits(LimitedCreative plugin) {
super(plugin);
}
protected FeatureBlockItemSpawn blockDrops = null;
@Override
public String getName() {
return "Limits";
}
@Override
public void initialize(ModuleEntry<IModule> entry) {
super.initialize(entry);
listeners.addListener(new PlayerListener(this));
listeners.addListener(new EntityListener(this));
listeners.addListener(new BlockListener(this));
listeners.addListener(new VehicleListener(this));
config = plugin.getPluginConfig().registerSection(new LimitConfig(this, entry));
blockDrops = modules.linkSharedModule(FeatureBlockItemSpawn.class, plugin.getModules());
modules.linkSharedModule(AdditionalBlockBreaks.class, plugin.getModules());
modules.linkSharedModule(InstantHangingBreak.class, plugin.getModules());
}
public FeatureBlockItemSpawn getBlockSpawn() {
return blockDrops;
}
@Override
public void onEnable() {
super.onEnable();
getLog().info(plugin.getLocale().trans("basic.loaded.module"));
}
public LimitConfig getConfig() {
return config;
}
public EntityNoDrop getNoDropMobs() {
if (noDropsMobs == null)
noDropsMobs = new EntityNoDrop();
return noDropsMobs;
}
}

View file

@ -0,0 +1,67 @@
package de.jaschastarke.minecraft.limitedcreative;
import de.jaschastarke.bukkit.lib.CoreModule;
import de.jaschastarke.minecraft.limitedcreative.gmperm.GMPermConfig;
import de.jaschastarke.minecraft.limitedcreative.gmperm.PermissionInterface;
import de.jaschastarke.minecraft.limitedcreative.gmperm.PlayerListener;
import de.jaschastarke.modularize.IModule;
import de.jaschastarke.modularize.ModuleEntry;
public class ModGameModePerm extends CoreModule<LimitedCreative> {
private GMPermConfig config;
private PermissionInterface permission = null;
public ModGameModePerm(LimitedCreative plugin) {
super(plugin);
}
@Override
public String getName() {
return "GameModePerm";
}
@Override
public void initialize(ModuleEntry<IModule> entry) {
super.initialize(entry);
listeners.addListener(new PlayerListener(this));
config = new GMPermConfig(this, entry);
plugin.getPluginConfig().registerSection(config);
if (!plugin.getServer().getPluginManager().isPluginEnabled("Vault")) {
if (config.getEnabled())
getLog().warn(plugin.getLocale().trans("gmperm.warning.vault_not_found", getName()));
entry.deactivateUsage();
return;
}
permission = new PermissionInterface(this);
if (config.getEnabled()) {
if (!permission.isPresent()) {
getLog().warn(plugin.getLocale().trans("gmperm.warning.vault_not_found", getName()));
entry.deactivateUsage();
return;
} /*else if (!getVaultPermission().hasGroupSupport()) {
getLog().warn(plugin.getLocale().trans("gmperm.warning.no_group_support", getName()));
entry.initialState = ModuleState.NOT_INITIALIZED;
return;
}*/
}
}
@Override
public void onEnable() {
super.onEnable();
getLog().info(plugin.getLocale().trans("basic.loaded.module"));
}
@Override
public void onDisable() {
super.onDisable();
permission.clear();
}
public GMPermConfig getConfig() {
return config;
}
public PermissionInterface getPermissionInterface() {
return permission;
}
}

View file

@ -0,0 +1,135 @@
package de.jaschastarke.minecraft.limitedcreative;
import de.jaschastarke.bukkit.lib.CoreModule;
import de.jaschastarke.minecraft.limitedcreative.inventories.*;
import de.jaschastarke.minecraft.limitedcreative.inventories.store.PlayerInventoryStorage;
import de.jaschastarke.minecraft.limitedcreative.inventories.store.ReflectionStorage;
import de.jaschastarke.modularize.IModule;
import de.jaschastarke.modularize.ModuleEntry;
import org.bukkit.GameMode;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.io.File;
import java.util.Map;
import java.util.WeakHashMap;
public class ModInventories extends CoreModule<LimitedCreative> {
protected PlayerInventoryStorage storage;
protected Map<Player, Inventory> inventories;
protected InventoryConfig config;
protected ArmoryConfig armor_config;
public ModInventories(LimitedCreative plugin) {
super(plugin);
}
@Override
public String getName() {
return "Inventory";
}
@Override
public void initialize(ModuleEntry<IModule> entry) {
super.initialize(entry);
listeners.addListener(new PlayerListener(this));
config = plugin.getPluginConfig().registerSection(new InventoryConfig(this, entry));
armor_config = config.registerSection(new ArmoryConfig(this));
if (Hooks.isAuthMePresent()) {
addModule(new de.jaschastarke.minecraft.limitedcreative.inventories.AuthMeInventories(plugin, this));
}
String incomp = Hooks.InventoryIncompatible.test();
if (config.getEnabled() && incomp != null) {
getLog().warn(plugin.getLocale().trans("inventory.warning.conflict", incomp, this.getName()));
entry.deactivateUsage();
}
}
@Override
public void onEnable() {
String incomp = Hooks.InventoryIncompatible.test();
if (incomp != null) {
throw new IllegalAccessError(plugin.getLocale().trans("inventory.warning.conflict", incomp, this.getName()));
}
super.onEnable();
//storage = new InvYamlStorage(this, new File(plugin.getDataFolder(), config.getFolder()));
storage = new ReflectionStorage(this, new File(plugin.getDataFolder(), config.getFolder()));
inventories = new WeakHashMap<Player, Inventory>();
getLog().info(plugin.getLocale().trans("basic.loaded.module"));
}
public InventoryConfig getConfig() {
return config;
}
public ArmoryConfig getArmorConfig() {
return armor_config;
}
public PlayerInventoryStorage getStorage() {
return storage;
}
public Inventory getInventory(Player player) {
if (inventories.containsKey(player)) {
return inventories.get(player);
} else {
Inventory inv = new Inventory(storage, player);
inventories.put(player, inv);
return inv;
}
}
public void onSetGameMode(Player player, GameMode gm) {
if (plugin.getPermManager().hasPermission(player, InventoryPermissions.KEEP_INVENTORY))
return;
player.closeInventory();
GameMode cgm = player.getGameMode();
if (gm == GameMode.ADVENTURE && !config.getSeparateAdventure())
gm = GameMode.SURVIVAL;
else if (gm == GameMode.SPECTATOR)
gm = GameMode.CREATIVE;
if (cgm == GameMode.ADVENTURE && !config.getSeparateAdventure())
cgm = GameMode.SURVIVAL;
else if (cgm == GameMode.SPECTATOR)
cgm = GameMode.CREATIVE;
if (gm != cgm) {
if (gm != GameMode.CREATIVE || config.getStoreCreative()) {
getInventory(player).save(cgm);
}
if (gm == GameMode.CREATIVE) {
if (config.getStoreCreative() && getInventory(player).isStored(GameMode.CREATIVE)) {
getInventory(player).load(GameMode.CREATIVE);
} else {
getInventory(player).clear();
}
setCreativeArmor(player);
} else if (gm == GameMode.SURVIVAL) {
if (getInventory(player).isStored(GameMode.SURVIVAL))
getInventory(player).load(GameMode.SURVIVAL);
} else if (gm == GameMode.ADVENTURE) {
if (getInventory(player).isStored(GameMode.ADVENTURE))
getInventory(player).load(GameMode.ADVENTURE);
else
getInventory(player).clear();
}
}
}
public void setCreativeArmor(Player player) {
if (!getPlugin().getPermManager().hasPermission(player, InventoryPermissions.BYPASS_CREATIVE_ARMOR)) {
Map<String, ItemStack> armor = armor_config.getCreativeArmor();
if (armor != null) {
ItemStack[] is = new ItemStack[4];
if (armor.containsKey("feet"))
is[0] = armor.get("feet");
if (armor.containsKey("legs"))
is[1] = armor.get("legs");
if (armor.containsKey("chest"))
is[2] = armor.get("chest");
if (armor.containsKey("head"))
is[3] = armor.get("head");
player.getInventory().setArmorContents(is);
}
}
}
}

View file

@ -0,0 +1,113 @@
package de.jaschastarke.minecraft.limitedcreative;
import java.io.File;
import org.bukkit.entity.Player;
import de.jaschastarke.bukkit.lib.CoreModule;
import de.jaschastarke.bukkit.lib.commands.AliasHelpedCommand;
import de.jaschastarke.minecraft.limitedcreative.regions.BlockListener;
import de.jaschastarke.minecraft.limitedcreative.regions.IWorldGuardIntegration;
import de.jaschastarke.minecraft.limitedcreative.regions.PlayerData;
import de.jaschastarke.minecraft.limitedcreative.regions.PlayerListener;
import de.jaschastarke.minecraft.limitedcreative.regions.RegionConfig;
import de.jaschastarke.minecraft.limitedcreative.regions.RegionListener;
import de.jaschastarke.minecraft.limitedcreative.regions.RegionsCommand;
import de.jaschastarke.minecraft.limitedcreative.regions.WorldGuardIntegration;
import de.jaschastarke.minecraft.limitedcreative.regions.worldguard.CustomRegionManager;
import de.jaschastarke.minecraft.limitedcreative.regions.worldguard.PlayerRegionListener;
import de.jaschastarke.modularize.IModule;
import de.jaschastarke.modularize.ModuleEntry;
public class ModRegions extends CoreModule<LimitedCreative> {
private CustomRegionManager mgr;
private IWorldGuardIntegration wg;
private PlayerData pdata;
private FeatureBlockItemSpawn blockDrops = null;
private RegionConfig config;
private RegionsCommand command;
public ModRegions(LimitedCreative plugin) {
super(plugin);
}
@Override
public String getName() {
return "Regions";
}
@Override
public void initialize(ModuleEntry<IModule> pEntry) {
super.initialize(pEntry);
blockDrops = modules.linkSharedModule(FeatureBlockItemSpawn.class, plugin.getModules());
config = plugin.getPluginConfig().registerSection(new RegionConfig(this, entry));
if (!plugin.getServer().getPluginManager().isPluginEnabled("WorldGuard")) {
if (config.getEnabled())
getLog().warn(plugin.getLocale().trans("region.warning.worldguard_not_found", getName()));
entry.deactivateUsage();
return;
}
command = new RegionsCommand(this);
listeners.addListener(new PlayerListener(this));
listeners.addListener(new BlockListener(this));
listeners.addListener(new RegionListener(this));
listeners.addListener(new PlayerRegionListener(this)); // Fires Custom-Events listen by RegionListener
getWorldGuardIntegration().initFlagList();
}
public IWorldGuardIntegration getWorldGuardIntegration() {
if (wg == null) {
wg = new WorldGuardIntegration(this);
}
return wg;
}
@Override
public void onEnable() {
super.onEnable();
mgr = new CustomRegionManager(new File(plugin.getDataFolder(), "regions.yml"), this);
/*wg = (WorldGuardPlugin) plugin.getServer().getPluginManager().getPlugin("WorldGuard");
if (wg == null)
throw new IllegalAccessError("Missing Plugin WorldGuard");*/
plugin.getCommandHandler().registerCommand(command);
plugin.getMainCommand().registerCommand(new AliasHelpedCommand<RegionsCommand>(command, "region", new String[]{"r"}));
pdata = new PlayerData(this);
getLog().info(plugin.getLocale().trans("basic.loaded.module"));
}
@Override
public void onDisable() {
super.onDisable();
plugin.getCommandHandler().removeCommand(command);
plugin.getMainCommand().removeCommand(command);
}
public RegionConfig getConfig() {
return config;
}
/*public WorldGuardPlugin getWorldGuard() {
return wg;
}*/
public CustomRegionManager getRegionManager() {
return mgr;
}
public PlayerData getPlayerData() {
return pdata;
}
public PlayerData.Data getPlayerData(Player player) {
return pdata.getData(player);
}
public FeatureBlockItemSpawn getBlockSpawn() {
return blockDrops;
}
}

View file

@ -0,0 +1,47 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.limitedcreative;
import org.bukkit.permissions.PermissionDefault;
import de.jaschastarke.maven.ArchiveDocComments;
import de.jaschastarke.maven.PluginPermissions;
import de.jaschastarke.minecraft.lib.permissions.BasicPermission;
import de.jaschastarke.minecraft.lib.permissions.IPermission;
import de.jaschastarke.minecraft.lib.permissions.SimplePermissionContainerNode;
@ArchiveDocComments
public class Permissions extends SimplePermissionContainerNode {
protected Permissions(String name) {
super(name);
}
@PluginPermissions
public final static Permissions CONTAINER = new Permissions("limitedcreative");
/**
* Allows changing plugin configuration ingame via commands
*/
public static final IPermission CONFIG = new BasicPermission(CONTAINER, "config", PermissionDefault.OP);
/**
* Needed for any player that want's to use the /lc or /limitedcreative-command. If not granted, the user shouldn't
* see the command in /help, but he also isn't able to use the /lc c-gamemode commands, even if switch_gamemode
* is granted.
*/
public static final IPermission COMMAND = new BasicPermission(CONTAINER, "command", PermissionDefault.OP);
}

View file

@ -0,0 +1,59 @@
package de.jaschastarke.minecraft.limitedcreative;
import org.bukkit.permissions.PermissionDefault;
import de.jaschastarke.maven.ArchiveDocComments;
import de.jaschastarke.maven.PluginPermissions;
import de.jaschastarke.minecraft.lib.permissions.BasicPermission;
import de.jaschastarke.minecraft.lib.permissions.IAbstractPermission;
import de.jaschastarke.minecraft.lib.permissions.IsChildPermission;
import de.jaschastarke.minecraft.lib.permissions.ParentPermissionContainerNode;
@ArchiveDocComments
public class SwitchGameModePermissions extends ParentPermissionContainerNode {
/**
* Allows switching of own game mode to creative/adventure and back
*/
@PluginPermissions
public final static SwitchGameModePermissions ALL = new SwitchGameModePermissions(Permissions.CONTAINER, "switch_gamemode");
protected SwitchGameModePermissions(IAbstractPermission parent, String name) {
super(parent, name);
}
@Override
public PermissionDefault getDefault() {
return PermissionDefault.OP;
}
/**
* Allows switching of own game mode to default of the not world he is in, but not to an other
*/
public final static BasicPermission BACKONLY = new BasicPermission(ALL, "backonly", PermissionDefault.FALSE);
/**
* Allows switching of own game mode to survival, but not to creative/adventure
*/
@IsChildPermission
public final static BasicPermission SURVIVAL = new BasicPermission(ALL, "survival", PermissionDefault.FALSE);
/**
* Allows switching of own game mode to creative, but not to survival/adventure
*/
@IsChildPermission
public final static BasicPermission CREATIVE = new BasicPermission(ALL, "creative", PermissionDefault.FALSE);
/**
* Allows switching of own game mode to adventure, but not to creative/survival
*/
@IsChildPermission
public final static BasicPermission ADVENTURE = new BasicPermission(ALL, "adventure", PermissionDefault.FALSE);
/**
* Allows switching of own game mode to spectator, but not to creative/survival/adventure
*/
@IsChildPermission
public final static BasicPermission SPECTATOR = new BasicPermission(ALL, "spectator", PermissionDefault.FALSE);
/**
* Allows switching of other users game mode
*/
public final static BasicPermission OTHER = new BasicPermission(ALL, "other", PermissionDefault.OP);
}

View file

@ -0,0 +1,87 @@
package de.jaschastarke.minecraft.limitedcreative.blockstate;
import java.util.List;
import org.bukkit.block.Block;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.metadata.MetadataValue;
import org.bukkit.metadata.Metadatable;
import org.bukkit.plugin.Plugin;
public abstract class AbstractModel {
protected static final String BSMDKEY = "blockstate";
protected MetadataValue metadataNull;
private Plugin plugin;
protected AbstractModel(Plugin plugin) {
this.plugin = plugin;
metadataNull = new FixedMetadataValue(plugin, new Boolean(null));
}
protected void moveMetaState(Block from, Block to) {
HasBlockState metaBlock = getMetaBlock(from);
if (metaBlock.isSet() && metaBlock.getState() != null) {
BlockState state = metaBlock.state;
state.setLocation(to.getLocation());
setMetaBlock(to, state);
} else {
removeMetaBlock(to);
}
setMetaBlock(from, null);
}
protected boolean hasMetaBlock(Metadatable m) {
List<MetadataValue> metadata = m.getMetadata(BSMDKEY);
for (MetadataValue v : metadata) {
if (v.value() instanceof BlockState)
return true;
}
return false;
}
protected void setMetaBlock(Metadatable m, BlockState s) {
if (s == null)
m.setMetadata(BSMDKEY, metadataNull);
else
m.setMetadata(BSMDKEY, new FixedMetadataValue(plugin, s));
}
protected HasBlockState getMetaBlock(Metadatable m) {
HasBlockState has = null;
List<MetadataValue> metadata = m.getMetadata(BSMDKEY);
for (MetadataValue v : metadata) {
if (v.value() instanceof BlockState) {
has = new HasBlockState((BlockState) v.value());
break;
} else if (v == metadataNull) {
// Metadata Knows, that there is no entry in DB
has = new HasBlockState(true);
break;
}
}
if (has == null)
return new HasBlockState(false);
else
return has;
}
protected void removeMetaBlock(Metadatable m) {
m.removeMetadata(BSMDKEY, plugin);
}
public static class HasBlockState {
private boolean set = false;
private BlockState state = null;
public HasBlockState(BlockState state) {
set = true;
this.state = state;
}
public HasBlockState(boolean isSet) {
set = isSet;
}
public boolean isSet() {
return set;
}
public BlockState getState() {
return state;
}
}
}

View file

@ -0,0 +1,186 @@
package de.jaschastarke.minecraft.limitedcreative.blockstate;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.FallingBlock;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPistonExtendEvent;
import org.bukkit.event.block.BlockPistonRetractEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityChangeBlockEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.metadata.MetadataValue;
import de.jaschastarke.bukkit.lib.events.BlockDestroyedEvent;
import de.jaschastarke.bukkit.lib.events.BlockMovedEvent;
import de.jaschastarke.minecraft.limitedcreative.ModBlockStates;
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBModel.DBTransaction;
public class BlockListener implements Listener {
private final static String FALLING_ENTITY_BSMDKEY = "blockstate";
private ModBlockStates mod;
private MetadataValue blockAlreadExtended;
public BlockListener(ModBlockStates mod) {
this.mod = mod;
blockAlreadExtended = new FixedMetadataValue(mod.getPlugin(), new Boolean(true));
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBlockBreak(BlockBreakEvent event) {
if (mod.getConfig().getIgnoredWorlds().contains(event.getBlock().getWorld().getName()))
return;
if (mod.getModel().isRestricted(event.getBlock())) {
if (mod.isDebug())
mod.getLog().debug("Breaking bad, err.. block: " + event.getBlock().getLocation().toString() + " was placed by creative. Drop prevented");
if (event.getPlayer().getGameMode() != GameMode.CREATIVE) {
mod.getBlockSpawn().block(event.getBlock(), event.getPlayer());
event.setExpToDrop(0);
}
}
mod.getModel().removeState(event.getBlock());
}
@EventHandler
public void onOtherBlockDestroy(BlockDestroyedEvent event) {
if (mod.getConfig().getIgnoredWorlds().contains(event.getBlock().getWorld().getName()))
return;
if (mod.getModel().isRestricted(event.getBlock())) {
if (mod.isDebug())
mod.getLog().debug("Breaking attached block: " + event.getBlock().getLocation().toString() + " was placed by creative. Drop prevented");
mod.getBlockSpawn().block(event.getBlock());
}
mod.getModel().removeState(event.getBlock());
}
@EventHandler
public void onBlockMoved(BlockMovedEvent event) {
if (mod.getConfig().getIgnoredWorlds().contains(event.getBlock().getWorld().getName()))
return;
for (MetadataValue md : event.getEntity().getMetadata(FALLING_ENTITY_BSMDKEY)) {
if (md.value() instanceof BlockState) {
BlockState bs = (BlockState) md.value();
// The state of the source block should be always be cached yet, as we either asked it before, or
// it was just placed
if (bs != mod.getModel().getState(event.getSource())) {
bs.setLocation(event.getBlock().getLocation());
mod.getModel().setState(bs);
return;
}
}
}
mod.getModel().moveState(event.getSource(), event.getBlock());
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onEntityChangeBlock(final EntityChangeBlockEvent event) {
if (event.getEntityType() == EntityType.FALLING_BLOCK) {
if (event.getTo() == Material.AIR) {
if (mod.getModel().isRestricted(event.getBlock())) {
if (mod.isDebug())
mod.getLog().debug("Falling block: " + event.getBlock().getLocation().toString() + " was placed by creative (drop prevented)");
FallingBlock fe = (FallingBlock) event.getEntity();
fe.setDropItem(false);
// Using getState to fetch the full state from database synchronous isn't optimal, but either it is
// cached, as it was just placed, or it isn't that important, as it is a rare event
fe.setMetadata(FALLING_ENTITY_BSMDKEY, new FixedMetadataValue(mod.getPlugin(), mod.getModel().getState(event.getBlock())));
}
}
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBlocksBreakByExplosion(EntityExplodeEvent event) {
if (mod.getConfig().getIgnoredWorlds().contains(event.getLocation().getWorld().getName()))
return;
Map<Block, Boolean> states = mod.getModel().getRestrictedStates(event.blockList());
DBTransaction update = mod.getModel().groupUpdate();
for (Block block : event.blockList()) {
if (mod.isDebug())
mod.getLog().debug("Breaking bad, err.. block by explosion: " + block.getLocation().toString());
if (states.get(block)) {
if (mod.isDebug())
mod.getLog().debug("... was placed by creative. Drop prevented");
mod.getBlockSpawn().block(block);
}
update.removeState(block);
}
update.finish();
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onBlockPlace(BlockPlaceEvent event) {
if (mod.getConfig().getIgnoredWorlds().contains(event.getBlock().getWorld().getName()))
return;
BlockState s = new BlockState();
s.setLocation(event.getBlock().getLocation());
s.setPlayer(event.getPlayer());
s.setDate(new Date());
if (mod.isDebug())
mod.getLog().debug("Saving BlockState: " + s.toString());
mod.getModel().setState(s);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPistionExtend(BlockPistonExtendEvent event) {
if (mod.getConfig().getIgnoredWorlds().contains(event.getBlock().getWorld().getName()))
return;
if (event.getBlock().getMetadata("LCBS_pistonIsAlreadyExtended").size() > 0) // Fixes long known Bukkit issue
return;
event.getBlock().setMetadata("LCBS_pistonIsAlreadyExtended", blockAlreadExtended);
/*if (mod.isDebug())
mod.getLog().debug("PistonExtend "+source.getType()+" "+source.getLocation()+" "+event.getDirection());*/
List<Block> movedBlocks = event.getBlocks();
if (movedBlocks.size() > 0) {
DBTransaction update = mod.getModel().groupUpdate();
for(int count = movedBlocks.size()-1; count >= 0; count--){
Block sblock = movedBlocks.get(count);
Block dest = sblock.getRelative(event.getDirection());
if (mod.isDebug())
mod.getLog().debug("PistionExtend moves "+sblock.getType()+"-Block from "+sblock.getLocation()+" to "+dest.getLocation());
update.moveState(sblock, dest);
}
update.finish();
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPistionRetract(BlockPistonRetractEvent event) {
if (mod.getConfig().getIgnoredWorlds().contains(event.getBlock().getWorld().getName()))
return;
event.getBlock().removeMetadata("LCBS_pistonIsAlreadyExtended", mod.getPlugin());
List<Block> movedBlocks = event.getBlocks();
if(movedBlocks.size() > 0)
{
DBTransaction update = mod.getModel().groupUpdate();
for(int count = movedBlocks.size()-1; count >= 0; count--){
Block sblock = movedBlocks.get(count);
Block dest = sblock.getRelative(event.getDirection());
if (mod.isDebug())
mod.getLog().debug("PistionRetract moves "+sblock.getType()+"-Block from "+sblock.getLocation()+" to "+dest.getLocation());
update.moveState(sblock, dest);
}
update.finish();
}
}
}

View file

@ -0,0 +1,141 @@
package de.jaschastarke.minecraft.limitedcreative.blockstate;
import java.util.Date;
import java.util.UUID;
import javax.persistence.Column;
//import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
//import javax.persistence.IdClass;
import javax.persistence.Table;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import com.avaje.ebean.validation.NotNull;
/**
* @TODO: A Database Table-Generation based on Annotations (much work). all those Annotations here have not effect yet
*/
@Entity
@Table(name = "block_state")
//@IdClass(BlockLocation.class)
public class BlockState {
public static enum Source {
SEED, // There is no way to determine this source, but lets be prepared for miracles ;)
PLAYER,
EDIT, // WorldEdit or MCEdit or such, we also can't determine that. But I keep believing in miracles
COMMAND, // Manual Databse-Change via. BlockState-Command
UNKNOWN
}
private Location location;
@Column(name = "gm")
private GameMode gameMode;
@Column(name = "player")
private UUID uuid;
@NotNull
@Column(name = "cdate")
private Date date;
@NotNull
private Source source = Source.UNKNOWN;
public BlockState() {
}
public BlockState(BlockState copy) {
this.location = copy.location;
this.gameMode = copy.gameMode;
this.uuid = copy.uuid;
this.date = copy.date;
this.source = copy.source;
}
public Location getLocation() {
return location;
}
public void setLocation(Location loc) {
location = loc;
}
public GameMode getGameMode() {
return gameMode;
}
public void setGameMode(GameMode gm) {
this.gameMode = gm;
}
public UUID getPlayerUUID() {
return uuid;
}
public String getPlayerName() {
return Bukkit.getOfflinePlayer(uuid).getName();
}
//TODO Rename
@SuppressWarnings("deprecation")
public void setPlayerNameOrUUID(String s) {
if(s==null)
uuid=null;
else if(!s.matches("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"))
uuid = Bukkit.getOfflinePlayer(s).getUniqueId(); //If it's a name, get UUID
else
uuid = UUID.fromString(s);
}
public OfflinePlayer getPlayer() {
OfflinePlayer p = Bukkit.getPlayer(uuid);
if (p == null)
p = Bukkit.getOfflinePlayer(uuid);
return p;
}
public void setPlayer(OfflinePlayer player) {
setSource(Source.PLAYER);
this.uuid = player.getUniqueId();
if (player instanceof Player) {
setGameMode(((Player) player).getGameMode());
}
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public Source getSource() {
return source;
}
public void setSource(Source source) {
if (source != Source.PLAYER && source != Source.EDIT && source != Source.COMMAND)
setPlayerNameOrUUID(null);
this.source = source;
}
public boolean isRestricted() {
return this.getGameMode() == GameMode.CREATIVE || this.getSource() == Source.EDIT;
}
@Override
public String toString() {
String playerName = Bukkit.getOfflinePlayer(uuid).getName();
//return blockLocation.toString() + " by " +
return location.toString() + " by " +
(source == Source.PLAYER ? playerName : (source.toString() + (playerName != null ? "(" + playerName + ")" : ""))) +
(gameMode != null ? "" : (" in GM: " + gameMode)) +
" at " + date.toString();
}
}

View file

@ -0,0 +1,285 @@
package de.jaschastarke.minecraft.limitedcreative.blockstate;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.BukkitPlayer;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.World;
import de.jaschastarke.LocaleString;
import de.jaschastarke.bukkit.lib.chat.ChatFormattings;
import de.jaschastarke.bukkit.lib.commands.*;
import de.jaschastarke.bukkit.lib.commands.annotations.IsCommand;
import de.jaschastarke.bukkit.lib.commands.annotations.Usages;
import de.jaschastarke.bukkit.lib.commands.parser.DefinedParameterParser;
import de.jaschastarke.bukkit.lib.database.DBHelper;
import de.jaschastarke.database.DatabaseConfigurationException;
import de.jaschastarke.database.db.Database;
import de.jaschastarke.maven.ArchiveDocComments;
import de.jaschastarke.maven.PluginCommand;
import de.jaschastarke.minecraft.lib.permissions.IAbstractPermission;
import de.jaschastarke.minecraft.limitedcreative.ModBlockStates;
import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState.Source;
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBModel.Cuboid;
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBModel.DBTransaction;
import de.jaschastarke.modularize.ModuleEntry.ModuleState;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import java.util.Date;
/**
* LimitedCreative-BlockState-Command: modify blockstate database to prevent drops of selected blocks (requires WorldEdit)
* @usage /<command> - displays Regions-Command-Help
* @permission limitedcreative.blockstate.command
*/
@ArchiveDocComments
@PluginCommand
public class BlockStateCommand extends BukkitCommand implements IHelpDescribed {
private ModBlockStates mod;
private HelpCommand help;
public BlockStateCommand() {
this.help = this.getDefaultHelpCommand();
}
public BlockStateCommand(ModBlockStates mod) {
super(mod.getPlugin());
this.help = this.getDefaultHelpCommand();
this.mod = mod;
}
@Override
public String getName() {
return "lcbs";
}
@Override
public String[] getAliases() {
return new String[]{};
}
/**
* @internal has no effect, as not tested by any command handler
* @see IHelpDescribed
*/
@Override
public IAbstractPermission[] getRequiredPermissions() {
return new IAbstractPermission[]{BlockStatePermissions.COMMAND};
}
@Override
public CharSequence[] getUsages() {
return new String[]{"..."};
}
@Override
public CharSequence getDescription() {
return new LocaleString("command.blockstate");
}
@Override
public CharSequence getPackageName() {
return mod.getPlugin().getName() + " - " + mod.getName();
}
public boolean execute(final CommandContext context, final String[] args) throws MissingPermissionCommandException, CommandException {
if (mod.getModuleEntry().getState() != ModuleState.ENABLED)
throw new CommandException("Module " + mod.getName() + " is disabled");
return super.execute(context, args);
}
/**
* Deletes no longer used data from the BlockState-Database. Currently it only removes non-creative entries
* from the database, if you changed to "logSurvival"-config from true to false.
*/
@IsCommand("cleanup")
@Usages("")
public boolean cleanupDatabase(final CommandContext context, String... args) throws CommandException {
if (mod.getConfig().getLogSurvival()) {
context.responseFormatted(ChatFormattings.INFO, L("command.blockstate.nothing_to_cleanup"));
} else {
mod.getPlugin().getServer().getScheduler().runTaskAsynchronously(mod.getPlugin(), new Runnable() {
@Override
public void run() {
int countDeleted = mod.getModel().cleanUp(DBModel.Cleanup.SURVIVAL);
if (countDeleted < 0)
context.responseFormatted(ChatFormattings.ERROR, L("command.blockstate.cleanup_error"));
else
context.responseFormatted(ChatFormattings.SUCCESS, L("command.blockstate.cleanup_success", countDeleted));
}
});
}
return true;
}
/**
* Modifies the BlockState-Database and sets all blocks in the selection to the provided gamemode. Set it
* to "creative" to disable drop of this block on destroying. Set it to "survival" to allow it.
* WorldEdit is required, because the selection Region is used.
* gamemode can be: survival / creative / adventure / s / c / a / 0 / 1 / 2
* @throws MissingPermissionCommandException
*/
@IsCommand("set")
@Usages("<gamemode>")
public boolean setGameMode(final CommandContext context, String... args) throws CommandException, MissingPermissionCommandException {
if (!mod.getPlugin().getServer().getPluginManager().isPluginEnabled("WorldEdit")) {
help.execute(context, new String[]{"set"});
context.response(L("command.blockstate.requires_worldedit"));
return true;
}
if (!context.isPlayer()) {
context.response(L("cmdblock.blocked.not_console"));
return true;
}
if (args.length < 1) {// doesn't count parameters
return false;
}
if (mod.getConfig().getIgnoredWorlds().contains(context.getPlayer().getWorld().getName())) {
context.response(L("command.blockstate.world_ignored", context.getPlayer().getWorld().getName()));
return true;
}
String gm = args[0].toLowerCase();
final GameMode tgm;
if (gm.equals("0") || gm.equals("s") || gm.equals("survival"))
tgm = GameMode.SURVIVAL;
else if (gm.equals("1") || gm.equals("c") || gm.equals("creative"))
tgm = GameMode.CREATIVE;
else if (gm.equals("2") || gm.equals("a") || gm.equals("adventure"))
tgm = GameMode.ADVENTURE;
else {
return false;
}
BukkitPlayer bp = BukkitAdapter.adapt(context.getPlayer());
Region region = null;
try {
region = WorldEdit.getInstance().getSessionManager().get(bp).getSelection(bp.getWorld());
} catch (Exception ignored) { //IncompleteRegionException
}
final Region selection = region;
if (selection == null) {
context.response(L("command.blockstate.worledit_selection_empty"));
return true;
}
final BlockVector3 min = selection.getMinimumPoint();
final BlockVector3 max = selection.getMaximumPoint();
mod.getPlugin().getServer().getScheduler().runTaskAsynchronously(mod.getPlugin(), () -> {
if (mod.isDebug())
mod.getLog().debug("Scheduler: Asynchronous Task run");
DBTransaction update = mod.getModel().groupUpdate();
int count = 0;
World w = selection.getWorld();
assert w != null;
org.bukkit.World bw = BukkitAdapter.adapt(w);
Cuboid c = new Cuboid();
c.add(new Location(bw, min.getBlockX(), min.getBlockY(), min.getBlockZ()));
c.add(new Location(bw, max.getBlockX(), max.getBlockY(), max.getBlockZ()));
mod.getModel().cacheStates(c);
BlockState seed = new BlockState();
seed.setPlayer(context.getPlayer());
seed.setGameMode(tgm);
seed.setSource(Source.COMMAND);
seed.setDate(new Date());
for (int x = min.getBlockX(); x <= max.getBlockX(); x++) {
for (int y = min.getBlockY(); y <= max.getBlockY(); y++) {
for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) {
BlockVector3 loc = BlockVector3.at(x, y, z);
if (!w.getBlock(loc).getBlockType().getMaterial().isAir() && selection.contains(loc)) {
seed.setLocation(new Location(bw, x, y, z));
update.setState(new BlockState(seed));
count++;
}
}
}
}
update.finish();
context.response(L("command.blockstate.command_updated", count));
});
return true;
}
/**
* Imports BlockState Data from a given Database to the current active Database.
* A Server-Restart is needed after migration!
* Parameters:
* -u --update Don't delete existing records / only overwrite if newer
* --import=<type> Import from other Plugins. Supported Types:
* cc CreativeControl
*/
@IsCommand("migrate")
@Usages("-u --import=cc <dsn> [username] [password]")
public boolean migrateDatabase(final CommandContext context, String... args) throws CommandException, MissingPermissionCommandException {
DefinedParameterParser params = new DefinedParameterParser(args, new String[]{"debug", "d", "update", "u", "confirm"});
if (params.getArgumentCount() < 1) {// doesn't count parameters
return false;
}
if (Bukkit.getServer().getOnlinePlayers().size() > (context.isPlayer() ? 1 : 0)) {
context.responseFormatted(ChatFormattings.ERROR, L("command.blockstate.migrate_useronline_error"));
return true;
}
Database source;
Database target;
try {
if (params.getArgumentCount() < 2)
source = DBHelper.createConnection(params.getArgument(0));
else if (params.getArgumentCount() < 3)
source = DBHelper.createConnection(params.getArgument(0), params.getArgument(1), null);
else
source = DBHelper.createConnection(params.getArgument(0), params.getArgument(1), params.getArgument(2));
target = mod.getPlugin().getDatabaseConnection();
} catch (DatabaseConfigurationException e) {
context.responseFormatted(ChatFormattings.ERROR, L("command.blockstate.migrate_connect_error", e.getMessage()));
return true;
}
DatabaseMigrationThread thread;
if (params.getParameter("import") != null) {
if (params.getParameter("import").equals("cc")) {
thread = new CreativeControlImportThread(mod, context, source, target);
} else {
context.responseFormatted(ChatFormattings.ERROR, L("command.blockstate.migrate_importtype_error", params.getParameter("import")));
return false;
}
} else {
thread = new DatabaseMigrationThread(mod, context, source, target);
}
if (params.getFlags().contains("update") || params.getFlags().contains("u")) {
thread.setMode(DatabaseMigrationThread.Mode.UPDATE);
}
if (params.getFlags().contains("debug") || params.getFlags().contains("d")) {
thread.setDebug(true);
}
if (!params.getFlags().contains("confirm")) {
context.responseFormatted(ChatFormattings.INFO, L("command.blockstate.migrate_confirm", "--confirm"));
return true;
}
mod.getModuleEntry().disable();
thread.start();
String sourceType = source.getType().toString();
if (params.getParameter("import") != null) {
if (params.getParameter("import").equals("cc")) {
sourceType = "CreativeControl-" + sourceType;
}
}
context.response(L("command.blockstate.migrate_started", sourceType, target.getType()));
return true;
}
private String L(String msg, Object... args) {
return mod.getPlugin().getLocale().trans(msg, args);
}
}

View file

@ -0,0 +1,203 @@
package de.jaschastarke.minecraft.limitedcreative.blockstate;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import de.jaschastarke.bukkit.lib.configuration.Configuration;
import de.jaschastarke.bukkit.lib.configuration.ConfigurationContainer;
import de.jaschastarke.bukkit.lib.configuration.StringList;
import de.jaschastarke.configuration.IConfigurationNode;
import de.jaschastarke.configuration.IConfigurationSubGroup;
import de.jaschastarke.configuration.InvalidValueException;
import de.jaschastarke.configuration.annotations.IsConfigurationNode;
import de.jaschastarke.maven.ArchiveDocComments;
import de.jaschastarke.maven.PluginConfigurations;
import de.jaschastarke.minecraft.limitedcreative.Config;
import de.jaschastarke.minecraft.limitedcreative.ModBlockStates;
import de.jaschastarke.modularize.IModule;
import de.jaschastarke.modularize.ModuleEntry;
/**
* BlockState-Feature
*
* http://dev.bukkit.org/server-mods/limited-creative/pages/features/blockstate/
*/
@ArchiveDocComments
@PluginConfigurations(parent = Config.class)
public class BlockStateConfig extends Configuration implements IConfigurationSubGroup {
protected ModBlockStates mod;
protected ModuleEntry<IModule> entry;
public BlockStateConfig(ConfigurationContainer container) {
super(container);
}
public BlockStateConfig(ModBlockStates mod, ModuleEntry<IModule> modEntry) {
super(mod.getPlugin().getDocCommentStorage());
this.mod = mod;
entry = modEntry;
}
@Override
public void setValue(IConfigurationNode node, Object pValue) throws InvalidValueException {
if (node.getName().equals("tool"))
setTool(pValue);
else
super.setValue(node, pValue);
if (node.getName().equals("enabled")) {
entry.setEnabled(getEnabled());
} else if (node.getName().equals("useThreading")) {
if (entry.isEnabled()) {
entry.disable();
entry.enable();
}
}
}
@Override
public void setValues(ConfigurationSection sect) {
ignoredWorlds = null;
super.setValues(sect);
entry.setDefaultEnabled(getEnabled());
}
@Override
public String getName() {
return "blockstate";
}
@Override
public int getOrder() {
return 700;
}
/**
* BlockStateEnabled
*
* This Feature stores the GameMode a Block was created in, and prevents drops if a Block was created
* in creative mode.
*
* Due to the huge load of this Feature, it isn't enabled by default. It uses the Database-credentials from
* bukkit.yml (http://wiki.bukkit.org/Bukkit.yml#database) in the server-directory.
*
* default: false
*/
@IsConfigurationNode(order = 100)
public boolean getEnabled() {
return config.getBoolean("enabled", false);
}
/**
* BlockStateThreading
*
* Uses Threading to minimize lag. This fully relies on Bukkit metadata implementation. You only should need this,
* if there are often plays more then 10 players at once on your server, or you're about to use huge WorldEdits often.
* Be aware that this requires more memory, to increase the performance
*
* Without threading, huge WorldEdits becomes much noticeable slower.
*
* default: true
*/
@IsConfigurationNode(order = 150)
public boolean getUseThreading() {
return config.getBoolean("useThreading", true);
}
/**
* BlockStateTool
*
* The id or technical name (http://public.ja-s.de/bukkit/material) of an item that displays information about the
* right-clicked block.
*
* default: WOOD_PICKAXE
*/
@IsConfigurationNode(order = 200)
public Material getTool() {
if (config.isString("tool")) {
Material v = Material.getMaterial(config.getString("tool"));
if (v != null)
return v;
} else if (config.isInt("tool")) {
Material v = Material.getMaterial(config.getInt("tool"));
if (v != null)
return v;
} else {
Object v = config.get("tool", Material.WOOD_PICKAXE);
if (v instanceof Material)
return (Material) v;
}
mod.getLog().warn("Unknown BlockStateTool: " + config.get("tool"));
return Material.WOOD_PICKAXE;
}
/**
* BlockStateLogSurvival
*
* Log all Block-Places to the database. Disable to make the database more slim by not adding blocks placed in
* survival-mode.
*
* default: false
*/
@IsConfigurationNode(order = 400)
public boolean getLogSurvival() {
return config.getBoolean("logSurvival", false);
}
private StringList ignoredWorlds = null;
/**
* BlockStateIgnoredWorlds
*
* While you may use per world permissions to configure limitations fine graded, you may want to disable the
* BlockState-Feature for certain worlds (like complete creative worlds) to save cpu and memory.
*
* default: []
*/
@IsConfigurationNode(order = 500)
public StringList getIgnoredWorlds() {
if (ignoredWorlds == null) {
ignoredWorlds = new StringList(config.getStringList("ignoredWorlds"));
}
return ignoredWorlds;
}
/**
* BlockStateWorldEditIntegration
*
* Allows you to disable hook into WorldEdit for better Performance. By default Integration is enable, so it logs
* block modifications via worldedit as creative-placed blocks in the database.
* A server reload (better restart) is needed to disabled WE-Integration.
*
* default: true
*/
@IsConfigurationNode(order = 600)
public boolean getWorldeditIntegration() {
return config.getBoolean("worldeditIntegration", true);
}
protected void setTool(Object val) throws InvalidValueException {
String v = (String) val;
Material m = null;
try {
int i = Integer.parseInt(v);
if (i > 0)
m = Material.getMaterial(i);
} catch (NumberFormatException e) {
m = null;
}
if (m == null)
m = Material.getMaterial(v);
if (m == null)
throw new InvalidValueException("Material '" + v + "' not found");
else
config.set("tool", m);
}
@Override
public Object getValue(final IConfigurationNode node) {
Object val = super.getValue(node);
if (node.getName().equals("tool") && val != null) {
return val.toString();
} else {
return val;
}
}
}

View file

@ -0,0 +1,54 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.limitedcreative.blockstate;
import org.bukkit.permissions.PermissionDefault;
import de.jaschastarke.maven.ArchiveDocComments;
import de.jaschastarke.maven.PluginPermissions;
import de.jaschastarke.minecraft.lib.permissions.BasicPermission;
import de.jaschastarke.minecraft.lib.permissions.IAbstractPermission;
import de.jaschastarke.minecraft.lib.permissions.IPermission;
import de.jaschastarke.minecraft.lib.permissions.IPermissionContainer;
import de.jaschastarke.minecraft.lib.permissions.SimplePermissionContainerNode;
import de.jaschastarke.minecraft.limitedcreative.Permissions;
@ArchiveDocComments
public class BlockStatePermissions extends SimplePermissionContainerNode {
public BlockStatePermissions(IAbstractPermission parent, String name) {
super(parent, name);
}
@PluginPermissions
public static final IPermissionContainer PARENT = new BlockStatePermissions(Permissions.CONTAINER, "blockstate");
/**
* Grants ability to use the configured tool to get info about placed blocks.
*/
public static final IPermission TOOL = new BasicPermission(PARENT, "tool", PermissionDefault.OP);
/**
* Grants access to the blockstate admin command to modify the database.
*/
public static final IPermission COMMAND = new BasicPermission(PARENT, "command", PermissionDefault.OP);
/**
* Allows to get drops even if a block was created from a creative player or WorldEdit.
*/
public static final IPermission BYPASS = new BasicPermission(PARENT, "bypass", PermissionDefault.FALSE);
}

View file

@ -0,0 +1,140 @@
package de.jaschastarke.minecraft.limitedcreative.blockstate;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.World;
import de.jaschastarke.bukkit.lib.chat.ChatFormattings;
import de.jaschastarke.bukkit.lib.commands.CommandContext;
import de.jaschastarke.bukkit.lib.database.ResultIterator;
import de.jaschastarke.database.db.Database;
import de.jaschastarke.minecraft.limitedcreative.ModBlockStates;
import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState.Source;
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBModel.Cuboid;
public class CreativeControlImportThread extends DatabaseMigrationThread {
public CreativeControlImportThread(ModBlockStates mod, CommandContext context, Database source, Database target) {
super(mod, context, source, target);
}
@Override
public void run() {
try {
if (!target.isInTransaction())
target.startTransaction();
int rowCount = 0;
Connection sourceConnection = source.getConnection();
Connection targetConnection = target.getConnection();
if (mode == Mode.REPLACE) {
targetConnection.createStatement().execute("DELETE FROM lc_block_state");
}
DBQueries targetDB = new DBQueries(this, target);
List<WorldSize> worldBounds = new ArrayList<WorldSize>();
for (World w : mod.getPlugin().getServer().getWorlds()) {
try {
ResultSet fetchBounds = sourceConnection.createStatement().executeQuery("SELECT MIN(x), MIN(z), MAX(x), MAX(z) FROM crcr_blocks_" + w.getName());
while (fetchBounds.next()) {
worldBounds.add(new WorldSize(w,
fetchBounds.getInt(1),
fetchBounds.getInt(2),
fetchBounds.getInt(3),
fetchBounds.getInt(4)));
}
fetchBounds.close();
} catch (SQLException e) {
if (isDebug())
mod.getLog().debug("crcr_blocks_" + w.getName() + " not found: " + e.getMessage());
mod.getLog().info("CreativeControl has BlockData for World " + w.getName());
}
}
for (WorldSize bounds : worldBounds) {
World world = mod.getPlugin().getServer().getWorld(bounds.getWorld());
if (world != null) {
long time = System.currentTimeMillis();
int itCount = 0;
if (mod.isDebug())
mod.getLog().debug("Processing world " + world.getName() + " with bounds: " + bounds);
for (int x = bounds.getMinX(); x <= bounds.getMaxX(); x += CHUNK_SIZE + 1) {
for (int z = bounds.getMinZ(); z <= bounds.getMaxZ(); z += CHUNK_SIZE + 1) {
Cuboid c = new Cuboid();
c.add(new Location(world, x, 0, z));
c.add(new Location(world, x + CHUNK_SIZE, world.getMaxHeight(), z + CHUNK_SIZE));
if (mod.isDebug())
mod.getLog().debug("Fetching Cuboid: " + c.toString());
for (BlockState bs : iterateAllIn(c)) {
if (mode == Mode.UPDATE) {
BlockState xs = targetDB.find(bs.getLocation());
if (xs == null) {
targetDB.insert(bs);
} else if (xs.getDate().before(bs.getDate())) {
targetDB.update(bs);
}
} else {
targetDB.insert(bs);
}
rowCount++;
itCount++;
}
Thread.yield();
}
}
String region = "Region{world = " + world.getName() + ", x = [" + bounds.getMinX() + "; " + (bounds.getMinX() + CHUNK_SIZE) + "], z = [" + bounds.getMinZ() + "; " + (bounds.getMinZ() + CHUNK_SIZE) + "]}";
mod.getLog().info("Migration processed " + itCount + " BlockStates in " + region + " within " + ((System.currentTimeMillis() - time) / 1000.0) + " seconds");
}
}
target.endTransaction();
context.responseFormatted(ChatFormattings.SUCCESS, L("command.blockstate.migration_finished", rowCount) + " " +
context.getFormatter().formatString(ChatFormattings.ERROR, L("command.blockstate.migration_finished_restart")));
} catch (SQLException e) {
try {
target.revertTransaction();
} catch (SQLException e1) {}
context.responseFormatted(ChatFormattings.ERROR, L("command.blockstate.migration_error", e.getMessage()));
}
}
private PreparedStatement findall = null;
private Iterable<BlockState> iterateAllIn(final DBModel.Cuboid c) throws SQLException {
if (isDebug())
getLog().debug("DBQuery: iterateAllIn: " + c.toString());
if (findall == null) {
findall = source.prepare("SELECT * FROM crcr_blocks_" + c.getWorld().getName() + " LEFT JOIN crcr_players ON owner = id WHERE x >= ? AND x <= ? AND y >= ? AND y <= ? AND z >= ? AND z <= ?");
}
findall.setInt(1, c.getMinX());
findall.setInt(2, c.getMaxX());
findall.setInt(3, c.getMinY());
findall.setInt(4, c.getMaxY());
findall.setInt(5, c.getMinZ());
findall.setInt(6, c.getMaxZ());
ResultSet rs = findall.executeQuery();
return new ResultIterator<BlockState>(rs) {
@Override
protected BlockState fetch(ResultSet rs) throws SQLException {
BlockState bs = new BlockState();
bs.setLocation(new Location(c.getWorld(), rs.getInt("x"), rs.getInt("y"), rs.getInt("z")));
bs.setDate(new Date(rs.getLong("time")));
bs.setGameMode(GameMode.CREATIVE);
bs.setPlayerNameOrUUID(rs.getString("player"));
bs.setSource(Source.PLAYER);
return bs;
}
};
}
}

View file

@ -0,0 +1,92 @@
package de.jaschastarke.minecraft.limitedcreative.blockstate;
import java.util.List;
import java.util.Map;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Block;
public interface DBModel {
public static class Cuboid {
private World w = null;
private int minx, miny, minz;
private int maxx, maxy, maxz;
public void add(Location loc) {
if (w == null) {
w = loc.getWorld();
minx = maxx = loc.getBlockX();
miny = maxy = loc.getBlockY();
minz = maxz = loc.getBlockZ();
} else {
if (w != loc.getWorld())
throw new IllegalArgumentException("Point is from a different world");
if (minx > loc.getBlockX())
minx = loc.getBlockX();
if (maxx < loc.getBlockX())
maxx = loc.getBlockX();
if (miny > loc.getBlockY())
miny = loc.getBlockY();
if (maxy < loc.getBlockY())
maxy = loc.getBlockY();
if (minz > loc.getBlockZ())
minz = loc.getBlockZ();
if (maxz < loc.getBlockZ())
maxz = loc.getBlockZ();
}
}
public int getMinX() {
return minx;
}
public int getMinY() {
return miny;
}
public int getMinZ() {
return minz;
}
public int getMaxX() {
return maxx;
}
public int getMaxY() {
return maxy;
}
public int getMaxZ() {
return maxz;
}
public World getWorld() {
return w;
}
public boolean isEmpty() {
return w == null;
}
public String toString() {
return "Cuboid{world="+w.getName()+", min_x="+minx+", max_x="+maxx+", min_y="+miny+", max_y="+maxy+", min_z="+minz+", max_z="+maxz+"}";
}
}
public enum Cleanup {
SURVIVAL;
}
public void onEnable() throws Exception;
public void onDisable();
public void moveState(Block from, Block to);
public void removeState(BlockState state);
public void removeState(Block block);
public Map<Block, BlockState> getStates(List<Block> blocks);
public Map<Block, Boolean> getRestrictedStates(List<Block> blocks);
public void cacheStates(DBModel.Cuboid c);
public BlockState getState(Block block);
public boolean isRestricted(Block block);
public void setState(BlockState state);
public DBTransaction groupUpdate();
public static interface DBTransaction {
public void moveState(Block from, Block to);
public void setState(BlockState state);
public void removeState(Block block);
public void finish();
}
public int cleanUp(Cleanup target);
}

View file

@ -0,0 +1,324 @@
package de.jaschastarke.minecraft.limitedcreative.blockstate;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.GameMode;
import org.bukkit.Location;
import de.jaschastarke.bukkit.lib.database.ResultIterator;
import de.jaschastarke.database.Type;
import de.jaschastarke.database.db.Database;
import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState.Source;
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBModel.Cleanup;
import de.jaschastarke.utils.IDebugLogHolder;
public class DBQueries {
private Database db;
private IDebugLogHolder dbg;
public DBQueries(IDebugLogHolder mod, Database db) {
this.dbg = mod;
this.db = db;
}
private PreparedStatement find = null;
public BlockState find(Location loc) throws SQLException {
if (dbg.isDebug())
dbg.getLog().debug("DBQuery: find: " + loc.toString());
if (find == null) {
find = db.prepare("SELECT * FROM lc_block_state WHERE x = ? AND y = ? AND z = ? AND world = ?");
}
find.setInt(1, loc.getBlockX());
find.setInt(2, loc.getBlockY());
find.setInt(3, loc.getBlockZ());
find.setString(4, loc.getWorld().getUID().toString());
ResultSet rs = find.executeQuery();
if (rs.next()) {
BlockState bs = new BlockState();
bs.setLocation(loc);
bs.setDate(rs.getTimestamp("cdate"));
bs.setGameMode(getGameMode(rs));
bs.setPlayerNameOrUUID(rs.getString("player"));
bs.setSource(getSource(rs));
rs.close();
return bs;
}
rs.close();
return null;
}
private PreparedStatement findall = null;
public List<BlockState> findAllIn(DBModel.Cuboid c) throws SQLException {
if (dbg.isDebug())
dbg.getLog().debug("DBQuery: findAllIn: " + c.toString());
List<BlockState> blocks = new ArrayList<BlockState>();
if (findall == null) {
findall = db.prepare("SELECT * FROM lc_block_state WHERE x >= ? AND x <= ? AND y >= ? AND y <= ? AND z >= ? AND z <= ? AND world = ?");
}
findall.setInt(1, c.getMinX());
findall.setInt(2, c.getMaxX());
findall.setInt(3, c.getMinY());
findall.setInt(4, c.getMaxY());
findall.setInt(5, c.getMinZ());
findall.setInt(6, c.getMaxZ());
findall.setString(7, c.getWorld().getUID().toString());
ResultSet rs = findall.executeQuery();
while (rs.next()) {
BlockState bs = new BlockState();
bs.setLocation(new Location(c.getWorld(), rs.getInt("x"), rs.getInt("y"), rs.getInt("z")));
bs.setDate(rs.getTimestamp("cdate"));
bs.setGameMode(getGameMode(rs));
bs.setPlayerNameOrUUID(rs.getString("player"));
bs.setSource(getSource(rs));
blocks.add(bs);
}
rs.close();
return blocks;
}
public Iterable<BlockState> iterateAllIn(final DBModel.Cuboid c) throws SQLException {
if (dbg.isDebug())
dbg.getLog().debug("DBQuery: iterateAllIn: " + c.toString());
if (findall == null) {
findall = db.prepare("SELECT * FROM lc_block_state WHERE x >= ? AND x <= ? AND y >= ? AND y <= ? AND z >= ? AND z <= ? AND world = ?");
}
findall.setInt(1, c.getMinX());
findall.setInt(2, c.getMaxX());
findall.setInt(3, c.getMinY());
findall.setInt(4, c.getMaxY());
findall.setInt(5, c.getMinZ());
findall.setInt(6, c.getMaxZ());
findall.setString(7, c.getWorld().getUID().toString());
ResultSet rs = findall.executeQuery();
return new ResultIterator<BlockState>(rs) {
@Override
protected BlockState fetch(ResultSet rs) throws SQLException {
BlockState bs = new BlockState();
bs.setLocation(new Location(c.getWorld(), rs.getInt("x"), rs.getInt("y"), rs.getInt("z")));
bs.setDate(rs.getTimestamp("cdate"));
bs.setGameMode(getGameMode(rs));
bs.setPlayerNameOrUUID(rs.getString("player"));
bs.setSource(getSource(rs));
return bs;
}
};
}
private PreparedStatement delete = null;
public boolean delete(BlockState s) throws SQLException {
return delete(s.getLocation());
}
public boolean delete(Location loc) throws SQLException {
if (dbg.isDebug())
dbg.getLog().debug("DBQuery: delete: " + loc.toString());
if (delete == null) {
delete = db.prepare("DELETE FROM lc_block_state WHERE x = ? AND y = ? AND z = ? AND world = ?");
}
delete.setInt(1, loc.getBlockX());
delete.setInt(2, loc.getBlockY());
delete.setInt(3, loc.getBlockZ());
delete.setString(4, loc.getWorld().getUID().toString());
return delete.executeUpdate() > 0;
}
private PreparedStatement update = null;
public boolean update(BlockState s) throws SQLException {
if (dbg.isDebug())
dbg.getLog().debug("DBQuery: update: " + s.toString());
if (update == null) {
update = db.prepare("UPDATE lc_block_state SET gm = ?, player = ?, cdate = ?, source = ?"+
"WHERE x = ? AND y = ? AND z = ? AND world = ? ");
}
if (s.getGameMode() == null)
update.setNull(1, Types.INTEGER);
else if (db.getType() == Type.MySQL)
update.setString(1, s.getGameMode().name());
else
update.setInt(1, s.getGameMode().getValue());
update.setString(2, s.getPlayerUUID().toString());
update.setTimestamp(3, new java.sql.Timestamp(s.getDate().getTime()));
if (db.getType() == Type.MySQL)
update.setString(4, s.getSource().name());
else
update.setInt(4, s.getSource().ordinal());
update.setInt(5, s.getLocation().getBlockX());
update.setInt(6, s.getLocation().getBlockY());
update.setInt(7, s.getLocation().getBlockZ());
update.setString(8, s.getLocation().getWorld().getUID().toString());
return update.executeUpdate() > 0;
}
private PreparedStatement move = null;
public boolean move(BlockState s, Location newLoc) throws SQLException {
boolean r = move(s.getLocation(), newLoc);
if (r)
s.setLocation(newLoc);
return r;
}
public boolean move(Location oldLoc, Location newLoc) throws SQLException {
if (dbg.isDebug())
dbg.getLog().debug("DBQuery: move: " + oldLoc.toString() + ", " + newLoc.toString());
if (move == null) {
move = db.prepare("UPDATE lc_block_state SET x = ?, y = ?, z = ? "+
"WHERE x = ? AND y = ? AND z = ? AND world = ?");
}
move.setInt(1, newLoc.getBlockX());
move.setInt(2, newLoc.getBlockY());
move.setInt(3, newLoc.getBlockZ());
move.setInt(4, oldLoc.getBlockX());
move.setInt(5, oldLoc.getBlockY());
move.setInt(6, oldLoc.getBlockZ());
move.setString(7, oldLoc.getWorld().getUID().toString());
return move.executeUpdate() > 0;
}
/*private PreparedStatement replace = null;
public boolean replace(BlockState s) throws SQLException {
if (replace == null) {
replace = db.prepare("INSERT OR REPLACE INTO lc_block_state (x, y, z, world, gm, player, cdate, source)"+
" VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
}
return this._executeInsert(replace, s);
}*/
private PreparedStatement insert = null;
public boolean insert(BlockState s) throws SQLException {
if (dbg.isDebug())
dbg.getLog().debug("DBQuery: insert: " + s.toString());
if (insert == null) {
insert = db.prepare("INSERT INTO lc_block_state (x, y, z, world, gm, player, cdate, source)"+
" VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
}
return this._executeInsert(insert, s);
}
private boolean _executeInsert(PreparedStatement insert, BlockState s) throws SQLException {
insert.setInt(1, s.getLocation().getBlockX());
insert.setInt(2, s.getLocation().getBlockY());
insert.setInt(3, s.getLocation().getBlockZ());
insert.setString(4, s.getLocation().getWorld().getUID().toString());
if (s.getGameMode() == null)
insert.setNull(5, Types.INTEGER);
else if (db.getType() == Type.MySQL)
insert.setString(5, s.getGameMode().name());
else
insert.setInt(5, s.getGameMode().getValue());
insert.setString(6, s.getPlayerUUID().toString());
insert.setTimestamp(7, new java.sql.Timestamp(s.getDate().getTime()));
if (db.getType() == Type.MySQL)
insert.setString(8, s.getSource().name());
else
insert.setInt(8, s.getSource().ordinal());
return insert.executeUpdate() > 0;
}
private GameMode getGameMode(ResultSet rs) {
try {
switch (db.getType()) {
case SQLite:
int gm = rs.getInt("gm");
if (rs.wasNull())
return null;
return GameMode.getByValue(gm);
case MySQL:
if (rs.getString("gm") == null)
return null;
return GameMode.valueOf(rs.getString("gm"));
default:
throw new RuntimeException("Unsupported Database-Type.");
}
} catch (SQLException e) {
db.getLogger().warn("Couldn't get GameMode from result-set: "+e.getMessage());
return GameMode.SURVIVAL;
}
}
private Source getSource(ResultSet rs) {
try {
switch (db.getType()) {
case SQLite:
return Source.values()[rs.getInt("source")];
case MySQL:
return Source.valueOf(rs.getString("source"));
default:
throw new RuntimeException("Unsupported Database-Type.");
}
} catch (Exception e) {
db.getLogger().warn("Couldn't get Source from result-set: "+e.getMessage());
return Source.UNKNOWN;
}
}
public void initTable() throws SQLException {
switch (db.getType()) {
case SQLite:
if (!db.getDDL().tableExists("lc_block_state")) {
if (dbg.isDebug())
dbg.getLog().debug("DBQuery: initTable SQLite: lc_block_state");
db.execute(
"CREATE TABLE lc_block_state ("+
"x integer,"+
"y integer,"+
"z integer,"+
"world varchar(40),"+
"gm integer,"+
"player varchar(255),"+
"cdate timestamp not null,"+
"source integer not null,"+
"primary key (x, y, z, world),"+
"constraint ck_lc_block_state_gm check (gm in (0,1,2)),"+
"constraint ck_lc_block_state_source check (source in (0,1,2,3,4))"+
")"
).close();
db.getLogger().info("Created SQLite-Table: lc_block_state");
}
break;
case MySQL:
if (!db.getDDL().tableExists("lc_block_state")) {
if (dbg.isDebug())
dbg.getLog().debug("DBQuery: initTable MySQL: lc_block_state");
db.execute(
"CREATE TABLE IF NOT EXISTS lc_block_state ("+
"x INT NOT NULL,"+
"y INT NOT NULL,"+
"z INT NOT NULL,"+
"world VARCHAR(40) NOT NULL,"+
"gm ENUM('CREATIVE', 'SURVIVAL', 'ADVENTURE'),"+
"player VARCHAR(255),"+
"cdate TIMESTAMP NOT NULL,"+
"source ENUM('SEED','PLAYER','EDIT','COMMAND','UNKNOWN') NOT NULL,"+
"PRIMARY KEY (x, y, z, world)"+
")"
).close();
db.getLogger().info("Created MySQL-Table: lc_block_state");
}
break;
default:
throw new RuntimeException("Currently only SQLite or MySQL is supported.");
}
}
public int cleanup(Cleanup q) throws SQLException {
PreparedStatement delete;
if (dbg.isDebug())
dbg.getLog().debug("DBQuery: cleanup: " + q.toString());
if (q == Cleanup.SURVIVAL) {
delete = db.prepare("DELETE FROM lc_block_state WHERE gm = ?");
if (db.getType() == Type.MySQL)
delete.setString(1, GameMode.SURVIVAL.name());
else
delete.setInt(1, GameMode.SURVIVAL.getValue());
} else {
return -1;
}
return delete.executeUpdate();
}
public Database getDB() {
return db;
}
}

View file

@ -0,0 +1,186 @@
package de.jaschastarke.minecraft.limitedcreative.blockstate;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import de.jaschastarke.bukkit.lib.chat.ChatFormattings;
import de.jaschastarke.bukkit.lib.commands.CommandContext;
import de.jaschastarke.database.db.Database;
import de.jaschastarke.minecraft.limitedcreative.ModBlockStates;
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBModel.Cuboid;
import de.jaschastarke.utils.IDebugLogHolder;
import de.jaschastarke.utils.ISimpleLogger;
public class DatabaseMigrationThread extends Thread implements IDebugLogHolder {
protected static final int CHUNK_SIZE = 512;
protected ModBlockStates mod;
protected CommandContext context;
protected Database source;
protected Database target;
protected Mode mode = Mode.REPLACE;
private boolean debug = false;
public static enum Mode {
REPLACE,
UPDATE
}
public DatabaseMigrationThread(ModBlockStates mod, CommandContext context, Database source, Database target) {
this.mod = mod;
this.context = context;
this.source = source;
this.target = target;
setName("LC BlockState Database-Migration");
setPriority(MIN_PRIORITY);
}
public Mode getMode() {
return mode;
}
public void setMode(Mode mode) {
this.mode = mode;
}
public void setDebug(boolean debug) {
this.debug = debug;
}
@Override
public boolean isDebug() {
return debug;
}
@Override
public ISimpleLogger getLog() {
return mod.getLog();
}
@Override
public void run() {
try {
if (!target.isInTransaction())
target.startTransaction();
int rowCount = 0;
Connection sourceConnection = source.getConnection();
Connection targetConnection = target.getConnection();
if (mode == Mode.REPLACE) {
targetConnection.createStatement().execute("DELETE FROM lc_block_state");
}
DBQueries sourceDB = new DBQueries(this, source);
DBQueries targetDB = new DBQueries(this, target);
List<WorldSize> worldBounds = new ArrayList<WorldSize>();
ResultSet fetchBounds = sourceConnection.createStatement().executeQuery("SELECT world, MIN(x), MIN(z), MAX(x), MAX(z) FROM lc_block_state GROUP BY world");
while (fetchBounds.next()) {
worldBounds.add(new WorldSize(fetchBounds.getString("world"),
fetchBounds.getInt(2),
fetchBounds.getInt(3),
fetchBounds.getInt(4),
fetchBounds.getInt(5)));
}
fetchBounds.close();
for (WorldSize bounds : worldBounds) {
World world = mod.getPlugin().getServer().getWorld(bounds.getWorld());
if (world != null) {
long time = System.currentTimeMillis();
int itCount = 0;
if (mod.isDebug())
mod.getLog().debug("Processing world " + world.getName() + " with bounds: " + bounds);
for (int x = bounds.getMinX(); x <= bounds.getMaxX(); x += CHUNK_SIZE + 1) {
for (int z = bounds.getMinZ(); z <= bounds.getMaxZ(); z += CHUNK_SIZE + 1) {
Cuboid c = new Cuboid();
c.add(new Location(world, x, 0, z));
c.add(new Location(world, x + CHUNK_SIZE, world.getMaxHeight(), z + CHUNK_SIZE));
if (mod.isDebug())
mod.getLog().debug("Fetching Cuboid: " + c.toString());
for (BlockState bs : sourceDB.iterateAllIn(c)) {
if (mode == Mode.UPDATE) {
BlockState xs = targetDB.find(bs.getLocation());
if (xs == null) {
targetDB.insert(bs);
} else if (xs.getDate().before(bs.getDate())) {
targetDB.update(bs);
}
} else {
targetDB.insert(bs);
}
rowCount++;
itCount++;
}
Thread.yield();
}
}
String region = "Region{world = " + world.getName() + ", x = [" + bounds.getMinX() + "; " + (bounds.getMinX() + CHUNK_SIZE) + "], z = [" + bounds.getMinZ() + "; " + (bounds.getMinZ() + CHUNK_SIZE) + "]}";
mod.getLog().info("Migration processed " + itCount + " BlockStates in " + region + " within " + ((System.currentTimeMillis() - time) / 1000.0) + " seconds");
}
}
target.endTransaction();
context.responseFormatted(ChatFormattings.SUCCESS, L("command.blockstate.migration_finished", rowCount) + " " +
context.getFormatter().formatString(ChatFormattings.ERROR, L("command.blockstate.migration_finished_restart")));
} catch (SQLException e) {
try {
target.revertTransaction();
} catch (SQLException e1) {}
context.responseFormatted(ChatFormattings.ERROR, L("command.blockstate.migration_error", e.getMessage()));
}
}
protected String L(String msg, Object... args) {
return mod.getPlugin().getLocale().trans(msg, args);
}
protected static class WorldSize {
UUID w;
int minX, minZ, maxX, maxZ;
public WorldSize(String w, int minX, int minZ, int maxX, int maxZ) {
this.w = UUID.fromString(w);
this.minX = minX;
this.minZ = minZ;
this.maxX = maxX;
this.maxZ = maxZ;
}
public WorldSize(World w, int minX, int minZ, int maxX, int maxZ) {
this.w = w.getUID();
this.minX = minX;
this.minZ = minZ;
this.maxX = maxX;
this.maxZ = maxZ;
}
public String toString() {
World world = Bukkit.getServer().getWorld(w);
String wn = world == null ? w.toString() : world.getName();
return getClass().getSimpleName() + "{world = " + wn + ", minX = " + minX + ", minZ = " + minZ + ", maxX = " + maxX + ", maxZ = " + maxZ + "}";
}
public UUID getWorld() {
return w;
}
public int getMinX() {
return minX;
}
public int getMinZ() {
return minZ;
}
public int getMaxX() {
return maxX;
}
public int getMaxZ() {
return maxZ;
}
}
}

View file

@ -0,0 +1,205 @@
package de.jaschastarke.minecraft.limitedcreative.blockstate;
import java.util.Date;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.hanging.HangingBreakEvent;
import org.bukkit.event.hanging.HangingPlaceEvent;
import org.bukkit.event.player.PlayerArmorStandManipulateEvent;
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import de.jaschastarke.minecraft.limitedcreative.ModBlockStates;
public class HangingStandingListener implements Listener {
private ModBlockStates mod;
public HangingStandingListener(ModBlockStates mod) {
this.mod = mod;
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
if (mod.getConfig().getIgnoredWorlds().contains(event.getRightClicked().getWorld().getName()))
return;
if (event.getRightClicked() instanceof ItemFrame) {
if (mod.getModel().isRestricted(event.getRightClicked().getLocation().getBlock())) {
if (mod.isDebug())
mod.getLog().debug("Modifying hanging: " + event.getRightClicked().getLocation().toString());
if (event.getPlayer().getGameMode() != GameMode.CREATIVE) {
if (mod.isDebug())
mod.getLog().debug("... was placed by creative. Modify prevented");
event.setCancelled(true);
}
} else {
BlockState s = new BlockState();
s.setLocation(event.getRightClicked().getLocation().getBlock().getLocation());
s.setPlayer(event.getPlayer());
s.setDate(new Date());
if (mod.isDebug())
mod.getLog().debug("Saving BlockState: " + s.toString());
mod.getModel().setState(s);
}
} else if (event.getRightClicked() instanceof ArmorStand) {
if (mod.getModel().isRestricted(event.getRightClicked().getLocation().getBlock())) {
if (mod.isDebug())
mod.getLog().debug("Modifying standing: " + event.getRightClicked().getLocation().toString());
if (event.getPlayer().getGameMode() != GameMode.CREATIVE) {
if (mod.isDebug())
mod.getLog().debug("... was placed by creative. Modify prevented");
event.setCancelled(true);
}
} else {
BlockState s = new BlockState();
s.setLocation(event.getRightClicked().getLocation().getBlock().getLocation());
s.setPlayer(event.getPlayer());
s.setDate(new Date());
if (mod.isDebug())
mod.getLog().debug("Saving BlockState: " + s.toString());
mod.getModel().setState(s);
}
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onPlayerInteractAtEntity(PlayerInteractAtEntityEvent event) {
onPlayerInteractEntity(event);
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onArmorStandManipulateEvent(PlayerArmorStandManipulateEvent event) {
onPlayerInteractEntity(event);
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onPlayerLeftInteractEntity(EntityDamageByEntityEvent event) {
if (mod.getConfig().getIgnoredWorlds().contains(event.getEntity().getWorld().getName()))
return;
if (event.getDamager() instanceof Player && event.getEntity() instanceof ItemFrame) {
if (mod.getModel().isRestricted(event.getEntity().getLocation().getBlock())) {
if (mod.isDebug())
mod.getLog().debug("Modifying hanging: " + event.getEntity().getLocation().toString());
if (((Player) event.getDamager()).getGameMode() != GameMode.CREATIVE) {
if (mod.isDebug())
mod.getLog().debug("... was placed by creative. Modify prevented");
event.setCancelled(true);
}
} else {
BlockState s = new BlockState();
s.setLocation(event.getEntity().getLocation().getBlock().getLocation());
s.setPlayer((Player) event.getDamager());
s.setDate(new Date());
if (mod.isDebug())
mod.getLog().debug("Saving BlockState: " + s.toString());
mod.getModel().setState(s);
}
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onHangingBreak(HangingBreakEvent event) {
if (mod.getConfig().getIgnoredWorlds().contains(event.getEntity().getWorld().getName()))
return;
if (event.getEntity() instanceof ItemFrame) {
if (mod.isDebug())
mod.getLog().debug("Breaking hanging: " + event.getEntity().getLocation().toString());
if (mod.getModel().isRestricted(event.getEntity().getLocation().getBlock())) {
if (mod.isDebug())
mod.getLog().debug("... was placed by creative. Drop prevented");
mod.getBlockSpawn().block(event.getEntity().getLocation().getBlock().getLocation(), Material.ITEM_FRAME);
mod.getBlockSpawn().block(event.getEntity().getLocation().getBlock().getLocation(), ((ItemFrame) event.getEntity()).getItem().getType());
}
mod.getModel().removeState(event.getEntity().getLocation().getBlock());
}
}
protected void checkArmoryDestroy(ArmorStand entity, boolean deRemove) {
if (mod.isDebug())
mod.getLog().debug("Breaking standing: " + entity.getLocation().toString());
if (mod.getModel().isRestricted(entity.getLocation().getBlock())) {
if (mod.isDebug())
mod.getLog().debug("... was placed by creative. Drop prevented");
mod.getBlockSpawn().block(entity.getLocation().getBlock().getLocation(), Material.ARMOR_STAND);
mod.getBlockSpawn().block(entity.getLocation().getBlock().getRelative(BlockFace.UP).getLocation(), Material.ARMOR_STAND);
mod.getBlockSpawn().block(entity.getLocation().getBlock().getLocation(), entity.getHelmet());
mod.getBlockSpawn().block(entity.getLocation().getBlock().getLocation(), entity.getChestplate());
mod.getBlockSpawn().block(entity.getLocation().getBlock().getLocation(), entity.getBoots());
mod.getBlockSpawn().block(entity.getLocation().getBlock().getLocation(), entity.getItemInHand());
mod.getBlockSpawn().block(entity.getLocation().getBlock().getLocation(), entity.getLeggings());
mod.getBlockSpawn().block(entity.getLocation().getBlock().getRelative(BlockFace.UP).getLocation(), entity.getHelmet());
mod.getBlockSpawn().block(entity.getLocation().getBlock().getRelative(BlockFace.UP).getLocation(), entity.getChestplate());
mod.getBlockSpawn().block(entity.getLocation().getBlock().getRelative(BlockFace.UP).getLocation(), entity.getBoots());
mod.getBlockSpawn().block(entity.getLocation().getBlock().getRelative(BlockFace.UP).getLocation(), entity.getItemInHand());
mod.getBlockSpawn().block(entity.getLocation().getBlock().getRelative(BlockFace.UP).getLocation(), entity.getLeggings());
/*entity.setBoots(null);
entity.setChestplate(null);
entity.setHelmet(null);
entity.setItemInHand(null);
entity.setLeggings(null);*/
}
if (deRemove)
mod.getModel().removeState(entity.getLocation().getBlock());
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onStandingBreak(EntityDeathEvent event) {
if (mod.getConfig().getIgnoredWorlds().contains(event.getEntity().getWorld().getName()))
return;
if (event.getEntity() instanceof ArmorStand) {
checkArmoryDestroy((ArmorStand) event.getEntity(), true);
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onStandingBreaking(EntityDamageByEntityEvent event) {
if (mod.getConfig().getIgnoredWorlds().contains(event.getEntity().getWorld().getName()))
return;
if (event.getEntity() instanceof ArmorStand) {
// TODO: Bug in Spigot, we can not check for destroying yet. so the block state stays in DB :(
//if (event.getEntity().isDead() || ((ArmorStand) event.getEntity()).getHealth() <= event.getFinalDamage()) {
checkArmoryDestroy((ArmorStand) event.getEntity(), false);
//}
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onHangingPlace(HangingPlaceEvent event) {
if (mod.getConfig().getIgnoredWorlds().contains(event.getEntity().getWorld().getName()))
return;
if (event.getEntity() instanceof ItemFrame) {
BlockState s = new BlockState();
s.setLocation(event.getEntity().getLocation().getBlock().getLocation());
s.setPlayer(event.getPlayer());
s.setDate(new Date());
if (mod.isDebug())
mod.getLog().debug("Saving BlockState: " + s.toString());
mod.getModel().setState(s);
}
}
}

View file

@ -0,0 +1,87 @@
package de.jaschastarke.minecraft.limitedcreative.blockstate;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import de.jaschastarke.bukkit.lib.chat.ChatFormattings;
import de.jaschastarke.bukkit.lib.chat.InGameFormatter;
import de.jaschastarke.minecraft.limitedcreative.ModBlockStates;
import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState.Source;
public class PlayerListener implements Listener {
private ModBlockStates mod;
public PlayerListener(ModBlockStates mod) {
this.mod = mod;
}
@EventHandler(priority = EventPriority.HIGH)
public void onInteract(PlayerInteractEvent event) {
if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
Block b = event.getClickedBlock();
if (b != null && event.getPlayer().getInventory().getItemInMainHand().getType().equals(mod.getConfig().getTool()) && mod.getPlugin().getPermManager().hasPermission(event.getPlayer(), BlockStatePermissions.TOOL)) {
if (mod.getConfig().getIgnoredWorlds().contains(event.getClickedBlock().getWorld().getName())) {
event.getPlayer().sendMessage(mod.getPlugin().getLocale().trans("command.blockstate.world_ignored", event.getClickedBlock().getWorld().getName()));
} else {
showInfo(event.getPlayer(), b.getLocation(), b.getType());
}
}
}
}
@EventHandler(priority = EventPriority.HIGH)
public void onInteractEntity(PlayerInteractEntityEvent event) {
Entity e = event.getRightClicked();
if (e != null && e instanceof ItemFrame && event.getPlayer().getInventory().getItemInMainHand().getType().equals(mod.getConfig().getTool()) && mod.getPlugin().getPermManager().hasPermission(event.getPlayer(), BlockStatePermissions.TOOL)) {
if (mod.getConfig().getIgnoredWorlds().contains(e.getWorld().getName())) {
event.getPlayer().sendMessage(mod.getPlugin().getLocale().trans("command.blockstate.world_ignored", e.getWorld().getName()));
} else {
showInfo(event.getPlayer(), e.getLocation(), Material.ITEM_FRAME);
}
event.setCancelled(true);
}
}
private void showInfo(Player pl, Location loc, Material type) {
BlockState s = mod.getModel().getState(loc.getBlock());
InGameFormatter f = new InGameFormatter(mod.getPlugin().getLang());
String ret = null;
if (s == null || s.getSource() == Source.UNKNOWN) {
ret = f.formatString(ChatFormattings.ERROR, f.getString("block_state.tool_info.unknown", type.toString()));
} else {
String k = "block_state.tool_info." + s.getSource().name().toLowerCase();
String gm = "";
if (s.getGameMode() != null) {
switch (s.getGameMode()) {
case CREATIVE:
gm = ChatColor.GOLD + s.getGameMode().toString().toLowerCase() + ChatColor.RESET;
break;
case SURVIVAL:
gm = ChatColor.GREEN + s.getGameMode().toString().toLowerCase() + ChatColor.RESET;
break;
case ADVENTURE:
gm = ChatColor.DARK_GREEN + s.getGameMode().toString().toLowerCase() + ChatColor.RESET;
break;
default:
break;
}
}
ret = f.formatString(ChatFormattings.INFO, f.getString(k, type.toString(),
s.getPlayerName(),
gm,
s.getDate()));
}
if (ret != null)
pl.sendMessage(ret);
}
}

View file

@ -0,0 +1,212 @@
package de.jaschastarke.minecraft.limitedcreative.blockstate;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.bukkit.block.Block;
import de.jaschastarke.database.DatabaseConfigurationException;
import de.jaschastarke.minecraft.limitedcreative.ModBlockStates;
/**
* @internal I'm not happy with the error-handling here, especially in the Transaction, but I'll focus on the asynchronous
* variant, where all errors have to be handled in a separate thread.
*/
public class SyncronizedModel extends AbstractModel implements DBModel {
private ModBlockStates mod;
private DBQueries q;
public SyncronizedModel(ModBlockStates mod) throws DatabaseConfigurationException {
super(mod.getPlugin());
this.mod = mod;
this.q = new DBQueries(mod, mod.getPlugin().getDatabaseConnection());
}
@Override
public void onEnable() throws SQLException {
this.q.initTable();
}
@Override
public void onDisable() {
}
public void moveState(Block from, Block to) {
try {
q.delete(to.getLocation());
q.move(from.getLocation(), to.getLocation());
} catch (SQLException e) {
mod.getLog().severe(e.getMessage());
mod.getLog().warn("Failed to move BlockState in DB from " + from.getLocation().toString() + " to " + to.getLocation().toString());
}
moveMetaState(from, to);
}
public void removeState(BlockState state) {
removeState(state.getLocation().getBlock());
}
@Override
public void removeState(Block block) {
setMetaBlock(block, null);
try {
q.delete(block.getLocation());
} catch (SQLException e) {
mod.getLog().severe(e.getMessage());
mod.getLog().warn("Failed to delete BlockState in DB from " + block.getLocation().toString());
}
}
@Override
public Map<Block, Boolean> getRestrictedStates(List<Block> blocks) {
Map<Block, Boolean> ret = new HashMap<Block, Boolean>();
for (Map.Entry<Block, BlockState> entry : getStates(blocks).entrySet()) {
ret.put(entry.getKey(), entry.getValue() != null && entry.getValue().isRestricted());
}
return ret;
}
public Map<Block, BlockState> getStates(List<Block> blocks) {
Map<Block, BlockState> ret = new HashMap<Block, BlockState>();
Cuboid c = new Cuboid();
for (Block block : blocks) {
HasBlockState has = getMetaBlock(block);
if (has.isSet()) {
ret.put(block, has.getState());
} else {
c.add(block.getLocation());
}
}
if (!c.isEmpty()) {
try {
List<BlockState> dbb = q.findAllIn(c);
for (BlockState bs : dbb) {
setMetaBlock(bs.getLocation().getBlock(), bs);
if (blocks.contains(bs.getLocation().getBlock()))
ret.put(bs.getLocation().getBlock(), bs);
}
for (Block block : blocks) {
if (!ret.containsKey(block)) {
ret.put(block, null);
setMetaBlock(block, null);
}
}
} catch (SQLException e) {
mod.getLog().severe(e.getMessage());
mod.getLog().warn("Failed to fetch BlockState from DB in " + c.toString());
}
}
return ret;
}
public void cacheStates(Cuboid c) {
if (!c.isEmpty()) {
try {
List<BlockState> dbb = q.findAllIn(c);
for (BlockState bs : dbb) {
setMetaBlock(bs.getLocation().getBlock(), bs);
}
} catch (SQLException e) {
mod.getLog().severe(e.getMessage());
mod.getLog().warn("Failed to fetch BlockState (for caching) from DB in " + c.toString());
}
}
}
@Override
public boolean isRestricted(Block block) {
BlockState state = getState(block);
return state != null ? state.isRestricted() : false;
}
public BlockState getState(Block block) {
HasBlockState has = getMetaBlock(block);
if (!has.isSet()) {
try {
BlockState state = q.find(block.getLocation());
setMetaBlock(block, state);
return state;
} catch (SQLException e) {
mod.getLog().severe(e.getMessage());
mod.getLog().warn("Failed to fetch BlockState (for caching) from DB at " + block.getLocation().toString());
return null;
}
}
return has.getState();
}
public void setState(BlockState state) {
Block block = state.getLocation().getBlock();
boolean store = state != null && (state.isRestricted() || mod.getConfig().getLogSurvival());
setMetaBlock(block, store ? state : null);
try {
if (!store)
q.delete(state);
else if (!q.update(state))
q.insert(state);
} catch (SQLException e) {
mod.getLog().severe(e.getMessage());
mod.getLog().warn("Failed to update BlockState in DB at " + block.getLocation().toString());
}
}
@Override
public DBTransaction groupUpdate() {
return new Transaction();
}
private class Transaction implements DBTransaction {
private boolean finished = false;
private Transaction() {
try {
q.getDB().startTransaction();
} catch (SQLException e) {
mod.getLog().severe(e.getMessage());
finished = true;
}
}
@Override
public void moveState(Block from, Block to) {
if (finished)
throw new IllegalAccessError("Transaction already ended");
SyncronizedModel.this.moveState(from, to);
}
@Override
public void setState(BlockState state) {
if (finished)
throw new IllegalAccessError("Transaction already ended");
SyncronizedModel.this.setState(state);
}
@Override
public void removeState(Block block) {
if (finished)
throw new IllegalAccessError("Transaction already ended");
SyncronizedModel.this.removeState(block);
}
@Override
public void finish() {
try {
q.getDB().endTransaction();
} catch (SQLException e) {
mod.getLog().severe(e.getMessage());
} finally {
finished = true;
}
}
}
@Override
public int cleanUp(Cleanup target) {
try {
return q.cleanup(target);
} catch (SQLException e) {
mod.getLog().severe(e.getMessage());
mod.getLog().warn("Failed to cleanup BlockState-DB");
return -1;
}
}
}

View file

@ -0,0 +1,280 @@
package de.jaschastarke.minecraft.limitedcreative.blockstate;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.metadata.MetadataValue;
import org.bukkit.metadata.Metadatable;
import de.jaschastarke.database.DatabaseConfigurationException;
import de.jaschastarke.minecraft.limitedcreative.ModBlockStates;
import de.jaschastarke.minecraft.limitedcreative.blockstate.thread.CallableAction;
import de.jaschastarke.minecraft.limitedcreative.blockstate.thread.ThreadLink;
import de.jaschastarke.minecraft.limitedcreative.blockstate.thread.Transaction;
public class ThreadedModel extends AbstractModel implements DBModel, Listener {
private ModBlockStates mod;
private ThreadLink threads;
private MetadataValue metadataSet;
private MetadataValue metadataSetRestricted;
public ThreadedModel(ModBlockStates mod) {
super(mod.getPlugin());
this.mod = mod;
metadataSet = new FixedMetadataValue(mod.getPlugin(), new Boolean(true));
metadataSetRestricted = new FixedMetadataValue(mod.getPlugin(), new Object());
}
@Override
public void onEnable() throws SQLException, DatabaseConfigurationException {
DBQueries queries = new DBQueries(mod, mod.getPlugin().getDatabaseConnection());
queries.initTable();
threads = new ThreadLink(this, queries);
// We don't keep any reference to queries, because it contains the DB-Connection, which should be only used
// from the thread from now on (as SQLite may not threadsafe)
for (World w : mod.getPlugin().getServer().getWorlds()) {
if (!mod.getConfig().getIgnoredWorlds().containsIgnoreCase(w.getName())) {
for (Chunk chunk : w.getLoadedChunks()) {
threads.queueChunkLoad(chunk);
}
}
}
threads.start();
}
@Override
public void onDisable() {
try {
threads.shutdown();
} catch (InterruptedException e) {
e.printStackTrace();
mod.getLog().severe("Failed to clean end Database-Thread, maybe BlockStates haven't been saved");
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onChunkLoad(ChunkLoadEvent event) {
if (!mod.getConfig().getIgnoredWorlds().containsIgnoreCase(event.getWorld().getName())) {
threads.queueChunkLoad(event.getChunk());
}
}
@Override
public void moveState(Block from, Block to) {
threads.queueMetaMove(from.getLocation(), to.getLocation());
moveMetaState(from, to);
}
@Override
public void removeState(BlockState state) {
removeState(state.getLocation().getBlock());
}
@Override
public void removeState(Block block) {
setMetaBlock(block, null);
threads.queueUpdate(block);
}
@Override
public Map<Block, Boolean> getRestrictedStates(List<Block> blocks) {
Map<Block, Boolean> ret = new HashMap<Block, Boolean>();
for (Block block : blocks) {
HasBlockState has = getMetaBlock(block);
ret.put(block, has.isRestricted());
}
return ret;
}
@Override
public Map<Block, BlockState> getStates(List<Block> blocks) {
Map<Block, BlockState> ret = new HashMap<Block, BlockState>();
Cuboid c;
do {
c = new Cuboid();
for (Block block : blocks) {
HasBlockState has = getMetaBlock(block);
if (has.getState() != null || has.isNull()) {
ret.put(block, has.getState());
} else {
c.add(block.getLocation());
ret.put(block, null);
}
}
if (!c.isEmpty())
threads.callUpdate(c);
} while(!c.isEmpty());
return ret;
}
@Override
public void cacheStates(Cuboid c) {
threads.callUpdate(c);
}
@Override
public BlockState getState(Block block) {
HasBlockState has = getMetaBlock(block);
if (has.getState() == null && !has.isNull()) {
// The DB-Entry isn't set
// and the entry doesn't tell us that it knows that it isn't set
// (while using the threaded model, even having no Metadata entry, tells us there is no one in DB)
return threads.callUpdate(block);
}
return has.getState();
}
@Override
public boolean isRestricted(Block block) {
return getMetaBlock(block).isRestricted();
}
@Override
public void setState(BlockState state) {
Block block = state.getLocation().getBlock();
boolean store = state.isRestricted() || mod.getConfig().getLogSurvival();
setMetaBlock(block, store ? state : null);
threads.queueUpdate(block);
}
@Override
public DBTransaction groupUpdate() {
return new GroupUpdate(threads);
}
private class GroupUpdate extends Transaction {
public GroupUpdate(ThreadLink threads) {
super(threads);
}
@Override
public void moveState(Block from, Block to) {
moveMetaState(from, to);
super.moveState(from, to);
}
@Override
public void setState(BlockState state) {
Block block = state.getLocation().getBlock();
boolean store = state.isRestricted() || mod.getConfig().getLogSurvival();
setMetaBlock(block, store ? state : null);
super.setState(state);
}
@Override
public void removeState(Block block) {
setMetaBlock(block, null);
super.setState(block);
}
}
/**
* Metadata-Interface for the Thread-Link
*/
public HasBlockState getMetaState(Block block) {
return getMetaBlock(block);
}
/**
* Metadata-Interface for the Thread-Link
*/
public void setMetaState(Block block, BlockState state) {
super.setMetaBlock(block, state);
}
public void setSimpleMetaDataState(Block block, BlockState state) {
if (state == null)
super.setMetaBlock(block, null);
else if (state.isRestricted())
block.setMetadata(BSMDKEY, metadataSetRestricted);
else
block.setMetadata(BSMDKEY, metadataSet);
}
protected HasBlockState getMetaBlock(Metadatable m) {
HasBlockState has = null;
List<MetadataValue> metadata = m.getMetadata(BSMDKEY);
for (MetadataValue v : metadata) {
if (v.value() instanceof BlockState) {
// The actual DB-entry is in Metadata (requires more memory)
has = new HasBlockState((BlockState) v.value());
break;
} else if (v.getOwningPlugin() == mod.getPlugin()) {
if (v == metadataNull) {
// Metadata knows, that there is no entry in DB
has = new HasBlockState(true);
break;
} else if (v == metadataSet) {
// Metadata knows, that there is survival-entry in DB
has = new HasBlockState(true, false);
break;
} else if (v == metadataSetRestricted) {
// Metadata knows, that there is creative-entry in DB
has = new HasBlockState(true, true);
}
break;
}
}
if (has == null)
return new HasBlockState(false);
else
return has;
}
public static class HasBlockState extends AbstractModel.HasBlockState {
private boolean restricted = false;
private boolean isNull = false;
public HasBlockState(BlockState state) {
super(state);
restricted = state.isRestricted();
}
public HasBlockState(boolean isSet) {
super(isSet);
isNull = true;
}
public HasBlockState(boolean isSet, boolean isRestricted) {
super(isSet);
restricted = isRestricted;
}
public boolean isRestricted() {
return restricted;
}
public boolean isNull() {
return isNull;
}
}
public ModBlockStates getModel() {
return mod;
}
@Override
public int cleanUp(final Cleanup target) {
return threads.call(new CallableAction<Integer>() {
@Override
public void process(ThreadLink link, DBQueries q) {
this.returnSet = true;
try {
this.returnValue = q.cleanup(target);
} catch (SQLException e) {
this.returnValue = -1;
mod.getLog().severe(e.getMessage());
mod.getLog().warn("Failed to cleanup BlockState-DB");
}
}
});
}
}

View file

@ -0,0 +1,11 @@
package de.jaschastarke.minecraft.limitedcreative.blockstate.thread;
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBQueries;
public interface Action {
/**
* @internal Executed from asynchronous Thread. Only Thread-Safe methods should be called.
*/
void process(ThreadLink link, DBQueries q);
}

View file

@ -0,0 +1,64 @@
package de.jaschastarke.minecraft.limitedcreative.blockstate.thread;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.Set;
import org.bukkit.Chunk;
import org.bukkit.block.Block;
import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState;
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBModel.Cuboid;
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBQueries;
public class CacheChunkAction implements Action {
private static final int CHUNK_SIZE = 16;
private Chunk chunk;
public CacheChunkAction(Chunk chunk) {
this.chunk = chunk;
}
@Override
public void process(ThreadLink link, DBQueries q) {
if (!chunk.isLoaded())
return;
Set<Block> knownBlocks = new HashSet<Block>();
try {
if (chunk.isLoaded()) {
for (BlockState state : q.findAllIn(getBlocks())) {
if (chunk.isLoaded()) {
Block b = state.getLocation().getBlock();
knownBlocks.add(b);
link.setSimpleMetaState(b, state);
}
}
}
/*int h = chunk.getWorld().getMaxHeight();
for (int y = 0; y < h; y++) {
for (int x = 0; x < CHUNK_SIZE; x++) {
for (int z = 0; z < CHUNK_SIZE; z++) {
Block b = chunk.getBlock(x, y, z);
if (!knownBlocks.contains(b) && b.getType() != Material.AIR) {
link.setSimpleMetaState(b, null);
link.blockCount++;
}
}
}
}*/
} catch (SQLException e) {
link.getLog().severe(e.getMessage());
link.getLog().warn("Thread " + Thread.currentThread().getName() + " failed to load BlockStates for Chunk " + chunk.getX() + "/" + chunk.getZ());
}
}
protected Cuboid getBlocks() {
Cuboid c = new Cuboid();
c.add(chunk.getBlock(0, 0, 0).getLocation());
int h = chunk.getWorld().getMaxHeight();
c.add(chunk.getBlock(CHUNK_SIZE - 1, h - 1, CHUNK_SIZE - 1).getLocation());
return c;
}
}

View file

@ -0,0 +1,18 @@
package de.jaschastarke.minecraft.limitedcreative.blockstate.thread;
public abstract class CallableAction<E> implements Action {
protected boolean returnSet = false;
protected E returnValue = null;
public E getValue() {
synchronized (this) {
try {
while (!returnSet)
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return returnValue;
}
}

View file

@ -0,0 +1,34 @@
package de.jaschastarke.minecraft.limitedcreative.blockstate.thread;
import java.sql.SQLException;
import org.bukkit.block.Block;
import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState;
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBQueries;
public class FetchBlockStateAction extends CallableAction<BlockState> {
private Block block;
public FetchBlockStateAction(Block block) {
this.block = block;
}
@Override
public void process(ThreadLink link, DBQueries q) {
BlockState state = null;
try {
state = q.find(block.getLocation());
link.setMetaState(block, state);
} catch (SQLException e) {
link.getLog().severe(e.getMessage());
link.getLog().warn("Thread " + Thread.currentThread().getName() + " failed to fetch BlockState from DB: " + block.getLocation());
return;
}
synchronized (this) {
returnValue = state;
returnSet = true;
this.notify();
}
}
}

View file

@ -0,0 +1,36 @@
package de.jaschastarke.minecraft.limitedcreative.blockstate.thread;
import java.sql.SQLException;
import java.util.List;
import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState;
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBModel.Cuboid;
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBQueries;
public class FetchCuboidAction extends CallableAction<List<BlockState>> {
private Cuboid cuboid;
public FetchCuboidAction(Cuboid cuboid) {
this.cuboid = cuboid;
}
@Override
public void process(ThreadLink link, DBQueries q) {
List<BlockState> states = null;
try {
states = q.findAllIn(cuboid);
for (BlockState bs : states) {
link.setMetaState(bs.getLocation().getBlock(), bs);
}
} catch (SQLException e) {
link.getLog().severe(e.getMessage());
link.getLog().warn("Thread " + Thread.currentThread().getName() + " failed to fetch BlockState from DB: " + cuboid);
return;
}
synchronized (this) {
returnValue = states;
returnSet = true;
this.notify();
}
}
}

View file

@ -0,0 +1,34 @@
package de.jaschastarke.minecraft.limitedcreative.blockstate.thread;
import java.sql.SQLException;
import org.bukkit.Location;
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBQueries;
public class MoveBlockStateAction extends TransactionAction implements Action {
private Location from;
private Location to;
public MoveBlockStateAction(Location from, Location to) {
this.from = from;
this.to = to;
}
@Override
public void process(ThreadLink link, DBQueries q) {
try {
processInTransaction(link, q);
} catch (SQLException e) {
link.getLog().severe(e.getMessage());
link.getLog().warn("Thread " + Thread.currentThread().getName() + " failed to move BlockState in DB from " + from.toString() + " to " + to.toString());
}
}
@Override
public void processInTransaction(ThreadLink link, DBQueries q) throws SQLException {
q.delete(to);
q.move(from, to);
}
}

View file

@ -0,0 +1,241 @@
package de.jaschastarke.minecraft.limitedcreative.blockstate.thread;
import de.jaschastarke.bukkit.lib.ModuleLogger;
import de.jaschastarke.minecraft.limitedcreative.ModBlockStates;
import de.jaschastarke.minecraft.limitedcreative.blockstate.AbstractModel.HasBlockState;
import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState;
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBModel.Cuboid;
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBQueries;
import de.jaschastarke.minecraft.limitedcreative.blockstate.ThreadedModel;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.block.Block;
import java.lang.Thread.UncaughtExceptionHandler;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
public class ThreadLink {
private static final int BATCH_ACTION_LENGTH = 25;
private static final int QUEUE_ACCESS_WARNING_DURATION = 5; // ms
private static final int COUNT_WARNING_QUEUE = 5;
private static final int COUNT_ERROR_QUEUE = 20;
private static final int QUEUE_TIMING_DURATION = 500; // ms
private static final int STARTUP_TIMING = 30000; // ms
private static final int THREAD_SHUTDOWN_WAIT_MS = 30000;
private long lastTimeout;
private final Stack<Action> updateQueue = new Stack<Action>();
private boolean shutdown;
private ModuleLogger log;
private ThreadedModel model;
private Thread thread;
public ThreadLink(ThreadedModel threadedModel, DBQueries queries) {
model = threadedModel;
log = threadedModel.getModel().getLog();
/*
* In theory we could add multiple threads, e.g. 1 write and 2 read threads.
*/
createThread(queries);
shutdown = true; //Don't allow the thread to run until it's started
}
private class DBThread extends Thread {
private DBQueries q;
public DBThread(DBQueries queries) {
super();
this.q = queries;
}
public void run() {
if (getModule().isDebug())
log.debug("DB-Thread '" + Thread.currentThread().getName() + "' started.");
lastTimeout = System.currentTimeMillis() + STARTUP_TIMING;
while (!shutdown || !updateQueue.isEmpty()) {
try {
//Thread.sleep(1000);
//throw new RuntimeException("Test exception pls ignore");
List<Action> acts = new LinkedList<Action>();
synchronized (updateQueue) {
while (updateQueue.isEmpty() && !shutdown)
updateQueue.wait();
if (updateQueue.size() > (BATCH_ACTION_LENGTH * COUNT_ERROR_QUEUE)) {
if (System.currentTimeMillis() - lastTimeout > QUEUE_TIMING_DURATION) {
getLog().warn("Extrem large DB-Queue in " + Thread.currentThread().getName() + ": " + updateQueue.size());
lastTimeout = System.currentTimeMillis();
}
} else if (updateQueue.size() > (BATCH_ACTION_LENGTH * COUNT_WARNING_QUEUE)) {
if (System.currentTimeMillis() - lastTimeout > QUEUE_TIMING_DURATION) {
getLog().info("Large DB-Queue in " + Thread.currentThread().getName() + ": " + updateQueue.size());
lastTimeout = System.currentTimeMillis();
}
} else if (updateQueue.size() <= BATCH_ACTION_LENGTH) {
lastTimeout = System.currentTimeMillis();
}
for (int i = 0; i < BATCH_ACTION_LENGTH && !updateQueue.isEmpty(); i++) {
acts.add(updateQueue.pop());
}
}
long t = 0;
if (getModule().isDebug()) {
t = System.currentTimeMillis();
log.debug("DB-Thread '" + Thread.currentThread().getName() + "' run: " + acts.size());
}
for (Action act : acts) {
if (!shutdown || !(act instanceof CacheChunkAction)) {
if (act instanceof CallableAction) {
//noinspection SynchronizationOnLocalVariableOrMethodParameter
synchronized (act) {
act.process(ThreadLink.this, this.q);
act.notify();
}
} else {
act.process(ThreadLink.this, this.q);
}
}
}
if (getModule().isDebug())
log.debug("DB-Thread '" + Thread.currentThread().getName() + "' execution time: " + (System.currentTimeMillis() - t) + "ms");
} catch (InterruptedException e) {
e.printStackTrace();
log.severe("DB-Thread '" + Thread.currentThread().getName() + "' was harmfully interupted");
}
Thread.yield();
}
if (getModule().isDebug())
log.debug("DB-Thread " + Thread.currentThread().getName() + " finished.");
}
}
public void start() {
shutdown = false;
if (!thread.isAlive())
thread.start();
}
public void queueUpdate(Block block) {
restartThreadIfNeeded();
long l = System.currentTimeMillis();
synchronized (updateQueue) {
updateQueue.add(new UpdateBlockStateAction(block));
updateQueue.notifyAll();
}
long l2 = System.currentTimeMillis();
if (l2 - l > QUEUE_ACCESS_WARNING_DURATION) {
getLog().warn("queueUpdate-action took too long: " + (l2 - l) + "ms");
}
}
public BlockState callUpdate(Block block) {
restartThreadIfNeeded();
FetchBlockStateAction action = new FetchBlockStateAction(block);
synchronized (updateQueue) {
updateQueue.push(action);
updateQueue.notifyAll();
}
return action.getValue();
}
public void queue(Action act) {
restartThreadIfNeeded();
synchronized (updateQueue) {
updateQueue.add(act);
updateQueue.notifyAll();
}
}
public <T> T call(CallableAction<T> act) {
restartThreadIfNeeded();
synchronized (updateQueue) {
updateQueue.push(act);
updateQueue.notifyAll();
}
return act.getValue();
}
public List<BlockState> callUpdate(Cuboid c) {
FetchCuboidAction action = new FetchCuboidAction(c);
synchronized (updateQueue) {
updateQueue.push(action);
updateQueue.notifyAll();
}
return action.getValue();
}
public void queueMetaMove(Location from, Location to) {
restartThreadIfNeeded();
synchronized (updateQueue) {
updateQueue.add(new MoveBlockStateAction(from, to));
updateQueue.notifyAll();
}
}
public void queueChunkLoad(Chunk chunk) {
restartThreadIfNeeded();
synchronized (updateQueue) {
updateQueue.add(new CacheChunkAction(chunk));
updateQueue.notifyAll();
}
}
public void queueTransaction(Transaction transaction) {
restartThreadIfNeeded();
synchronized (updateQueue) {
updateQueue.add(transaction);
updateQueue.notifyAll();
}
}
public void shutdown() throws InterruptedException {
synchronized (updateQueue) {
shutdown = true;
updateQueue.notifyAll();
}
thread.join(THREAD_SHUTDOWN_WAIT_MS);
if (thread.isAlive())
thread.interrupt(); //Wake it up
}
public HasBlockState getMetaState(Block block) {
return model.getMetaState(block);
}
public void setMetaState(Block block, BlockState state) {
model.setMetaState(block, state);
}
public void setSimpleMetaState(Block block, BlockState state) {
model.setSimpleMetaDataState(block, state);
}
public ModBlockStates getModule() {
return model.getModel();
}
public ModuleLogger getLog() {
return log;
}
private void restartThreadIfNeeded() {
if ((thread != null && thread.isAlive()) || shutdown)
return;
log.warn("Thread is dead, restarting!");
new Exception("Thread-restarting update called").printStackTrace();
createThread(((DBThread) thread).q);
start();
}
private void createThread(DBQueries queries) {
if (shutdown)
return;
thread = new DBThread(queries);
thread.setName("LC BlockState DB-Thread");
thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable e) {
e.printStackTrace();
log.severe("Thread " + thread.getName() + " encoutered an uncaught Exception: " + e.getMessage());
}
});
}
}

View file

@ -0,0 +1,74 @@
package de.jaschastarke.minecraft.limitedcreative.blockstate.thread;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;
import org.bukkit.block.Block;
import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState;
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBModel.DBTransaction;
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBQueries;
abstract public class Transaction implements DBTransaction, Action {
protected boolean finished = false;
private List<TransactionAction> actions = new LinkedList<TransactionAction>();
private ThreadLink link;
public Transaction(ThreadLink link) {
this.link = link;
}
@Override
public void moveState(Block from, Block to) {
if (finished)
throw new IllegalAccessError("Transaction already ended");
actions.add(new MoveBlockStateAction(from.getLocation(), to.getLocation()));
}
@Override
public void setState(BlockState state) {
if (finished)
throw new IllegalAccessError("Transaction already ended");
Block block = state.getLocation().getBlock();
actions.add(new UpdateBlockStateAction(block));
}
public void setState(Block block) {
if (finished)
throw new IllegalAccessError("Transaction already ended");
actions.add(new UpdateBlockStateAction(block));
}
@Override
public void finish() {
if (finished)
return;
link.queueTransaction(this);
}
/**
* @internal Executed from asynchronous Thread. Only Thread-Safe methods should be called.
*/
@Override
public void process(ThreadLink link, DBQueries q) {
if (actions.isEmpty())
return;
try {
q.getDB().startTransaction();
for (TransactionAction act : actions) {
act.processInTransaction(link, q);
}
q.getDB().endTransaction();
} catch (SQLException e) {
try {
q.getDB().revertTransaction();
} catch (SQLException e1) {}
link.getLog().severe(e.getMessage());
link.getLog().warn("Thread " + Thread.currentThread().getName() + " failed to write Transaction to the Database");
}
}
}

View file

@ -0,0 +1,9 @@
package de.jaschastarke.minecraft.limitedcreative.blockstate.thread;
import java.sql.SQLException;
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBQueries;
abstract public class TransactionAction implements Action {
abstract public void processInTransaction(ThreadLink link, DBQueries q) throws SQLException;
}

View file

@ -0,0 +1,41 @@
package de.jaschastarke.minecraft.limitedcreative.blockstate.thread;
import java.sql.SQLException;
import org.bukkit.block.Block;
import de.jaschastarke.minecraft.limitedcreative.blockstate.AbstractModel.HasBlockState;
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBQueries;
public class UpdateBlockStateAction extends TransactionAction implements Action {
private Block block;
public UpdateBlockStateAction(Block block) {
this.block = block;
}
@Override
public void process(ThreadLink link, DBQueries q) {
HasBlockState state = link.getMetaState(block);
if (state.isSet()) {
try {
q.delete(block.getLocation());
if (state.getState() != null)
q.insert(state.getState());
} catch (SQLException e) {
link.getLog().severe(e.getMessage());
link.getLog().warn("Thread " + Thread.currentThread().getName() + " failed to save BlockState to DB: " + state.getState());
}
}
}
@Override
public void processInTransaction(ThreadLink link, DBQueries q) throws SQLException {
HasBlockState state = link.getMetaState(block);
if (state.isSet()) {
q.delete(block.getLocation());
if (state.getState() != null)
q.insert(state.getState());
}
}
}

View file

@ -0,0 +1,60 @@
package de.jaschastarke.minecraft.limitedcreative.blockstate.worldedit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import de.jaschastarke.minecraft.limitedcreative.ModBlockStates;
import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState;
import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState.Source;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import java.util.Date;
public class EditSessionExtent extends AbstractDelegateExtent {
private ModBlockStates mod;
private Player player = null;
private World world;
public EditSessionExtent(Extent extent, ModBlockStates mod, Player player, World world) {
super(extent);
this.mod = mod;
this.player = player;
this.world = world;
}
/**
* Called when a block is being changed.
*
* @param pt the position
* @param newBlock the new block to replace the old one
*/
@Override
public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 pt, T newBlock) throws WorldEditException {
if (mod.isDebug())
mod.getLog().debug("WorldEdit-Integration: BlockChange: " + pt.toString() + " BB: " + newBlock.toString());
Location loc = new Location(world, pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
if (newBlock.getBlockType().getMaterial().isAir()) {
mod.getModel().removeState(loc.getBlock());
} else {
BlockState s = mod.getModel().getState(loc.getBlock());
if (s == null) {
s = new BlockState();
s.setLocation(loc);
}
s.setGameMode(null);
s.setPlayerNameOrUUID(player.getUniqueId().toString());
s.setDate(new Date());
s.setSource(Source.EDIT);
if (mod.isDebug())
mod.getLog().debug("WorldEdit-Integration: Saving BlockState: " + s.toString());
mod.getModel().setState(s);
}
super.setBlock(pt, newBlock);
return true;
}
}

View file

@ -0,0 +1,38 @@
package de.jaschastarke.minecraft.limitedcreative.blockstate.worldedit;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import com.sk89q.worldedit.EditSession.Stage;
import com.sk89q.worldedit.bukkit.BukkitWorld;
import com.sk89q.worldedit.event.extent.EditSessionEvent;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.util.eventbus.Subscribe;
import com.sk89q.worldedit.world.World;
import de.jaschastarke.minecraft.limitedcreative.ModBlockStates;
public class EditSessionListener {
private ModBlockStates mod;
public EditSessionListener(ModBlockStates mod) {
this.mod = mod;
}
@Subscribe
public void onEditSession(EditSessionEvent event) {
if (mod.getConfig().getWorldeditIntegration()) {
if (event.getStage() == Stage.BEFORE_CHANGE) {
if (mod.isDebug())
mod.getLog().debug("WorldEdit-Integration: New EditSession: "+event.getActor().getName()+" in World "+event.getWorld().getName()); // + " (" + event.getStage() + ")");
Actor actor = event.getActor();
World world = event.getWorld();
if (actor != null && actor.isPlayer() && world != null && world instanceof BukkitWorld) {
Player player = Bukkit.getPlayer(actor.getUniqueId());
event.setExtent(new EditSessionExtent(event.getExtent(), mod, player, ((BukkitWorld) event.getWorld()).getWorld()));
}
}
}
}
}

View file

@ -0,0 +1,64 @@
package de.jaschastarke.minecraft.limitedcreative.cmdblocker;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import de.jaschastarke.bukkit.lib.configuration.ConfigurableList;
import de.jaschastarke.bukkit.lib.configuration.IToGeneric;
import de.jaschastarke.bukkit.lib.configuration.command.ITabComplete;
import de.jaschastarke.bukkit.lib.configuration.command.ListConfigValue;
import de.jaschastarke.configuration.InvalidValueException;
public class CmdBlockList extends ArrayList<ICmdBlockEntry> implements ConfigurableList<ICmdBlockEntry>, IToGeneric, ITabComplete {
private static final long serialVersionUID = -125544131527849084L;
@Override
public boolean addSetting(String cmd) throws InvalidValueException {
if (cmd.startsWith("^")) {
return add(new RegexpBlockEntry(cmd));
} else {
return add(new StringBlockEntry(cmd));
}
}
@Override
public boolean removeSetting(String e) {
for (Iterator<ICmdBlockEntry> iterator = this.iterator(); iterator.hasNext();) {
ICmdBlockEntry entry = iterator.next();
if (entry.toString().equalsIgnoreCase(e)) {
iterator.remove();
return true;
}
}
return false;
}
@Override
public List<String> toGeneric() {
List<String> list = new ArrayList<String>(size());
for (ICmdBlockEntry bl : this) {
list.add(bl.toString());
}
return list;
}
@Override
public void clearSettings() {
clear();
}
public List<String> tabComplete(String[] args, String[] chain) {
if (args.length > 0 && chain.length > 0) {
if (chain[chain.length - 1].equalsIgnoreCase(ListConfigValue.REMOVE)) {
List<String> hints = new ArrayList<String>();
for (ICmdBlockEntry s : this) {
if (s.toString().toLowerCase().startsWith(args[0].toLowerCase()))
hints.add(s.toString());
}
return hints;
}
}
return null;
}
}

View file

@ -0,0 +1,69 @@
package de.jaschastarke.minecraft.limitedcreative.cmdblocker;
import java.util.Collection;
import org.bukkit.permissions.PermissionDefault;
import de.jaschastarke.maven.ArchiveDocComments;
import de.jaschastarke.maven.PluginPermissions;
import de.jaschastarke.minecraft.lib.permissions.BasicPermission;
import de.jaschastarke.minecraft.lib.permissions.DynamicPermission;
import de.jaschastarke.minecraft.lib.permissions.IAbstractPermission;
import de.jaschastarke.minecraft.lib.permissions.IDynamicPermission;
import de.jaschastarke.minecraft.lib.permissions.IPermission;
import de.jaschastarke.minecraft.lib.permissions.SimplePermissionContainerNode;
import de.jaschastarke.minecraft.limitedcreative.Permissions;
@ArchiveDocComments
public class CmdBlockPermissions extends SimplePermissionContainerNode {
public CmdBlockPermissions(IAbstractPermission parent, String name) {
super(parent, name);
}
@PluginPermissions
public static final SimplePermissionContainerNode CONTAINER = new CmdBlockPermissions(Permissions.CONTAINER, "cmdblock");
/**
* Allows bypassing the "command block"-limitation. So no commands are blocked for this users.
*/
public static final IPermission ALL = new BasicPermission(CONTAINER, "*", PermissionDefault.OP);
/**
* Allows to bypass specific blockings of commands as it tests against all partial permissions:
*
* Example:
* A Command "/execute a fuzzy command -n 256" is entered by the player which is blocked by the configuration the
* following permissions are tested, and if one is present for the user, he is allowed to execute the command:
* - limitedcreative.cmdblock.*
* - limitedcreative.cmdblock.execute
* - limitedcreative.cmdblock.execute.a
* - limitedcreative.cmdblock.execute.a.fuzzy
* - limitedcreative.cmdblock.execute.a.fuzzy.command
* - limitedcreative.cmdblock.execute.a.fuzzy.command.-n
* - limitedcreative.cmdblock.execute.a.fuzzy.command.-n.256
*/
public static IDynamicPermission COMMAND(String cmd) {
return new CommandPermission(ALL, cmd);
}
public static class CommandPermission extends DynamicPermission {
private String cmd;
public CommandPermission(IAbstractPermission parent, String cmd) {
super(parent);
this.cmd = cmd;
}
@Override
protected void buildPermissionsToCheck(Collection<IAbstractPermission> perms) {
String[] chunks = cmd.split("\\s+");
String chain = "";
for (String chunk : chunks) {
if (chain.length() > 0)
chain += IAbstractPermission.SEP;
chain += chunk;
perms.add(new BasicPermission(CONTAINER, chain));
}
}
}
}

View file

@ -0,0 +1,110 @@
package de.jaschastarke.minecraft.limitedcreative.cmdblocker;
import org.bukkit.configuration.ConfigurationSection;
import de.jaschastarke.bukkit.lib.configuration.Configuration;
import de.jaschastarke.bukkit.lib.configuration.ConfigurationContainer;
import de.jaschastarke.configuration.IConfigurationNode;
import de.jaschastarke.configuration.IConfigurationSubGroup;
import de.jaschastarke.configuration.InvalidValueException;
import de.jaschastarke.configuration.annotations.IsConfigurationNode;
import de.jaschastarke.maven.ArchiveDocComments;
import de.jaschastarke.maven.PluginConfigurations;
import de.jaschastarke.minecraft.limitedcreative.Config;
import de.jaschastarke.minecraft.limitedcreative.ModCmdBlocker;
import de.jaschastarke.modularize.IModule;
import de.jaschastarke.modularize.ModuleEntry;
/**
* CommandBlocker-Feature
*
* http://dev.bukkit.org/server-mods/limited-creative/pages/features/command-blocker/
*/
@ArchiveDocComments
@PluginConfigurations(parent = Config.class)
public class CmdBlockerConfig extends Configuration implements IConfigurationSubGroup {
private CmdBlockList blockList;
protected ModCmdBlocker mod;
protected ModuleEntry<IModule> entry;
public CmdBlockerConfig(ConfigurationContainer container) {
super(container);
}
public CmdBlockerConfig(ModCmdBlocker modCmdBlocker, ModuleEntry<IModule> modEntry) {
super(modCmdBlocker.getPlugin().getDocCommentStorage());
mod = modCmdBlocker;
entry = modEntry;
}
@Override
public void setValues(ConfigurationSection sect) {
blockList = null;
super.setValues(sect);
entry.setDefaultEnabled(getEnabled());
}
@Override
public void setValue(IConfigurationNode node, Object pValue) throws InvalidValueException {
super.setValue(node, pValue);
if (node.getName().equals("enabled")) {
entry.setEnabled(getEnabled());
}
}
@Override
public String getName() {
return "cmdblock";
}
@Override
public int getOrder() {
return 500;
}
/**
* CmdBlockerEnabled
*
* Enables the feature for blocking certain commands in creative mode.
*
* default: true
*/
@IsConfigurationNode(order = 100)
public boolean getEnabled() {
return config.getBoolean("enabled", true);
}
/**
* CmdBlockerList
*
* Defines the list of commands that are blocked while in creative mode. The leading / isn't included. By default
* the list-item is treated as simple string as typed in by the user after the /. All commands starting with
* this string are blocked, even if more parameteres are entered by the user.
* If the first character is ^ the entry is interpreted as a regular expression (including the ^ for begin of the string).
* Only use regular expressions if you know them!
*
* Examples:
* - home
* - give diamond
* - ^home .+
* - ^chest (one|two|three)
* - ^(lc|limitedcreative) s(urvival)?\s*$
*
* default: []
*/
@IsConfigurationNode(order = 200, name = "commands")
public CmdBlockList getCommandBlockList() {
if (blockList == null) {
blockList = new CmdBlockList();
if (config.contains("commands") && config.isList("commands")) {
for (Object e : config.getList("commands")) {
try {
blockList.addSetting(e.toString());
} catch (InvalidValueException e1) {
mod.getLog().warn(e1.getMessage());
}
}
}
}
return blockList;
}
}

View file

@ -0,0 +1,36 @@
package de.jaschastarke.minecraft.limitedcreative.cmdblocker;
import org.bukkit.GameMode;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import de.jaschastarke.minecraft.limitedcreative.ModCmdBlocker;
public class CommandListener implements Listener {
private ModCmdBlocker mod;
public CommandListener(ModCmdBlocker mod) {
this.mod = mod;
}
@EventHandler
public void onPreCommand(PlayerCommandPreprocessEvent event) {
if (event.getPlayer().getGameMode() == GameMode.CREATIVE) {
String cmd = event.getMessage();
if (cmd.startsWith("/")) { // just to be sure ;)
cmd = cmd.substring(1);
for (ICmdBlockEntry blockentry : mod.getConfig().getCommandBlockList()) {
if (blockentry.test(cmd)) {
if (!mod.getPlugin().getPermManager().hasPermission(event.getPlayer(), CmdBlockPermissions.COMMAND(cmd))) {
if (mod.isDebug())
mod.getLog().debug("CmdBlock: " + event.getPlayer().getName() + ": '/" + cmd + "' blocked by rule '" + blockentry.toString() + "'");
event.setCancelled(true);
event.getPlayer().sendMessage(mod.getPlugin().getLocale().trans("cmdblock.blocked"));
return;
}
}
}
}
}
}
}

View file

@ -1,4 +1,4 @@
package de.jaschastarke.minecraft.limitedcreative.cmdblock;
package de.jaschastarke.minecraft.limitedcreative.cmdblocker;
public interface ICmdBlockEntry {
public boolean test(String cmd);

View file

@ -1,11 +1,11 @@
package de.jaschastarke.minecraft.limitedcreative.cmdblock;
package de.jaschastarke.minecraft.limitedcreative.cmdblocker;
import java.util.regex.Pattern;
public class RegexpBlockEntry implements ICmdBlockEntry {
private Pattern rx;
public RegexpBlockEntry(String regex) {
rx = Pattern.compile(regex);
rx = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
}
@Override

View file

@ -1,4 +1,4 @@
package de.jaschastarke.minecraft.limitedcreative.cmdblock;
package de.jaschastarke.minecraft.limitedcreative.cmdblocker;
public class StringBlockEntry implements ICmdBlockEntry {
private String str;
@ -8,7 +8,7 @@ public class StringBlockEntry implements ICmdBlockEntry {
@Override
public boolean test(String cmd) {
return cmd.startsWith(this.str);
return cmd.toLowerCase().startsWith(this.str.toLowerCase());
}
public String toString() {

View file

@ -0,0 +1,109 @@
package de.jaschastarke.minecraft.limitedcreative.gmperm;
import org.bukkit.configuration.ConfigurationSection;
import de.jaschastarke.bukkit.lib.configuration.Configuration;
import de.jaschastarke.bukkit.lib.configuration.ConfigurationContainer;
import de.jaschastarke.configuration.IConfigurationNode;
import de.jaschastarke.configuration.IConfigurationSubGroup;
import de.jaschastarke.configuration.InvalidValueException;
import de.jaschastarke.configuration.annotations.IsConfigurationNode;
import de.jaschastarke.maven.ArchiveDocComments;
import de.jaschastarke.maven.PluginConfigurations;
import de.jaschastarke.minecraft.limitedcreative.Config;
import de.jaschastarke.minecraft.limitedcreative.ModGameModePerm;
import de.jaschastarke.modularize.IModule;
import de.jaschastarke.modularize.ModuleEntry;
/**
* GameMode-Permissions-Feature
*
* This Feature requires Vault-Plugin to be active.
*
* http://dev.bukkit.org/server-mods/limited-creative/pages/features/gmperm/
*/
@ArchiveDocComments
@PluginConfigurations(parent = Config.class)
public class GMPermConfig extends Configuration implements IConfigurationSubGroup {
protected ModGameModePerm mod;
protected ModuleEntry<IModule> entry;
public GMPermConfig(ConfigurationContainer container) {
super(container);
}
public GMPermConfig(ModGameModePerm modGameModePerm, ModuleEntry<IModule> modEntry) {
super(modGameModePerm.getPlugin().getDocCommentStorage());
mod = modGameModePerm;
entry = modEntry;
}
@Override
public void setValue(IConfigurationNode node, Object pValue) throws InvalidValueException {
super.setValue(node, pValue);
if (node.getName().equals("enabled")) {
entry.setEnabled(getEnabled());
}
}
@Override
public void setValues(ConfigurationSection sect) {
super.setValues(sect);
entry.setDefaultEnabled(getEnabled());
}
@Override
public String getName() {
return "gmperm";
}
@Override
public int getOrder() {
return 600;
}
/**
* GMPermEnabled
*
* Activates that players are put in a special permission group while in creative mode.
*
* default: false
*/
@IsConfigurationNode(order = 100)
public boolean getEnabled() {
return config.getBoolean("enabled", false);
}
/**
* GMPermCreativeGroup
*
* Defines the Permission-Group which the player gets added to on entering creative-mode. If this value is changed
* the old group won't be automatically removed from players already in it. So be sure to delete the old group or
* remove all player of it, that they don't get stuck with that permissions.
*/
@IsConfigurationNode(order = 200)
public String getCreativeGroup() {
return config.getString("creativeGroup", "");
}
/**
* GMPermAdventureGroup
*
* Like GMPermCreativeGroup but for adventure users. This is optional, so you don't have to set any group.
*
* default: false
*/
@IsConfigurationNode(order = 300)
public String getAdventureGroup() {
if (config.isBoolean("adventureGroup"))
return null;
return config.getString("adventureGroup", null);
}
@Override
public Object getValue(final IConfigurationNode node) {
Object val = super.getValue(node);
if (node.getName().equals("adventureGroup") && val == null) {
return new Boolean(false);
} else {
return val;
}
}
}

View file

@ -0,0 +1,33 @@
package de.jaschastarke.minecraft.limitedcreative.gmperm;
import net.milkbowl.vault.permission.Permission;
import org.bukkit.plugin.RegisteredServiceProvider;
import de.jaschastarke.bukkit.lib.CoreModule;
public class PermissionInterface {
//private CoreModule<?> mod;
private Permission permission = null;
private RegisteredServiceProvider<Permission> permissionProvider;
public PermissionInterface(CoreModule<?> mod) {
//this.mod = mod;
permissionProvider = mod.getPlugin().getServer().getServicesManager().getRegistration(Permission.class);
}
public boolean isPresent() {
return permissionProvider != null && permissionProvider.getProvider() != null;
}
public void clear() {
permission = null;
}
public Permission getPermission() {
if (permission == null)
permission = permissionProvider.getProvider();
return permission;
}
}

View file

@ -0,0 +1,95 @@
/*
* Limited Creative - (Bukkit Plugin)
* Copyright (C) 2012 jascha@ja-s.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.jaschastarke.minecraft.limitedcreative.gmperm;
import net.milkbowl.vault.permission.Permission;
import org.bukkit.GameMode;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerGameModeChangeEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerLoginEvent.Result;
import de.jaschastarke.minecraft.limitedcreative.ModGameModePerm;
public class PlayerListener implements Listener {
private ModGameModePerm mod;
public PlayerListener(ModGameModePerm mod) {
this.mod = mod;
}
protected Permission v() {
return mod.getPermissionInterface().getPermission();
}
@EventHandler(priority = EventPriority.MONITOR)
public void onGameModeChange(PlayerGameModeChangeEvent event) {
if (event.isCancelled())
return;
ensureGroup(event.getPlayer(), event.getNewGameMode());
}
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerLogin(PlayerLoginEvent event) {
if (event.getResult() == Result.ALLOWED)
return;
ensureGroup(event.getPlayer());
}
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerTeleport(PlayerTeleportEvent event) {
if (!event.getFrom().getWorld().equals(event.getTo().getWorld())) {
ensureGroup(event.getPlayer());
}
}
protected void ensureGroup(Player player) {
ensureGroup(player, player.getGameMode());
}
protected void ensureGroup(Player player, GameMode gm) {
String cgroup = mod.getConfig().getCreativeGroup();
String agroup = mod.getConfig().getAdventureGroup();
if (gm == GameMode.CREATIVE) {
if (!v().playerInGroup(player, cgroup)) {
v().playerAddGroup(player, cgroup);
}
if (agroup != null && v().playerInGroup(player, agroup)) {
v().playerRemoveGroup(player, agroup);
}
} else if (gm == GameMode.ADVENTURE) {
if (v().playerInGroup(player, cgroup)) {
v().playerRemoveGroup(player, cgroup);
}
if (agroup != null && !v().playerInGroup(player, agroup)) {
v().playerAddGroup(player, agroup);
}
} else if (gm == GameMode.SURVIVAL) {
if (v().playerInGroup(player, cgroup)) {
v().playerRemoveGroup(player, cgroup);
}
if (agroup != null && v().playerInGroup(player, agroup)) {
v().playerRemoveGroup(player, agroup);
}
}
}
}

View file

@ -0,0 +1,21 @@
package de.jaschastarke.minecraft.limitedcreative.hooks;
import de.jaschastarke.minecraft.limitedcreative.Hooks;
import de.jaschastarke.minecraft.limitedcreative.LimitedCreative;
import fr.xephi.authme.api.v3.AuthMeApi;
import org.bukkit.entity.Player;
//@Deprecated // AuthMe 3.0 released. Compatibility for older versions will be removed sometime
public class AuthMeHooks {
public AuthMeHooks(final LimitedCreative plugin) {
Hooks.IsLoggedIn.register(new PlayerCheckHooker.Check() {
@Override
public boolean test(Player player) {
boolean li = AuthMeApi.getInstance().isAuthenticated(player);
if (plugin.isDebug()) // not nessesary, but so no string concation without debug needed
plugin.getLog().debug("AuthMe: "+player.getName()+": logged in: "+li);
return li;
}
});
}
}

View file

@ -0,0 +1,38 @@
package de.jaschastarke.minecraft.limitedcreative.hooks;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.World;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import de.jaschastarke.hooking.BooleanHooker;
import de.jaschastarke.minecraft.limitedcreative.Hooks;
import de.jaschastarke.minecraft.limitedcreative.LimitedCreative;
public class MultiVerseHooks {
public MultiVerseHooks(final LimitedCreative plugin) {
Hooks.IsMultiVerse.register(new BooleanHooker.Check() {
@Override
public boolean test() {
return true;
}
});
Hooks.DefaultWorldGameMode.register(new WorldTypeHooker.Check() {
@Override
public GameMode get(World world) {
MultiverseWorld mvWorld = getMV().getMVWorldManager().getMVWorld(world);
if (mvWorld == null)
return null;
GameMode gm = mvWorld.getGameMode();
plugin.getLog().debug("Multiverse: "+world.getName()+": game mode: "+gm);
return gm;
}
});
}
private static MultiverseCore getMV() {
return (MultiverseCore) Bukkit.getServer().getPluginManager().getPlugin("Multiverse-Core");
}
}

Some files were not shown because too many files have changed in this diff Show more