Compare commits

...

170 commits

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
60216d4067 Relocated MVN-Repo & CI 2013-02-10 10:07:53 +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
fd2314953b Metrics config command hint 2013-01-29 23:20:25 +01:00
Jascha Starke
5078df241e v1.4.7b:
- Metrics to monitor plugin usage
 - Region Safemode: http://dev.bukkit.org/server-mods/limited-creative/tickets/81-getting-out-of-creative-region-with-creative/
2013-01-29 22:31:01 +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
8cfb65365a Updated Version number 2013-01-18 09:02:01 +01:00
Jascha Starke
8afab9c603 - added Enchantment-Tables to blockbenches 2013-01-18 09:00:04 +01:00
Jascha Starke
c85a541b92 Multiverse-Inventories compatibility disable 2013-01-16 15:00:38 +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
6856c6d95a v1.4.6c:
- added Beacon to List of chested items (like enderchest)
2013-01-15 08:42:22 +01:00
Jascha Starke
2501aed96a Working plugin yml generation 2013-01-13 14:40:32 +01:00
Jascha Starke
6ff79cfc9e v1.4.6b:
- Support AuthMe Inventory-Events:
   * So login and logout _should_ never again f*ckup inventories
2013-01-12 14:52:29 +01:00
Jascha Starke
9773ce0343 fixed authme maven dep. 2012-12-22 23:28:28 +01:00
Jascha Starke
4bbc6a38c4 v1.4.6a:
- Moved Maven repository to automatic jenkin-build-repo by cloudbees (free hosting)
 - Removed Unsafe storage item serialization as it is now more complex than i'd like to manage manually
   * (restoring should still work, so no inventory loss)
2012-12-22 23:14:14 +01:00
Jascha Starke
7a471ea05e Fixed a java backward compatibility issue, to use jenkins maven build 2012-12-15 14:34:56 +01:00
Jascha Starke
a53962804f Fixes missing dep. for maven clean build with jenkins 2012-12-15 12:21:15 +01:00
Jascha Starke
679978a561 v1.4.5b:
- fixed localization encoding (again)
 - Bench-Block now also blocks Villagers and Anvils
 - Interacting with specific blocks is now also blocked cross regions
2012-12-07 20:03:15 +01:00
Jascha Starke
e726509472 Tag Serialization:
- Store and restore names (only in Unsafe save)
2012-12-07 18:29:03 +01:00
Jascha Starke
f0e6e853a6 v1.4.0b:
- Fix: CmdBlocker not active in survival mode
2012-11-20 09:09:16 +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
Jascha Starke
251de6aa5c v1.4.0a:
- Fixed Permissiond description
2012-11-13 00:06:18 +01:00
Jascha Starke
a9bce7ae2a v1.4.0:
- Fixed german translation encoding
 - Changed default of config-option regions.remember to not confuse new
   users whose gamemode is changed in a region by other plugins
   (MultiVerse can be a pain)
2012-11-12 23:31:02 +01:00
Jascha Starke
cf20f14433 v1.4.0a:
- unused import
2012-11-12 23:22:49 +01:00
Jascha Starke
31f670aff3 v1.4.0a:
- Fix: Block breaking of hanging entities (Paintings/ItemFrames) in/out
   of gamemode-areas
 - German Translation (As bad as English one, even its my primary lang.)
 - Removed Permission-Configuration
   * It is now always enabled to prevent confusion.
   * ATTION for PEX-Admins:
     # You have to add a Permission "-limitedcreative.keepinventory" if
     # you like to keep separated Inventories even with an
     # '*'-Admin-Permission
 - Now blocking interaction with item-frames in creative when
   nolimit.drop is enabled (default). So people neither can drop items,
   nor put it in a frame to pass it to survival.
 - Added Command Blocker
   * ATTENTION: You have to update the configuration by hand to add
     the commands to the block-list.
2012-11-12 23:22:18 +01:00
146 changed files with 9436 additions and 4156 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,174 +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
# UnsafeStore (for storing invalid enchants)
# By default the new and upgrade-safe storage method for items is used. This method doesn't allow the use
# of "invalid" enchants, like given by different plugins. Enable it, to allow invalid enchants (not recommended).
# (May be removed with 1.2, as bukkit then allows unsafed enchants by default)
# default: false
unsafe: false
# 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 like chests (so the creative player never can see his inventar).
# 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/d7/dd9/namespaceorg_1_1bukkit.html#ab7fa290bb19b9a830362aa88028ec80a)
# 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/d7/dd9/namespaceorg_1_1bukkit.html#ab7fa290bb19b9a830362aa88028ec80a)
# 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: true
remember: true
permissions:
# PermissionsEnabled
# When enabled, the Permissions will allow selected users to ignore limitations like PvP, Chest-Block, etc.
# When not enabled, all users are treated equally.
# Note: Not all Permission, are affected by this option. So you still need the defined permissions or op, to use
# commands, even if this options is disabled!
# default: false
enabled: false
# PermissionKeepInventory
# Disables the limitedcreative.keepinventory-Permission, so you can use the separated-inventories-feature, even
# if you have a permission plugin that grants ALL permission to you.
# If Enabled, only players WITHOUT the limitedcreative.keepinventory-Permission, have separated inventories;
# Players with the permission will have the inventory, like this plugin were not installed.
# When "PermissionsEnabled" is false, the KeepInventory-Option will act like disabled, even if you set it to true.
# default: false
keepinventory: false
# 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

View file

@ -1,66 +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
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
inside_place: You can not place blocks inside of the gamemode-area
inside_break: You can not destroy 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,75 +0,0 @@
name: LimitedCreative
main: de.jaschastarke.minecraft.limitedcreative.Core
version: 1.3.0c
softdepend: [WorldGuard, WorldEdit, MultiInv]
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 (if PermissionKeepInventory is enabled in config)
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

400
pom.xml
View file

@ -1,97 +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.3.0c</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>
<repositories>
<!-- Required dependencies for optional integrations, that aren't hosted yet -->
<repository>
<id>opt-dep</id>
<url>http://dl.dropbox.com/u/5023975/mvn-repo</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>
</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>
</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>
</build>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.3.1-R1.0</version>
</dependency>
<dependency>
<groupId>com.sk89q</groupId>
<artifactId>worldguard</artifactId>
<version>5.5.4-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>uk.org.whoami</groupId>
<artifactId>authme</artifactId>
<version>2.6.7b5</version>
</dependency>
<dependency>
<groupId>com.onarandombox.multiversecore</groupId>
<artifactId>Multiverse-Core</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>com.cypherx</groupId>
<artifactId>xauth</artifactId>
<version>2.0.20</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,80 +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 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*/ {
private 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);
}
/*@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,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,65 +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.isLoggedInComplete(player))
return false;
if (isPluginEnabled("xAuth") && !xAuth.isLoggedInNotGuest(player))
return false;
return true;
}
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,294 +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.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", true),
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),
PERMISSIONS("permissions.enabled", false),
PERM_KEEPINVENTORY("permissions.keepinventory", false),
PERM_WEPIF("permissions.wepif", 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);
if (value && opt == Option.PERM_KEEPINVENTORY && !this.getPermissionsEnabled())
c.set(Option.PERMISSIONS.getKey(), true);
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 getPermissionsEnabled() {
return this.getBoolean(Option.PERMISSIONS);
}
public boolean getPermissionToKeepInventory() {
return this.getPermissionsEnabled() && this.getBoolean(Option.PERM_KEEPINVENTORY);
}
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 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;
}
}

View file

@ -1,132 +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.minecraft.integration.Communicator;
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;
@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;
}
@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);
}
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")));
}
debug("Store: " + config.getStoreEnabled());
debug("Limit: " + config.getLimitEnabled());
debug("Region: " + (worldguard != null));
Commands.register(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,107 +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 org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import de.jaschastarke.minecraft.limitedcreative.store.PlayerInventoryStorage;
public class Inventory {
private static PlayerInventoryStorage storage = Core.plugin.config.getInvetoryStorage();
//private static InvMemStorage tempinvs = new InvMemStorage();
protected LCPlayer player;
public enum Target {
SURVIVAL,
CREATIVE,
ADVENTURE;
public static Target getTarget(GameMode gm) {
return Target.valueOf(gm.name());
}
}
public Inventory(LCPlayer player) {
this.player = player;
}
public LCPlayer getLCPlayer() {
return player;
}
public Player getPlayer() {
return player.getPlayer();
}
private PlayerInventory inv() {
return player.getPlayer().getInventory();
}
public void save() {
Core.debug(getPlayer().getName()+": store inventory: "+getPlayer().getGameMode());
storage.store(this, Target.getTarget(getPlayer().getGameMode()));
}
public void save(GameMode gm) {
Core.debug(getPlayer().getName()+": store inventory: "+gm);
storage.store(this, Target.getTarget(gm));
}
public void load() {
load(getPlayer().getGameMode());
}
public boolean isStored(GameMode gm) {
return storage.contains(this, Target.getTarget(gm));
}
public void load(GameMode gm) {
Core.debug(getPlayer().getName()+": load inventory: "+gm);
try {
storage.load(this, Target.getTarget(gm));
} catch (IllegalArgumentException e) {
if (Core.plugin.config.getUnsafeStorage()) {
throw e;
} else {
getPlayer().sendMessage(ChatColor.DARK_RED + L("exception.storage.load"));
}
}
}
/*public void storeTemp() {
Core.debug(getPlayer().getName()+": temp store inventory");
tempinvs.store(this);
}
public void restoreTemp() {
Core.debug(getPlayer().getName()+": temp restore inventory");
tempinvs.load(this);
}
public void clearTemp() {
Core.debug(getPlayer().getName()+": temp clear inventory");
tempinvs.remove(this);
}*/
public void clear() {
inv().setArmorContents(new ItemStack[0]);
inv().clear();
}
}

View file

@ -1,523 +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())) {
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() {
return isInPermanentGameMode(getPlayer().getGameMode());
}
public boolean isInPermanentGameMode(GameMode temp) {
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 (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() && (!plugin.config.getPermissionsEnabled() || !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 (plugin.config.getPermissionToKeepInventory() && 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 (plugin.config.getPermissionsEnabled() && 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 (plugin.config.getPermissionsEnabled() && 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 (!plugin.config.getPermissionsEnabled() || !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 (!plugin.config.getPermissionsEnabled() || !Players.get(attacker).hasPermission(Perms.NoLimit.PVP)) {
event.setCancelled(true);
return; // skip next check
}
}
if (getPlayer().getGameMode() == GameMode.CREATIVE) {
if (!plugin.config.getPermissionsEnabled() || !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 (!plugin.config.getPermissionsEnabled() || !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 (!plugin.config.getPermissionsEnabled() || !hasPermission(Perms.NoLimit.MOB_DAMAGE)) {
event.setCancelled(true);
}
}
}
}
public void onChestAccess(PlayerInteractEvent event) {
if (event.getPlayer().getGameMode() != GameMode.CREATIVE)
return;
if (plugin.config.getPermissionsEnabled() && 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 (plugin.config.getPermissionsEnabled() && 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 (plugin.config.getPermissionsEnabled() && 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 (plugin.config.getPermissionsEnabled() && 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 (plugin.config.getPermissionsEnabled() && hasPermission(Perms.NoLimit.LEVER))
return;
event.getPlayer().sendMessage(L("blocked.lever"));
event.setCancelled(true);
} else {
if (plugin.config.getPermissionsEnabled() && 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;
}
/*
* Attention: "Creative" stands for "the other gamemode". So true may mean, "be survival in creative world".
*/
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);
}
/** 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,68 +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;
}
}
}

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,224 +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.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.StorageMinecart;
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 (!plugin.config.getPermissionsEnabled() || !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) { // 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) {
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 (!plugin.config.getPermissionsEnabled() || !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();
if (entity instanceof StorageMinecart) {
player.onChestAccess(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);
}*/
@EventHandler
public void onBlockBreak(BlockBreakEvent event) {
if (event.isCancelled())
return;
if (event.getPlayer().getGameMode() == GameMode.CREATIVE) {
LCPlayer player = Players.get(event.getPlayer());
if (!plugin.config.getPermissionsEnabled() || !player.hasPermission(Perms.NoLimit.BREAK)) {
if (BlackList.isBlackListed(plugin.config.getBlockedBreaks(), event.getBlock())) {
event.setCancelled(true);
event.getPlayer().sendMessage(L("blocked.break"));
}
}
if (plugin.config.getPermissionsEnabled() && player.hasPermission(Perms.NoLimit.DROP))
return;
// Prevent dropping of doors and beds when destroying the wrong part
Block block = event.getBlock();
Material mat = block.getType();
switch (event.getBlock().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(event.getBlock().getLocation(), mat);
}
}
}
@EventHandler
public void onBlockPlace(BlockPlaceEvent event) {
if (event.isCancelled())
return;
if (event.getPlayer().getGameMode() == GameMode.CREATIVE) {
LCPlayer player = Players.get(event.getPlayer());
if (!plugin.config.getPermissionsEnabled() || !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,164 +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.entity.Item;
import org.bukkit.event.EventHandler;
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.ItemSpawnEvent;
import de.jaschastarke.minecraft.limitedcreative.Core;
import de.jaschastarke.minecraft.limitedcreative.LCPlayer;
import de.jaschastarke.minecraft.limitedcreative.Players;
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;
LCPlayer player = Players.get(event.getPlayer());
boolean diffrent_region = rm.isDiffrentRegion(event.getPlayer(), event.getBlock().getLocation());
if (player.isActiveRegionGameMode() && diffrent_region) {
// do not break 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_break"));
event.setCancelled(true);
}
} else if (diffrent_region) {
// do not break inside of "survial-region in creative world" when outside
if (rm.getRegionSet(event.getBlock()).getFlag(Flags.GAMEMODE) != null) {
event.getPlayer().sendMessage(L("blocked.inside_break"));
event.setCancelled(true);
}
}
if (!event.isCancelled()) {
// prevent any drops for survival players in creative regions
if (event.getPlayer().getGameMode() != GameMode.CREATIVE && rm.getRegionSet(event.getBlock()).getFlag(Flags.GAMEMODE) == GameMode.CREATIVE) {
plugin.spawnblock.block(event.getBlock(), 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,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.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()+"}";
}
}

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

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

View file

@ -0,0 +1,19 @@
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, Pattern.CASE_INSENSITIVE);
}
@Override
public boolean test(String cmd) {
return rx.matcher(cmd).matches();
}
public String toString() {
return rx.pattern();
}
}

View file

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

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");
}
}

View file

@ -0,0 +1,28 @@
package de.jaschastarke.minecraft.limitedcreative.hooks;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.World;
import de.jaschastarke.minecraft.limitedcreative.Hooks;
import de.jaschastarke.minecraft.limitedcreative.LimitedCreative;
import multiworld.MultiWorldPlugin;
import multiworld.api.MultiWorldAPI;
public class MultiWorldHooks {
public MultiWorldHooks(final LimitedCreative plugin) {
Hooks.DefaultWorldGameMode.register(new WorldTypeHooker.Check() {
@Override
public GameMode get(World world) {
boolean creative = getMWApi().isCreativeWorld(world.getName());
GameMode gm = creative ? GameMode.CREATIVE : GameMode.SURVIVAL;
plugin.getLog().debug("MultiWorld: "+world.getName()+": game mode: "+gm);
return gm;
}
});
}
private static MultiWorldAPI getMWApi() {
return ((MultiWorldPlugin) Bukkit.getServer().getPluginManager().getPlugin("MultiWorld")).getApi();
}
}

View file

@ -0,0 +1,24 @@
package de.jaschastarke.minecraft.limitedcreative.hooks;
import org.bukkit.entity.Player;
import de.jaschastarke.hooking.AbstractHooker;
public class PlayerCheckHooker extends AbstractHooker<PlayerCheckHooker.Check> {
public interface Check {
boolean test(Player player);
}
protected boolean def;
public PlayerCheckHooker(boolean defaultValue) {
def = defaultValue;
}
public boolean test(Player player) {
for (Check c : hooks) {
boolean ret = c.test(player);
if (ret != def)
return ret;
}
return def;
}
}

View file

@ -0,0 +1,20 @@
package de.jaschastarke.minecraft.limitedcreative.hooks;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.World;
import de.jaschastarke.hooking.AbstractHooker;
public class WorldTypeHooker extends AbstractHooker<WorldTypeHooker.Check> {
public interface Check {
GameMode get(World world);
}
public GameMode get(World world) {
for (Check c : hooks) {
return c.get(world);
}
return Bukkit.getServer().getDefaultGameMode();
}
}

View file

@ -0,0 +1,15 @@
/**
* This package contains Hookers and Hooks to integrate with other Plugins.
*
* Hookers are base classes to describe functions to test again. They are simple event manager, which hooks can register
* thru. So they should be only instantiated once in a global class.
* de.jaschastarke.minecraft.limitedcreative.Hooks in this case.
*
* Hooks are the implemented event listeners which will be registered to the static hooker-instances. The first hook
* sorted by priority which gives an answer will be returned. The exact behavior of multiple hooks are described by
* the hooker.
*
* As the plugins itself doesn't register the hooks it is done by the static
* de.jaschastarke.minecraft.limitedcreative.Hooks-initializer.
*/
package de.jaschastarke.minecraft.limitedcreative.hooks;

View file

@ -0,0 +1,32 @@
package de.jaschastarke.minecraft.limitedcreative.hooks;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import com.cypherx.xauth.xAuth;
import com.cypherx.xauth.xAuthPlayer;
import de.jaschastarke.minecraft.limitedcreative.Hooks;
import de.jaschastarke.minecraft.limitedcreative.LimitedCreative;
public class xAuthHooks {
public xAuthHooks(final LimitedCreative plugin) {
Hooks.IsLoggedIn.register(new PlayerCheckHooker.Check() {
@Override
public boolean test(Player player) {
xAuthPlayer xpl = getAuth().getPlayerManager().getPlayer(player);
boolean li = true;
if (!xpl.isAuthenticated())
li = false;
else if (xpl.isGuest())
li = false;
plugin.getLog().debug("xAuth: "+player.getName()+": logged in not guest: "+li);
return li;
}
});
}
private static xAuth getAuth() {
return (xAuth) Bukkit.getServer().getPluginManager().getPlugin("xAuth");
}
}

View file

@ -0,0 +1,161 @@
package de.jaschastarke.minecraft.limitedcreative.inventories;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.MaterialData;
import de.jaschastarke.bukkit.lib.ModuleLogger;
import de.jaschastarke.bukkit.lib.configuration.Configuration;
import de.jaschastarke.bukkit.lib.configuration.ConfigurationContainer;
import de.jaschastarke.bukkit.lib.configuration.command.ICommandConfigCallback;
import de.jaschastarke.bukkit.lib.items.MaterialDataNotRecognizedException;
import de.jaschastarke.bukkit.lib.items.MaterialNotRecognizedException;
import de.jaschastarke.bukkit.lib.items.ItemUtils;
import de.jaschastarke.configuration.ConfigurationStyle;
import de.jaschastarke.configuration.IConfigurationSubGroup;
import de.jaschastarke.configuration.annotations.IsConfigurationNode;
import de.jaschastarke.maven.ArchiveDocComments;
import de.jaschastarke.maven.PluginConfigurations;
import de.jaschastarke.minecraft.limitedcreative.ModInventories;
/**
* InventoryCreativeArmor
*
* When set, all creative Player automatically wears the given items as Armor. So they are better seen by other Players.
*/
@ArchiveDocComments
@PluginConfigurations(parent = InventoryConfig.class)
public class ArmoryConfig extends Configuration implements IConfigurationSubGroup, ICommandConfigCallback {
protected ModInventories mod;
public ArmoryConfig(ConfigurationContainer container) {
super(container);
}
public ArmoryConfig(ModInventories modInventories) {
super(modInventories.getPlugin().getDocCommentStorage());
mod = modInventories;
}
@Override
public void setValues(ConfigurationSection sect) {
if (sect == null || sect.getValues(false).size() == 0) {
ConfigurationSection parent_sect = mod.getConfig().getValues();
if (parent_sect.contains("armore") && parent_sect.isConfigurationSection("armor")) {
sect = parent_sect.createSection(this.getName(), parent_sect.getConfigurationSection("armor").getValues(true));
}
}
super.setValues(sect);
}
@Override
public String getName() {
return "creativeArmor";
}
@Override
public int getOrder() {
return 1000;
}
/**
* InventoryCreativeArmorEnabled
*
* When disabled, the players Armor isn't changed.
*
* default: true
*/
@IsConfigurationNode
public boolean getEnabled() {
return config.getBoolean("enabled", true);
}
public Map<String, ItemStack> getCreativeArmor() {
if (getEnabled()) {
Map<String, ItemStack> armor = new HashMap<String, ItemStack>();
for (Map.Entry<String, Object> entry : config.getValues(false).entrySet()) {
if (!entry.getKey().equals("enabled") && !entry.getKey().equals("fixed")) {
if (entry.getValue() instanceof ItemStack) {
armor.put(entry.getKey(), (ItemStack) entry.getValue());
} else {
MaterialData md = null;
try {
md = ItemUtils.parseMaterial((String) entry.getValue());
} catch (MaterialNotRecognizedException e) {
getLog().warn(L("exception.config.material_not_found", entry.getValue()));
} catch (MaterialDataNotRecognizedException e) {
getLog().warn(L("exception.config.materiak_data_not_found", entry.getValue()));
}
if (md != null)
armor.put(entry.getKey(), md.toItemStack(1));
}
}
}
return armor.size() > 0 ? armor : null;
}
return null;
}
/**
* InventoryCreativeArmorItems
*
* Allows changing of the "Creative-Armor" to be wear when in creative mode.
* *see Blacklist for details on Item-Types
*
* When using commands to change this options, use "current" (without quotes) to set it to the currently wearing item.
* This way you can easily set it to dyed leather armor.
*/
@IsConfigurationNode(order = 500)
public Object getHead() {
return config.get("head", "CHAINMAIL_HELMET");
}
@IsConfigurationNode(order = 501, style = ConfigurationStyle.GROUPED_PREVIOUS)
public Object getChest() {
return config.get("chest", "CHAINMAIL_CHESTPLATE");
}
@IsConfigurationNode(order = 502, style = ConfigurationStyle.GROUPED_PREVIOUS)
public Object getLegs() {
return config.get("legs", "CHAINMAIL_LEGGINGS");
}
@IsConfigurationNode(order = 503, style = ConfigurationStyle.GROUPED_PREVIOUS)
public Object getFeet() {
return config.get("feet", "CHAINMAIL_BOOTS");
}
/* -- Doesn't work, because of bugged bukkit... the event isn't fired if you try again --*
* InventoryCreativeArmorFixed
*
* Prevent players from changing armor while in creative.
*
* default: true
*//*
@IsConfigurationNode(order = 600, name = "fixed")
public boolean getFixedArmor() {
return config.getBoolean("fixed", true);
}*/
public String L(String msg, Object... objects) {
return mod.getPlugin().getLocale().trans(msg, objects);
}
public ModuleLogger getLog() {
return mod.getLog();
}
@Override
public void onConfigCommandChange(Callback cb) {
String n = cb.getNode().getName();
if (n.equals("head") || n.equals("chest") || n.equals("legs") || n.equals("feet")) {
if (cb.getValue().equals("current") || cb.getValue().equals("this")) {
if (cb.getContext().isPlayer()) {
if (n.equals("head"))
cb.setValue(cb.getContext().getPlayer().getInventory().getHelmet());
if (n.equals("chest"))
cb.setValue(cb.getContext().getPlayer().getInventory().getChestplate());
if (n.equals("legs"))
cb.setValue(cb.getContext().getPlayer().getInventory().getLeggings());
if (n.equals("feet"))
cb.setValue(cb.getContext().getPlayer().getInventory().getBoots());
}
}
}
}
}

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